Merge branch 'mac-release'
This commit is contained in:
commit
6cf1e4539d
|
@ -278,6 +278,7 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
||||||
// Feedbin uses tags and if at least one feed isn't tagged, then the folder doesn't exist on their system
|
// Feedbin uses tags and if at least one feed isn't tagged, then the folder doesn't exist on their system
|
||||||
guard folder.hasAtLeastOneFeed() else {
|
guard folder.hasAtLeastOneFeed() else {
|
||||||
account.removeFolder(folder)
|
account.removeFolder(folder)
|
||||||
|
completion(.success(()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ protocol DetailWebViewControllerDelegate: class {
|
||||||
final class DetailWebViewController: NSViewController, WKUIDelegate {
|
final class DetailWebViewController: NSViewController, WKUIDelegate {
|
||||||
|
|
||||||
weak var delegate: DetailWebViewControllerDelegate?
|
weak var delegate: DetailWebViewControllerDelegate?
|
||||||
var webview: DetailWebView!
|
var webView: DetailWebView!
|
||||||
var state: DetailState = .noSelection {
|
var state: DetailState = .noSelection {
|
||||||
didSet {
|
didSet {
|
||||||
if state != oldValue {
|
if state != oldValue {
|
||||||
|
@ -28,6 +28,7 @@ final class DetailWebViewController: NSViewController, WKUIDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var waitingForFirstReload = false
|
||||||
private let keyboardDelegate = DetailKeyboardDelegate()
|
private let keyboardDelegate = DetailKeyboardDelegate()
|
||||||
|
|
||||||
private struct MessageName {
|
private struct MessageName {
|
||||||
|
@ -36,6 +37,16 @@ final class DetailWebViewController: NSViewController, WKUIDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func loadView() {
|
override func loadView() {
|
||||||
|
// Wrap the webview in a box configured with the same background color that the web view uses
|
||||||
|
let box = NSBox(frame: .zero)
|
||||||
|
box.boxType = .custom
|
||||||
|
box.borderType = .noBorder
|
||||||
|
box.titlePosition = .noTitle
|
||||||
|
box.contentViewMargins = .zero
|
||||||
|
box.fillColor = NSColor(named: "webviewBackgroundColor")!
|
||||||
|
|
||||||
|
view = box
|
||||||
|
|
||||||
let preferences = WKPreferences()
|
let preferences = WKPreferences()
|
||||||
preferences.minimumFontSize = 12.0
|
preferences.minimumFontSize = 12.0
|
||||||
preferences.javaScriptCanOpenWindowsAutomatically = false
|
preferences.javaScriptCanOpenWindowsAutomatically = false
|
||||||
|
@ -51,18 +62,32 @@ final class DetailWebViewController: NSViewController, WKUIDelegate {
|
||||||
userContentController.add(self, name: MessageName.mouseDidExit)
|
userContentController.add(self, name: MessageName.mouseDidExit)
|
||||||
configuration.userContentController = userContentController
|
configuration.userContentController = userContentController
|
||||||
|
|
||||||
webview = DetailWebView(frame: NSRect.zero, configuration: configuration)
|
webView = DetailWebView(frame: NSRect.zero, configuration: configuration)
|
||||||
webview.uiDelegate = self
|
webView.uiDelegate = self
|
||||||
webview.navigationDelegate = self
|
webView.navigationDelegate = self
|
||||||
webview.keyboardDelegate = keyboardDelegate
|
webView.keyboardDelegate = keyboardDelegate
|
||||||
webview.translatesAutoresizingMaskIntoConstraints = false
|
webView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
if let userAgent = UserAgent.fromInfoPlist() {
|
if let userAgent = UserAgent.fromInfoPlist() {
|
||||||
webview.customUserAgent = userAgent
|
webView.customUserAgent = userAgent
|
||||||
}
|
}
|
||||||
|
|
||||||
view = webview
|
box.addSubview(webView)
|
||||||
|
|
||||||
self.reloadHTML()
|
let constraints = [
|
||||||
|
webView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||||
|
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
||||||
|
webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||||
|
webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||||
|
]
|
||||||
|
|
||||||
|
NSLayoutConstraint.activate(constraints)
|
||||||
|
|
||||||
|
// Hide the web view until the first reload (navigation) is complete (plus some delay) to avoid the awful white flash that happens on the initial display in dark mode.
|
||||||
|
// See bug #901.
|
||||||
|
webView.isHidden = true
|
||||||
|
waitingForFirstReload = true
|
||||||
|
|
||||||
|
reloadHTML()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Scrolling
|
// MARK: Scrolling
|
||||||
|
@ -74,7 +99,7 @@ final class DetailWebViewController: NSViewController, WKUIDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func scrollPageDown(_ sender: Any?) {
|
override func scrollPageDown(_ sender: Any?) {
|
||||||
webview.scrollPageDown(sender)
|
webView.scrollPageDown(sender)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +132,20 @@ extension DetailWebViewController: WKNavigationDelegate {
|
||||||
|
|
||||||
decisionHandler(.allow)
|
decisionHandler(.allow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||||
|
// See note in viewDidLoad()
|
||||||
|
if waitingForFirstReload {
|
||||||
|
assert(webView.isHidden)
|
||||||
|
waitingForFirstReload = false
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
|
||||||
|
webView.isHidden = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
@ -126,13 +165,13 @@ private extension DetailWebViewController {
|
||||||
html = ArticleRenderer.articleHTML(article: article, style: style)
|
html = ArticleRenderer.articleHTML(article: article, style: style)
|
||||||
}
|
}
|
||||||
|
|
||||||
webview.loadHTMLString(html, baseURL: nil)
|
webView.loadHTMLString(html, baseURL: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchScrollInfo(_ callback: @escaping (ScrollInfo?) -> Void) {
|
func fetchScrollInfo(_ callback: @escaping (ScrollInfo?) -> Void) {
|
||||||
let javascriptString = "var x = {contentHeight: document.body.scrollHeight, offsetY: document.body.scrollTop}; x"
|
let javascriptString = "var x = {contentHeight: document.body.scrollHeight, offsetY: document.body.scrollTop}; x"
|
||||||
|
|
||||||
webview.evaluateJavaScript(javascriptString) { (info, error) in
|
webView.evaluateJavaScript(javascriptString) { (info, error) in
|
||||||
guard let info = info as? [String: Any] else {
|
guard let info = info as? [String: Any] else {
|
||||||
callback(nil)
|
callback(nil)
|
||||||
return
|
return
|
||||||
|
@ -142,7 +181,7 @@ private extension DetailWebViewController {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let scrollInfo = ScrollInfo(contentHeight: contentHeight, viewHeight: self.webview.frame.height, offsetY: offsetY)
|
let scrollInfo = ScrollInfo(contentHeight: contentHeight, viewHeight: self.webView.frame.height, offsetY: offsetY)
|
||||||
callback(scrollInfo)
|
callback(scrollInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
},
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"red" : "1.000",
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "1.000",
|
||||||
|
"green" : "1.000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "display-p3",
|
||||||
|
"components" : {
|
||||||
|
"red" : "0.176",
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.176",
|
||||||
|
"green" : "0.176"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue