Rationalize the ArticleRenderer API.

This commit is contained in:
Brent Simmons 2019-02-10 22:06:03 -08:00
parent 9d9afea52a
commit 8de4ff4ee3
3 changed files with 58 additions and 41 deletions

View File

@ -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 = "<h3 class='systemMessage'>Multiple selection</h3>"
return renderHTML(withBody: body)
}
var noSelectionHTML: String {
let body = "<h3 class='systemMessage'>No selection</h3>"
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 = "<h3 class='systemMessage'>Multiple selection</h3>"
return renderHTML(withBody: body)
}
private var noSelectionHTML: String {
let body = "<h3 class='systemMessage'>No selection</h3>"
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
}
}

View File

@ -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

View File

@ -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) {