diff --git a/NetNewsWire/MainWindow/Detail/ArticleRenderer.swift b/NetNewsWire/MainWindow/Detail/ArticleRenderer.swift index 286cf37b2..874f45089 100644 --- a/NetNewsWire/MainWindow/Detail/ArticleRenderer.swift +++ b/NetNewsWire/MainWindow/Detail/ArticleRenderer.swift @@ -11,31 +11,20 @@ import RSCore import Articles import Account -class ArticleRenderer { - +struct ArticleRendererResult { + let html: String let baseURL: URL? +} - var articleHTML: String { - let body = RSMacroProcessor.renderedText(withTemplate: template(), substitutions: substitutions(), macroStart: "[[", macroEnd: "]]") - return renderHTML(withBody: body) - } - - var multipleSelectionHTML: String { - let body = "

Multiple selection

" - return renderHTML(withBody: body) - } - - var noSelectionHTML: String { - let body = "

No selection

" - return renderHTML(withBody: body) - } +struct ArticleRenderer { + private let baseURL: URL? private let article: Article? private let articleStyle: ArticleStyle private let appearance: NSAppearance? private let title: String - init(article: Article?, style: ArticleStyle, appearance: NSAppearance? = nil) { + private init(article: Article?, style: ArticleStyle, appearance: NSAppearance?) { self.article = article self.articleStyle = style self.appearance = appearance @@ -47,12 +36,44 @@ class ArticleRenderer { self.baseURL = nil } } + + // MARK: - API + + static func articleHTML(article: Article, style: ArticleStyle, appearance: NSAppearance?) -> ArticleRendererResult { + let renderer = ArticleRenderer(article: article, style: style, appearance: appearance) + return ArticleRendererResult(html: renderer.articleHTML, baseURL: renderer.baseURL) + } + + static func multipleSelectionHTML(style: ArticleStyle, appearance: NSAppearance?) -> ArticleRendererResult { + let renderer = ArticleRenderer(article: nil, style: style, appearance: appearance) + return ArticleRendererResult(html: renderer.multipleSelectionHTML, baseURL: nil) + } + + static func noSelectionHTML(style: ArticleStyle, appearance: NSAppearance?) -> ArticleRendererResult { + let renderer = ArticleRenderer(article: nil, style: style, appearance: appearance) + return ArticleRendererResult(html: renderer.noSelectionHTML, baseURL: nil) + } } -// MARK: Private +// MARK: - Private private extension ArticleRenderer { + private var articleHTML: String { + let body = RSMacroProcessor.renderedText(withTemplate: template(), substitutions: substitutions(), macroStart: "[[", macroEnd: "]]") + return renderHTML(withBody: body) + } + + private var multipleSelectionHTML: String { + let body = "

Multiple selection

" + return renderHTML(withBody: body) + } + + private var noSelectionHTML: String { + let body = "

No selection

" + return renderHTML(withBody: body) + } + static var faviconImgTagCache = [Feed: String]() static var feedIconImgTagCache = [Feed: String]() @@ -362,6 +383,5 @@ private extension ArticleRenderer { //print(s) return s - } } diff --git a/NetNewsWire/MainWindow/Detail/DetailViewController.swift b/NetNewsWire/MainWindow/Detail/DetailViewController.swift index 044cfe5ff..58a3a498a 100644 --- a/NetNewsWire/MainWindow/Detail/DetailViewController.swift +++ b/NetNewsWire/MainWindow/Detail/DetailViewController.swift @@ -21,7 +21,7 @@ final class DetailViewController: NSViewController, WKUIDelegate { var articles: [Article]? { didSet { - if articles == articles { + if articles == oldValue { return } statusBarView.mouseoverLink = nil @@ -43,7 +43,6 @@ final class DetailViewController: NSViewController, WKUIDelegate { } override func viewDidLoad() { - NotificationCenter.default.addObserver(self, selector: #selector(timelineSelectionDidChange(_:)), name: .TimelineSelectionDidChange, object: nil) let preferences = WKPreferences() @@ -74,10 +73,9 @@ final class DetailViewController: NSViewController, WKUIDelegate { containerView.viewController = self } - // MARK: - Scrolling + // MARK: Scrolling func canScrollDown(_ callback: @escaping (Bool) -> Void) { - if webviewIsHidden { callback(false) return @@ -96,7 +94,7 @@ final class DetailViewController: NSViewController, WKUIDelegate { webview.scrollPageDown(sender) } - // MARK: - Notifications + // MARK: Notifications @objc func timelineSelectionDidChange(_ notification: Notification) { @@ -122,7 +120,7 @@ final class DetailViewController: NSViewController, WKUIDelegate { } } -// MARK: - WKNavigationDelegate +// MARK: WKNavigationDelegate extension DetailViewController: WKNavigationDelegate { @@ -142,7 +140,7 @@ extension DetailViewController: WKNavigationDelegate { } } -// MARK: - WKScriptMessageHandler +// MARK: WKScriptMessageHandler extension DetailViewController: WKScriptMessageHandler { @@ -168,29 +166,29 @@ extension DetailViewController: WKScriptMessageHandler { } } -// MARK: - Private +// MARK: Private private extension DetailViewController { func reloadHTML() { + let articleRendererResult: ArticleRendererResult + let style = ArticleStylesManager.shared.currentStyle + let appearance = self.view.effectiveAppearance - let articleRenderer = ArticleRenderer(article: article, - style: ArticleStylesManager.shared.currentStyle, - appearance: self.view.effectiveAppearance) - - if article != nil { - webview.loadHTMLString(articleRenderer.articleHTML, baseURL: articleRenderer.baseURL) + if let articles = articles, articles.count > 1 { + articleRendererResult = ArticleRenderer.multipleSelectionHTML(style: style, appearance: appearance) } - else if articles != nil { - webview.loadHTMLString(articleRenderer.multipleSelectionHTML, baseURL: nil) + else if let article = article { + articleRendererResult = ArticleRenderer.articleHTML(article: article, style: style, appearance: appearance) } else { - webview.loadHTMLString(articleRenderer.noSelectionHTML, baseURL: nil) + articleRendererResult = ArticleRenderer.noSelectionHTML(style: style, appearance: appearance) } + + webview.loadHTMLString(articleRendererResult.html, baseURL: articleRendererResult.baseURL) } func fetchScrollInfo(_ callback: @escaping (ScrollInfo?) -> Void) { - let javascriptString = "var x = {contentHeight: document.body.scrollHeight, offsetY: document.body.scrollTop}; x" webview.evaluateJavaScript(javascriptString) { (info, error) in @@ -245,7 +243,7 @@ final class DetailContainerView: NSView { } } -// MARK: - +// MARK: - ScrollInfo private struct ScrollInfo { @@ -256,7 +254,6 @@ private struct ScrollInfo { let canScrollUp: Bool init(contentHeight: CGFloat, viewHeight: CGFloat, offsetY: CGFloat) { - self.contentHeight = contentHeight self.viewHeight = viewHeight self.offsetY = offsetY diff --git a/NetNewsWire/MainWindow/Timeline/ArticlePasteboardWriter.swift b/NetNewsWire/MainWindow/Timeline/ArticlePasteboardWriter.swift index 4fadd4af7..9f818333a 100644 --- a/NetNewsWire/MainWindow/Timeline/ArticlePasteboardWriter.swift +++ b/NetNewsWire/MainWindow/Timeline/ArticlePasteboardWriter.swift @@ -20,8 +20,8 @@ import RSCore static let articleUTIInternalType = NSPasteboard.PasteboardType(rawValue: articleUTIInternal) private lazy var renderedHTML: String = { - let articleRenderer = ArticleRenderer(article: article, style: ArticleStylesManager.shared.currentStyle) - return articleRenderer.articleHTML + let articleRendererResult = ArticleRenderer.articleHTML(article: article, style: ArticleStylesManager.shared.currentStyle, appearance: nil) + return articleRendererResult.html }() init(article: Article) {