Merge branch 'master' of https://github.com/brentsimmons/NetNewsWire
This commit is contained in:
commit
3588ce8e2b
|
@ -15,30 +15,28 @@ struct ArticleRenderer {
|
||||||
|
|
||||||
private let article: Article?
|
private let article: Article?
|
||||||
private let articleStyle: ArticleStyle
|
private let articleStyle: ArticleStyle
|
||||||
private let appearance: NSAppearance?
|
|
||||||
private let title: String
|
private let title: String
|
||||||
|
|
||||||
private init(article: Article?, style: ArticleStyle, appearance: NSAppearance?) {
|
private init(article: Article?, style: ArticleStyle) {
|
||||||
self.article = article
|
self.article = article
|
||||||
self.articleStyle = style
|
self.articleStyle = style
|
||||||
self.appearance = appearance
|
|
||||||
self.title = article?.title ?? ""
|
self.title = article?.title ?? ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - API
|
// MARK: - API
|
||||||
|
|
||||||
static func articleHTML(article: Article, style: ArticleStyle, appearance: NSAppearance?) -> String {
|
static func articleHTML(article: Article, style: ArticleStyle) -> String {
|
||||||
let renderer = ArticleRenderer(article: article, style: style, appearance: appearance)
|
let renderer = ArticleRenderer(article: article, style: style)
|
||||||
return renderer.articleHTML
|
return renderer.articleHTML
|
||||||
}
|
}
|
||||||
|
|
||||||
static func multipleSelectionHTML(style: ArticleStyle, appearance: NSAppearance?) -> String {
|
static func multipleSelectionHTML(style: ArticleStyle) -> String {
|
||||||
let renderer = ArticleRenderer(article: nil, style: style, appearance: appearance)
|
let renderer = ArticleRenderer(article: nil, style: style)
|
||||||
return renderer.multipleSelectionHTML
|
return renderer.multipleSelectionHTML
|
||||||
}
|
}
|
||||||
|
|
||||||
static func noSelectionHTML(style: ArticleStyle, appearance: NSAppearance?) -> String {
|
static func noSelectionHTML(style: ArticleStyle) -> String {
|
||||||
let renderer = ArticleRenderer(article: nil, style: style, appearance: appearance)
|
let renderer = ArticleRenderer(article: nil, style: style)
|
||||||
return renderer.noSelectionHTML
|
return renderer.noSelectionHTML
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -338,8 +336,7 @@ private extension ArticleRenderer {
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
let appearanceClass = appearance?.isDarkMode ?? false ? "dark" : "light"
|
s += "\n\n</head><body onload='startup()'>\n\n"
|
||||||
s += "\n\n</head><body id='bodyId' onload='startup()' class=\(appearanceClass)>\n\n"
|
|
||||||
s += body
|
s += body
|
||||||
s += "\n\n</body></html>"
|
s += "\n\n</body></html>"
|
||||||
|
|
||||||
|
|
|
@ -40,11 +40,6 @@ final class DetailWebView: WKWebView {
|
||||||
super.willOpenMenu(menu, with: event)
|
super.willOpenMenu(menu, with: event)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewDidChangeEffectiveAppearance() {
|
|
||||||
let bodyClass = effectiveAppearance.isDarkMode ? "dark" : "light"
|
|
||||||
evaluateJavaScript("document.getElementById('bodyId').className = '\(bodyClass)'")
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewWillStartLiveResize() {
|
override func viewWillStartLiveResize() {
|
||||||
super.viewWillStartLiveResize()
|
super.viewWillStartLiveResize()
|
||||||
evaluateJavaScript("document.body.style.overflow = 'hidden';", completionHandler: nil)
|
evaluateJavaScript("document.body.style.overflow = 'hidden';", completionHandler: nil)
|
||||||
|
|
|
@ -62,12 +62,8 @@ final class DetailWebViewController: NSViewController, WKUIDelegate {
|
||||||
|
|
||||||
view = webview
|
view = webview
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
// Must do this async, because reloadHTML references view.effectiveAppearance,
|
|
||||||
// which causes loadView to get called. Infinite loop.
|
|
||||||
self.reloadHTML()
|
self.reloadHTML()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Scrolling
|
// MARK: Scrolling
|
||||||
|
|
||||||
|
@ -119,17 +115,16 @@ private extension DetailWebViewController {
|
||||||
|
|
||||||
func reloadHTML() {
|
func reloadHTML() {
|
||||||
let style = ArticleStylesManager.shared.currentStyle
|
let style = ArticleStylesManager.shared.currentStyle
|
||||||
let appearance = view.effectiveAppearance
|
|
||||||
let html: String
|
let html: String
|
||||||
var baseURL: URL? = nil
|
var baseURL: URL? = nil
|
||||||
|
|
||||||
switch state {
|
switch state {
|
||||||
case .noSelection:
|
case .noSelection:
|
||||||
html = ArticleRenderer.noSelectionHTML(style: style, appearance: appearance)
|
html = ArticleRenderer.noSelectionHTML(style: style)
|
||||||
case .multipleSelection:
|
case .multipleSelection:
|
||||||
html = ArticleRenderer.multipleSelectionHTML(style: style, appearance: appearance)
|
html = ArticleRenderer.multipleSelectionHTML(style: style)
|
||||||
case .article(let article):
|
case .article(let article):
|
||||||
html = ArticleRenderer.articleHTML(article: article, style: style, appearance: appearance)
|
html = ArticleRenderer.articleHTML(article: article, style: style)
|
||||||
baseURL = article.baseURL
|
baseURL = article.baseURL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,73 +28,62 @@ a:hover {
|
||||||
transform: translateX(-55%) translateY(-50%);
|
transform: translateX(-55%) translateY(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Light mode */
|
:root {
|
||||||
|
--body-color: #444;
|
||||||
body.light {
|
--body-background-color: -apple-system-text-background;
|
||||||
color: #444;
|
--link-color: hsla(215, 99%, 43%, 1);
|
||||||
background-color: -apple-system-text-background;
|
--header-table-border-color: rgba(0, 0, 0, 0.1);
|
||||||
|
--header-color: rgba(0, 0, 0, 0.3);
|
||||||
|
--header-link-color: rgba(0, 0, 0, 0.3);
|
||||||
|
--body-code-color: #666;
|
||||||
|
--system-message-color: #cbcbcb;
|
||||||
|
--feedlink-color: rgba(0, 0, 0, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
body.light a, body.light a:link, body.light a:visited {
|
@media(prefers-color-scheme: dark) {
|
||||||
color: hsla(215, 99%, 43%, 1);
|
:root {
|
||||||
}
|
--body-color: #d2d2d2;
|
||||||
body.light .headerTable {
|
--body-background-color: #2d2d2d;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
--link-color: #4490e2;
|
||||||
}
|
--header-table-border-color: rgba(255, 255, 255, 0.1);
|
||||||
body.light .header {
|
--header-color: #d2d2d2;
|
||||||
color: rgba(0, 0, 0, 0.3);
|
--header-link-color: #4490e2;
|
||||||
}
|
--body-code-color: #b2b2b2;
|
||||||
body.light .header a:link, body.light .header a:visited {
|
--system-message-color: #5f5f5f
|
||||||
color: rgba(0, 0, 0, 0.3);
|
}
|
||||||
}
|
|
||||||
body.light .articleDateline, body.light .articleDateLine.a:link, body.light .articleDateline a:visited {
|
|
||||||
color: rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body.light code, body.light pre {
|
body {
|
||||||
color: #666;
|
color: var(--body-color);
|
||||||
|
background-color: var(--body-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.light > .systemMessage {
|
body a, body a:link, body a:visited {
|
||||||
color: #cbcbcb;
|
color: var(--link-color);
|
||||||
|
}
|
||||||
|
body .headerTable {
|
||||||
|
border-bottom: 1px solid var(--header-table-border-color);
|
||||||
|
}
|
||||||
|
body .header {
|
||||||
|
color: var(--header-color);
|
||||||
|
}
|
||||||
|
body .header a:link, body .header a:visited {
|
||||||
|
color: var(--header-link-color);
|
||||||
|
}
|
||||||
|
body .articleDateline, body .articleDateLine.a:link, body .articleDateline a:visited {
|
||||||
|
color: var(--header-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dark mode */
|
body code, body pre {
|
||||||
|
color: var(--body-code-color);
|
||||||
body.dark {
|
|
||||||
color: #d2d2d2;
|
|
||||||
background-color: #2d2d2d;
|
|
||||||
}
|
|
||||||
body.dark a, body.dark a:link, body.dark a:visited {
|
|
||||||
color: #4490e2;
|
|
||||||
}
|
|
||||||
body.dark .headerTable {
|
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body.dark .header a:link, body.dark .header a:visited {
|
body > .systemMessage {
|
||||||
color: #4490e2;
|
color: var(--system-message-color);
|
||||||
}
|
|
||||||
body.dark .header {
|
|
||||||
color: #d2d2d2;
|
|
||||||
}
|
|
||||||
body.dark .articleDateline {
|
|
||||||
color: #d2d2d2;
|
|
||||||
}
|
|
||||||
body.dark .articleDateline, body.dark .articleDateLine.a:link, body.dark .articleDateline a:visited {
|
|
||||||
color: #d2d2d2;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.dark code, body.dark pre {
|
|
||||||
color: #b2b2b2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark > .systemMessage {
|
|
||||||
color: #5f5f5f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.feedlink a:link, .feedlink a:visited {
|
.feedlink a:link, .feedlink a:visited {
|
||||||
color: rgba(0, 0, 0, 0.6);
|
color: var(--feed-link-color);
|
||||||
}
|
}
|
||||||
.avatar img {
|
.avatar img {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
|
@ -20,7 +20,7 @@ import RSCore
|
||||||
static let articleUTIInternalType = NSPasteboard.PasteboardType(rawValue: articleUTIInternal)
|
static let articleUTIInternalType = NSPasteboard.PasteboardType(rawValue: articleUTIInternal)
|
||||||
|
|
||||||
private lazy var renderedHTML: String = {
|
private lazy var renderedHTML: String = {
|
||||||
return ArticleRenderer.articleHTML(article: article, style: ArticleStylesManager.shared.currentStyle, appearance: nil)
|
return ArticleRenderer.articleHTML(article: article, style: ArticleStylesManager.shared.currentStyle)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
init(article: Article) {
|
init(article: Article) {
|
||||||
|
|
Loading…
Reference in New Issue