From 3fcede7fb4d43f98625ffbd03c723c7b6d1ebdbc Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 5 Nov 2017 20:31:50 -0800 Subject: [PATCH] =?UTF-8?q?Add=20JavaScript=20and=20native=20message=20han?= =?UTF-8?q?dler=20for=20getting=20mouseover=20urls=20from=20the=20detail?= =?UTF-8?q?=20view=E2=80=99s=20WKWebView.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Commands/DeleteFromSidebarCommand.swift | 4 +- Evergreen.xcodeproj/project.pbxproj | 2 +- Evergreen/AppNotifications.swift | 5 ++ .../MainWindow/Detail/ArticleRenderer.swift | 32 ++++++++++-- .../Detail/DetailViewController.swift | 49 ++++++++++++++++++- .../MainWindow/StatusBar/StatusBarView.swift | 31 ++++++++++++ 6 files changed, 115 insertions(+), 8 deletions(-) diff --git a/Commands/DeleteFromSidebarCommand.swift b/Commands/DeleteFromSidebarCommand.swift index b384f283b..583dc5edc 100644 --- a/Commands/DeleteFromSidebarCommand.swift +++ b/Commands/DeleteFromSidebarCommand.swift @@ -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() } } diff --git a/Evergreen.xcodeproj/project.pbxproj b/Evergreen.xcodeproj/project.pbxproj index a8af0c656..125e4d6eb 100644 --- a/Evergreen.xcodeproj/project.pbxproj +++ b/Evergreen.xcodeproj/project.pbxproj @@ -620,8 +620,8 @@ 849A977C1ED9EC42007D329B /* Detail */ = { isa = PBXGroup; children = ( - 849A977D1ED9EC42007D329B /* ArticleRenderer.swift */, 849A977E1ED9EC42007D329B /* DetailViewController.swift */, + 849A977D1ED9EC42007D329B /* ArticleRenderer.swift */, ); path = Detail; sourceTree = ""; diff --git a/Evergreen/AppNotifications.swift b/Evergreen/AppNotifications.swift index a7c17fff5..8fdb60896 100644 --- a/Evergreen/AppNotifications.swift +++ b/Evergreen/AppNotifications.swift @@ -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" diff --git a/Evergreen/MainWindow/Detail/ArticleRenderer.swift b/Evergreen/MainWindow/Detail/ArticleRenderer.swift index 954eb2535..c6f8f9d0c 100644 --- a/Evergreen/MainWindow/Detail/ArticleRenderer.swift +++ b/Evergreen/MainWindow/Detail/ArticleRenderer.swift @@ -180,14 +180,40 @@ class ArticleRenderer { private func renderedHTML() -> String { - var s = "" + var s = "\n\n" s += textInsideTag(title, "title") s += textInsideTag(styleString(), "style") - s += "" + + s += """ + + + + """ + + s += "\n\n\n\n" + s += RSMacroProcessor.renderedText(withTemplate: template(), substitutions: substitutions(), macroStart: "[[", macroEnd: "]]") - s += "" + s += "\n\n" // print(s) diff --git a/Evergreen/MainWindow/Detail/DetailViewController.swift b/Evergreen/MainWindow/Detail/DetailViewController.swift index e69bad5dd..8cd070f39 100644 --- a/Evergreen/MainWindow/Detail/DetailViewController.swift +++ b/Evergreen/MainWindow/Detail/DetailViewController.swift @@ -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? diff --git a/Evergreen/MainWindow/StatusBar/StatusBarView.swift b/Evergreen/MainWindow/StatusBar/StatusBarView.swift index b4e7220a5..4d4be6fe0 100644 --- a/Evergreen/MainWindow/StatusBar/StatusBarView.swift +++ b/Evergreen/MainWindow/StatusBar/StatusBarView.swift @@ -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) {