Make stylesheet external to page.html

This commit is contained in:
Maurice Parker
2019-09-20 19:28:13 -05:00
parent 9c6d47eaa1
commit 710abf30c7
5 changed files with 22 additions and 185 deletions

View File

@@ -161,6 +161,7 @@ extension DetailWebViewController: WKNavigationDelegate {
if waitingForFirstReload {
assert(webView.isHidden)
waitingForFirstReload = false
reloadHTML()
// Waiting for the first navigation to complete isn't long enough to avoid the flash of white.
// A hard coded value is awful, but 5/100th of a second seems to be enough.
@@ -173,6 +174,7 @@ extension DetailWebViewController: WKNavigationDelegate {
// MARK: - Private
struct TemplateData: Codable {
let style: String
let body: String
}
@@ -180,20 +182,20 @@ private extension DetailWebViewController {
func reloadHTML() {
let style = ArticleStylesManager.shared.currentStyle
let html: String
let rendering: ArticleRendering
switch state {
case .noSelection:
html = ArticleRenderer.noSelectionHTML(style: style)
rendering = ArticleRenderer.noSelectionHTML(style: style)
case .multipleSelection:
html = ArticleRenderer.multipleSelectionHTML(style: style)
rendering = ArticleRenderer.multipleSelectionHTML(style: style)
case .article(let article):
html = ArticleRenderer.articleHTML(article: article, style: style)
rendering = ArticleRenderer.articleHTML(article: article, style: style)
case .extracted(let article, let extractedArticle):
html = ArticleRenderer.articleHTML(article: article, extractedArticle: extractedArticle, style: style)
rendering = ArticleRenderer.articleHTML(article: article, extractedArticle: extractedArticle, style: style)
}
let templateData = TemplateData(body: html)
let templateData = TemplateData(style: rendering.style, body: rendering.html)
let encoder = JSONEncoder()
var render = "error();"

View File

@@ -20,7 +20,8 @@ import RSCore
static let articleUTIInternalType = NSPasteboard.PasteboardType(rawValue: articleUTIInternal)
private lazy var renderedHTML: String = {
return ArticleRenderer.articleHTML(article: article, style: ArticleStylesManager.shared.currentStyle)
let rendering = ArticleRenderer.articleHTML(article: article, style: ArticleStylesManager.shared.currentStyle)
return rendering.html
}()
init(article: Article) {

View File

@@ -11,6 +11,8 @@ import RSCore
import Articles
import Account
typealias ArticleRendering = (style: String, html: String)
struct ArticleRenderer {
private let article: Article?
@@ -36,24 +38,24 @@ struct ArticleRenderer {
// MARK: - API
static func articleHTML(article: Article, extractedArticle: ExtractedArticle? = nil, style: ArticleStyle) -> String {
static func articleHTML(article: Article, extractedArticle: ExtractedArticle? = nil, style: ArticleStyle) -> ArticleRendering {
let renderer = ArticleRenderer(article: article, extractedArticle: extractedArticle, style: style)
return renderer.articleHTML
return (renderer.styleString(), renderer.articleHTML)
}
static func multipleSelectionHTML(style: ArticleStyle) -> String {
static func multipleSelectionHTML(style: ArticleStyle) -> ArticleRendering {
let renderer = ArticleRenderer(article: nil, extractedArticle: nil, style: style)
return renderer.multipleSelectionHTML
return (renderer.styleString(), renderer.multipleSelectionHTML)
}
static func noSelectionHTML(style: ArticleStyle) -> String {
static func noSelectionHTML(style: ArticleStyle) -> ArticleRendering {
let renderer = ArticleRenderer(article: nil, extractedArticle: nil, style: style)
return renderer.noSelectionHTML
return (renderer.styleString(), renderer.noSelectionHTML)
}
static func noContentHTML(style: ArticleStyle) -> String {
static func noContentHTML(style: ArticleStyle) -> ArticleRendering {
let renderer = ArticleRenderer(article: nil, extractedArticle: nil, style: style)
return renderer.noContentHTML
return (renderer.styleString(), renderer.noContentHTML)
}
}

View File

@@ -1,175 +1,6 @@
<html>
<head>
<style>
body {
margin-top: 20px;
margin-bottom: 64px;
margin-left: 64px;
margin-right: 64px;
font-family: -apple-system;
font-size: 18px;
word-wrap: break-word; /* break long words or URLs */
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.feedlink {
font-weight: bold;
}
.headerTable {
width: 100%;
height: 68px;
}
.systemMessage {
position: absolute;
top: 45%;
left: 50%;
transform: translateX(-55%) translateY(-50%);
}
:root {
--body-color: #444;
--body-background-color: -apple-system-text-background;
--link-color: hsla(215, 99%, 43%, 1);
--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);
}
@media(prefers-color-scheme: dark) {
:root {
--body-color: #d2d2d2;
--body-background-color: #2d2d2d;
--link-color: #4490e2;
--header-table-border-color: rgba(255, 255, 255, 0.1);
--header-color: #d2d2d2;
--header-link-color: #4490e2;
--body-code-color: #b2b2b2;
--system-message-color: #5f5f5f
}
}
body {
color: var(--body-color);
background-color: var(--body-background-color);
}
body a, body a:link, body a:visited {
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);
}
body code, body pre {
color: var(--body-code-color);
}
body > .systemMessage {
color: var(--system-message-color);
}
.feedlink a:link, .feedlink a:visited {
color: var(--feed-link-color);
}
.avatar img {
border-radius: 4px;
}
.feedIcon {
border-radius: 4px;
}
.rightAlign {
text-align: right;
}
.leftAlign {
text-align: left;
}
.articleTitle {
margin-top: 26px;
}
.articleDateline {
margin-bottom: 25px;
font-weight: bold;
}
.articleBody {
line-height: 1.6em;
}
h1 {
line-height: 1.15em;
font-weight: bold;
}
code, pre {
font-family: "SF Mono", Menlo, "Courier New", Courier, monospace;
font-size: 14px;
}
pre {
white-space: pre-wrap;
}
img, figure, video, iframe, div {
max-width: 100%;
height: auto !important;
margin: 0 auto;
}
figcaption {
font-size: 14px;
line-height: 1.3em;
}
/*Block ads and junk*/
iframe[src*="feedads"],
iframe[src*="doubleclick"],
iframe[src*="plusone.google"] {
display: none !important;
}
a[href*=".ads."],
a[href*="feedads"],
a[href*="doubleclick"],
a[href*="//ads."],
a[href*="api.tweetmeme"],
a[href*="delicious.com/post?"],
a[href*="digg.com/submit?"],
a[href*="google.com/bookmarks/mark?"],
a[href*="posterous.com/share?"],
a[href*="tumblr.com/share?"],
a[href*="linkedin.com/shareArticle?"],
a[href*="facebook.com/share.php?"],
a[href*="http://twitter.com/home?"],
a[href*="addtoany.com/share_save"] {
display: none !important;
}
img[src*=".ads."],
img[src*="//ads."],
img[src*="doubleclick"],
img[src*="feedads"],
img[src*="feedburner"],
img[src*="feedblitz"],
img[src*="share-buttons"] {
display: none !important;
}
</style>
<script>
function mouseDidEnterLink(anchor) {
@@ -181,6 +12,7 @@
}
function render(data) {
document.getElementsByTagName("style")[0].innerHTML = data.style;
document.body.innerHTML = data.body;
window.scrollTo(0, 0);
var anchors = document.getElementsByTagName("a");

View File

@@ -104,7 +104,7 @@ class DetailViewController: UIViewController {
return
}
let style = ArticleStylesManager.shared.currentStyle
let html = ArticleRenderer.articleHTML(article: article, style: style)
let (styleSheet, html) = ArticleRenderer.articleHTML(article: article, style: style)
webView.loadHTMLString(html, baseURL: nil)
}