Remove WebViewProvider and PreloadedWebView. This is really Maurice’s change but I’ve changed things so much that I don’t think I can cherry-pick it. There’s going to be a lot of that coming up.
This commit is contained in:
parent
185ac2db1c
commit
f54fe338cd
@ -213,7 +213,6 @@
|
|||||||
51707439232AA97100A461A3 /* ShareFolderPickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51707438232AA97100A461A3 /* ShareFolderPickerController.swift */; };
|
51707439232AA97100A461A3 /* ShareFolderPickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51707438232AA97100A461A3 /* ShareFolderPickerController.swift */; };
|
||||||
517630042336215100E15FFF /* main.js in Resources */ = {isa = PBXBuildFile; fileRef = 517630032336215100E15FFF /* main.js */; };
|
517630042336215100E15FFF /* main.js in Resources */ = {isa = PBXBuildFile; fileRef = 517630032336215100E15FFF /* main.js */; };
|
||||||
517630052336215100E15FFF /* main.js in Resources */ = {isa = PBXBuildFile; fileRef = 517630032336215100E15FFF /* main.js */; };
|
517630052336215100E15FFF /* main.js in Resources */ = {isa = PBXBuildFile; fileRef = 517630032336215100E15FFF /* main.js */; };
|
||||||
517630232336657E00E15FFF /* WebViewProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 517630222336657E00E15FFF /* WebViewProvider.swift */; };
|
|
||||||
517A745B2443665000B553B9 /* UIPageViewController-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 517A745A2443665000B553B9 /* UIPageViewController-Extensions.swift */; };
|
517A745B2443665000B553B9 /* UIPageViewController-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 517A745A2443665000B553B9 /* UIPageViewController-Extensions.swift */; };
|
||||||
5183CCD0226E1E880010922C /* NonIntrinsicLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCCF226E1E880010922C /* NonIntrinsicLabel.swift */; };
|
5183CCD0226E1E880010922C /* NonIntrinsicLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCCF226E1E880010922C /* NonIntrinsicLabel.swift */; };
|
||||||
5183CCDA226E31A50010922C /* NonIntrinsicImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */; };
|
5183CCDA226E31A50010922C /* NonIntrinsicImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */; };
|
||||||
@ -358,7 +357,6 @@
|
|||||||
51DC07992552083500A3F79F /* ArticleTextSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC07972552083500A3F79F /* ArticleTextSize.swift */; };
|
51DC07992552083500A3F79F /* ArticleTextSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC07972552083500A3F79F /* ArticleTextSize.swift */; };
|
||||||
51DC079A2552083500A3F79F /* ArticleTextSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC07972552083500A3F79F /* ArticleTextSize.swift */; };
|
51DC079A2552083500A3F79F /* ArticleTextSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC07972552083500A3F79F /* ArticleTextSize.swift */; };
|
||||||
51DC07AC255209E200A3F79F /* ArticleTextSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC07972552083500A3F79F /* ArticleTextSize.swift */; };
|
51DC07AC255209E200A3F79F /* ArticleTextSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC07972552083500A3F79F /* ArticleTextSize.swift */; };
|
||||||
51DC370B2405BC9A0095D371 /* PreloadedWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51DC370A2405BC9A0095D371 /* PreloadedWebView.swift */; };
|
|
||||||
51DEE81226FB9233006DAA56 /* Appanoose.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 51DEE81126FB9233006DAA56 /* Appanoose.nnwtheme */; };
|
51DEE81226FB9233006DAA56 /* Appanoose.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 51DEE81126FB9233006DAA56 /* Appanoose.nnwtheme */; };
|
||||||
51DEE81326FB9233006DAA56 /* Appanoose.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 51DEE81126FB9233006DAA56 /* Appanoose.nnwtheme */; };
|
51DEE81326FB9233006DAA56 /* Appanoose.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 51DEE81126FB9233006DAA56 /* Appanoose.nnwtheme */; };
|
||||||
51DEE81426FB9233006DAA56 /* Appanoose.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 51DEE81126FB9233006DAA56 /* Appanoose.nnwtheme */; };
|
51DEE81426FB9233006DAA56 /* Appanoose.nnwtheme in Resources */ = {isa = PBXBuildFile; fileRef = 51DEE81126FB9233006DAA56 /* Appanoose.nnwtheme */; };
|
||||||
@ -1192,7 +1190,6 @@
|
|||||||
516AE9DE2372269A007DEEAA /* IconImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconImage.swift; sourceTree = "<group>"; };
|
516AE9DE2372269A007DEEAA /* IconImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconImage.swift; sourceTree = "<group>"; };
|
||||||
51707438232AA97100A461A3 /* ShareFolderPickerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareFolderPickerController.swift; sourceTree = "<group>"; };
|
51707438232AA97100A461A3 /* ShareFolderPickerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareFolderPickerController.swift; sourceTree = "<group>"; };
|
||||||
517630032336215100E15FFF /* main.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = main.js; sourceTree = "<group>"; };
|
517630032336215100E15FFF /* main.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = main.js; sourceTree = "<group>"; };
|
||||||
517630222336657E00E15FFF /* WebViewProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewProvider.swift; sourceTree = "<group>"; };
|
|
||||||
517A745A2443665000B553B9 /* UIPageViewController-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIPageViewController-Extensions.swift"; sourceTree = "<group>"; };
|
517A745A2443665000B553B9 /* UIPageViewController-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIPageViewController-Extensions.swift"; sourceTree = "<group>"; };
|
||||||
5183CCCF226E1E880010922C /* NonIntrinsicLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonIntrinsicLabel.swift; sourceTree = "<group>"; };
|
5183CCCF226E1E880010922C /* NonIntrinsicLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonIntrinsicLabel.swift; sourceTree = "<group>"; };
|
||||||
5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonIntrinsicImageView.swift; sourceTree = "<group>"; };
|
5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonIntrinsicImageView.swift; sourceTree = "<group>"; };
|
||||||
@ -1269,7 +1266,6 @@
|
|||||||
51D6A5BB23199C85001C27D8 /* TimelineDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineDataSource.swift; sourceTree = "<group>"; };
|
51D6A5BB23199C85001C27D8 /* TimelineDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineDataSource.swift; sourceTree = "<group>"; };
|
||||||
51D87EE02311D34700E63F03 /* ActivityType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityType.swift; sourceTree = "<group>"; };
|
51D87EE02311D34700E63F03 /* ActivityType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityType.swift; sourceTree = "<group>"; };
|
||||||
51DC07972552083500A3F79F /* ArticleTextSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleTextSize.swift; sourceTree = "<group>"; };
|
51DC07972552083500A3F79F /* ArticleTextSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleTextSize.swift; sourceTree = "<group>"; };
|
||||||
51DC370A2405BC9A0095D371 /* PreloadedWebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreloadedWebView.swift; sourceTree = "<group>"; };
|
|
||||||
51DEE81126FB9233006DAA56 /* Appanoose.nnwtheme */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Appanoose.nnwtheme; sourceTree = "<group>"; };
|
51DEE81126FB9233006DAA56 /* Appanoose.nnwtheme */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Appanoose.nnwtheme; sourceTree = "<group>"; };
|
||||||
51DEE81726FBFF84006DAA56 /* Promenade.nnwtheme */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Promenade.nnwtheme; sourceTree = "<group>"; };
|
51DEE81726FBFF84006DAA56 /* Promenade.nnwtheme */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Promenade.nnwtheme; sourceTree = "<group>"; };
|
||||||
51E36E70239D6610006F47A5 /* AddFeedSelectFolderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddFeedSelectFolderTableViewCell.swift; sourceTree = "<group>"; };
|
51E36E70239D6610006F47A5 /* AddFeedSelectFolderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddFeedSelectFolderTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
@ -2018,9 +2014,7 @@
|
|||||||
518651D9235621840078E021 /* ImageTransition.swift */,
|
518651D9235621840078E021 /* ImageTransition.swift */,
|
||||||
5142192923522B5500E07E2C /* ImageViewController.swift */,
|
5142192923522B5500E07E2C /* ImageViewController.swift */,
|
||||||
512D554323C804DE0023FFFA /* OpenInSafariActivity.swift */,
|
512D554323C804DE0023FFFA /* OpenInSafariActivity.swift */,
|
||||||
51DC370A2405BC9A0095D371 /* PreloadedWebView.swift */,
|
|
||||||
51AB8AB223B7F4C6008F147D /* WebViewController.swift */,
|
51AB8AB223B7F4C6008F147D /* WebViewController.swift */,
|
||||||
517630222336657E00E15FFF /* WebViewProvider.swift */,
|
|
||||||
51C9DE5723EA2EF4003D5A6D /* WrapperScriptMessageHandler.swift */,
|
51C9DE5723EA2EF4003D5A6D /* WrapperScriptMessageHandler.swift */,
|
||||||
D3A398632465054F00F9A366 /* FindInArticleActivity.swift */,
|
D3A398632465054F00F9A366 /* FindInArticleActivity.swift */,
|
||||||
D3555BF324664539005E48C3 /* ArticleSearchBar.swift */,
|
D3555BF324664539005E48C3 /* ArticleSearchBar.swift */,
|
||||||
@ -3944,7 +3938,6 @@
|
|||||||
511B9807237DCAC90028BCAA /* UserInfoKey.swift in Sources */,
|
511B9807237DCAC90028BCAA /* UserInfoKey.swift in Sources */,
|
||||||
51C45269226508F600C03939 /* FeedTableViewCell.swift in Sources */,
|
51C45269226508F600C03939 /* FeedTableViewCell.swift in Sources */,
|
||||||
51F85BFD2275DCA800C787DC /* SingleLineUILabelSizer.swift in Sources */,
|
51F85BFD2275DCA800C787DC /* SingleLineUILabelSizer.swift in Sources */,
|
||||||
517630232336657E00E15FFF /* WebViewProvider.swift in Sources */,
|
|
||||||
51E43962238037C400015C31 /* AddFeedFolderViewController.swift in Sources */,
|
51E43962238037C400015C31 /* AddFeedFolderViewController.swift in Sources */,
|
||||||
51C4528F226509BD00C03939 /* UnreadFeed.swift in Sources */,
|
51C4528F226509BD00C03939 /* UnreadFeed.swift in Sources */,
|
||||||
51FD413B2342BD0500880194 /* TimelineUnreadCountView.swift in Sources */,
|
51FD413B2342BD0500880194 /* TimelineUnreadCountView.swift in Sources */,
|
||||||
@ -4053,7 +4046,6 @@
|
|||||||
51627A6923861DED007B3B4B /* FeedsViewController+Drop.swift in Sources */,
|
51627A6923861DED007B3B4B /* FeedsViewController+Drop.swift in Sources */,
|
||||||
514219372352510100E07E2C /* ImageScrollView.swift in Sources */,
|
514219372352510100E07E2C /* ImageScrollView.swift in Sources */,
|
||||||
516AE9B32371C372007DEEAA /* FeedTableViewSectionHeaderLayout.swift in Sources */,
|
516AE9B32371C372007DEEAA /* FeedTableViewSectionHeaderLayout.swift in Sources */,
|
||||||
51DC370B2405BC9A0095D371 /* PreloadedWebView.swift in Sources */,
|
|
||||||
D3555BF524664566005E48C3 /* ArticleSearchBar.swift in Sources */,
|
D3555BF524664566005E48C3 /* ArticleSearchBar.swift in Sources */,
|
||||||
8454C3F3263F2D8700E3F9C7 /* IconImageCache.swift in Sources */,
|
8454C3F3263F2D8700E3F9C7 /* IconImageCache.swift in Sources */,
|
||||||
B24E9ADE245AB88400DA5718 /* NSAttributedString+NetNewsWire.swift in Sources */,
|
B24E9ADE245AB88400DA5718 /* NSAttributedString+NetNewsWire.swift in Sources */,
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
//
|
|
||||||
// PreloadedWebView.swift
|
|
||||||
// NetNewsWire-iOS
|
|
||||||
//
|
|
||||||
// Created by Maurice Parker on 2/25/20.
|
|
||||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import WebKit
|
|
||||||
|
|
||||||
class PreloadedWebView: WKWebView {
|
|
||||||
|
|
||||||
private var isReady: Bool = false
|
|
||||||
private var readyCompletion: (() -> Void)?
|
|
||||||
|
|
||||||
init(articleIconSchemeHandler: ArticleIconSchemeHandler) {
|
|
||||||
let preferences = WKPreferences()
|
|
||||||
preferences.javaScriptCanOpenWindowsAutomatically = false
|
|
||||||
preferences.javaScriptEnabled = true
|
|
||||||
|
|
||||||
let configuration = WKWebViewConfiguration()
|
|
||||||
configuration.preferences = preferences
|
|
||||||
configuration.setValue(true, forKey: "allowUniversalAccessFromFileURLs")
|
|
||||||
configuration.allowsInlineMediaPlayback = true
|
|
||||||
configuration.mediaTypesRequiringUserActionForPlayback = .audio
|
|
||||||
configuration.setURLSchemeHandler(articleIconSchemeHandler, forURLScheme: ArticleRenderer.imageIconScheme)
|
|
||||||
|
|
||||||
super.init(frame: .zero, configuration: configuration)
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
|
||||||
super.init(coder: coder)
|
|
||||||
}
|
|
||||||
|
|
||||||
func preload() {
|
|
||||||
navigationDelegate = self
|
|
||||||
loadFileURL(ArticleRenderer.blank.url, allowingReadAccessTo: ArticleRenderer.blank.baseURL)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ready(completion: @escaping () -> Void) {
|
|
||||||
if isReady {
|
|
||||||
completeRequest(completion: completion)
|
|
||||||
} else {
|
|
||||||
readyCompletion = completion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: WKScriptMessageHandler
|
|
||||||
|
|
||||||
extension PreloadedWebView: WKNavigationDelegate {
|
|
||||||
|
|
||||||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
|
||||||
isReady = true
|
|
||||||
if let completion = readyCompletion {
|
|
||||||
completeRequest(completion: completion)
|
|
||||||
readyCompletion = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Private
|
|
||||||
|
|
||||||
private extension PreloadedWebView {
|
|
||||||
|
|
||||||
func completeRequest(completion: @escaping () -> Void) {
|
|
||||||
isReady = false
|
|
||||||
navigationDelegate = nil
|
|
||||||
completion()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -31,14 +31,15 @@ class WebViewController: UIViewController {
|
|||||||
private var topShowBarsViewConstraint: NSLayoutConstraint!
|
private var topShowBarsViewConstraint: NSLayoutConstraint!
|
||||||
private var bottomShowBarsViewConstraint: NSLayoutConstraint!
|
private var bottomShowBarsViewConstraint: NSLayoutConstraint!
|
||||||
|
|
||||||
private var webView: PreloadedWebView? {
|
var webView: WKWebView? {
|
||||||
return view.subviews[0] as? PreloadedWebView
|
return view.subviews[0] as? WKWebView
|
||||||
}
|
}
|
||||||
|
|
||||||
private lazy var contextMenuInteraction = UIContextMenuInteraction(delegate: self)
|
private lazy var contextMenuInteraction = UIContextMenuInteraction(delegate: self)
|
||||||
private var isFullScreenAvailable: Bool {
|
private var isFullScreenAvailable: Bool {
|
||||||
return AppDefaults.shared.articleFullscreenAvailable && traitCollection.userInterfaceIdiom == .phone && coordinator.isRootSplitCollapsed
|
return AppDefaults.shared.articleFullscreenAvailable && traitCollection.userInterfaceIdiom == .phone && coordinator.isRootSplitCollapsed
|
||||||
}
|
}
|
||||||
|
private lazy var articleIconSchemeHandler = ArticleIconSchemeHandler(coordinator: coordinator);
|
||||||
private lazy var transition = ImageTransition(controller: self)
|
private lazy var transition = ImageTransition(controller: self)
|
||||||
private var clickedImageCompletion: (() -> Void)?
|
private var clickedImageCompletion: (() -> Void)?
|
||||||
|
|
||||||
@ -374,14 +375,6 @@ extension WebViewController: UIContextMenuInteractionDelegate {
|
|||||||
|
|
||||||
extension WebViewController: WKNavigationDelegate {
|
extension WebViewController: WKNavigationDelegate {
|
||||||
|
|
||||||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
|
||||||
for (index, view) in view.subviews.enumerated() {
|
|
||||||
if index != 0, let oldWebView = view as? PreloadedWebView {
|
|
||||||
oldWebView.removeFromSuperview()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
||||||
|
|
||||||
if navigationAction.navigationType == .linkActivated {
|
if navigationAction.navigationType == .linkActivated {
|
||||||
@ -543,19 +536,46 @@ private extension WebViewController {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinator.webViewProvider.dequeueWebView() { webView in
|
let preferences = WKPreferences()
|
||||||
|
preferences.javaScriptCanOpenWindowsAutomatically = false
|
||||||
|
|
||||||
webView.ready {
|
/// The defaults for `preferredContentMode` and `allowsContentJavaScript` are suitable
|
||||||
|
/// and don't need to be explicitly set.
|
||||||
|
/// `allowsContentJavaScript` replaces `WKPreferences.javascriptEnabled`.
|
||||||
|
let webpagePreferences = WKWebpagePreferences()
|
||||||
|
|
||||||
// Add the webview
|
let configuration = WKWebViewConfiguration()
|
||||||
webView.translatesAutoresizingMaskIntoConstraints = false
|
configuration.defaultWebpagePreferences = webpagePreferences
|
||||||
|
configuration.preferences = preferences
|
||||||
|
configuration.setValue(true, forKey: "allowUniversalAccessFromFileURLs")
|
||||||
|
configuration.allowsInlineMediaPlayback = true
|
||||||
|
configuration.mediaTypesRequiringUserActionForPlayback = .audio
|
||||||
|
if #available(iOS 15.4, *) {
|
||||||
|
configuration.preferences.isElementFullscreenEnabled = true
|
||||||
|
}
|
||||||
|
configuration.setURLSchemeHandler(articleIconSchemeHandler, forURLScheme: ArticleRenderer.imageIconScheme)
|
||||||
|
|
||||||
|
let userContentController = WKUserContentController()
|
||||||
|
let baseURL = ArticleRenderer.page.baseURL
|
||||||
|
let appScriptsWorld = WKContentWorld.world(name: "NetNewsWire")
|
||||||
|
for fileName in ["main.js", "main_ios.js", "newsfoot.js"] {
|
||||||
|
userContentController.addUserScript(
|
||||||
|
.init(source: try! String(contentsOf: baseURL.appending(path: fileName,
|
||||||
|
directoryHint: .notDirectory)),
|
||||||
|
injectionTime: .atDocumentStart,
|
||||||
|
forMainFrameOnly: true,
|
||||||
|
in: appScriptsWorld))
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration.userContentController = userContentController
|
||||||
|
|
||||||
|
let webView = WKWebView(frame: self.view.bounds, configuration: configuration)
|
||||||
|
webView.isOpaque = false;
|
||||||
|
webView.backgroundColor = .clear;
|
||||||
|
|
||||||
|
// Add the webview - using autolayout will cause fullscreen video to fail and lose the web view
|
||||||
|
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||||
self.view.insertSubview(webView, at: 0)
|
self.view.insertSubview(webView, at: 0)
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
self.view.leadingAnchor.constraint(equalTo: webView.leadingAnchor),
|
|
||||||
self.view.trailingAnchor.constraint(equalTo: webView.trailingAnchor),
|
|
||||||
self.view.topAnchor.constraint(equalTo: webView.topAnchor),
|
|
||||||
self.view.bottomAnchor.constraint(equalTo: webView.bottomAnchor)
|
|
||||||
])
|
|
||||||
|
|
||||||
// UISplitViewController reports the wrong size to WKWebView which can cause horizontal
|
// UISplitViewController reports the wrong size to WKWebView which can cause horizontal
|
||||||
// rubberbanding on the iPad. This interferes with our UIPageViewController preventing
|
// rubberbanding on the iPad. This interferes with our UIPageViewController preventing
|
||||||
@ -578,14 +598,9 @@ private extension WebViewController {
|
|||||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.showFeedInspector)
|
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.showFeedInspector)
|
||||||
|
|
||||||
self.renderPage(webView)
|
self.renderPage(webView)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
func renderPage(_ webView: WKWebView?) {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func renderPage(_ webView: PreloadedWebView?) {
|
|
||||||
guard let webView = webView else { return }
|
guard let webView = webView else { return }
|
||||||
|
|
||||||
let theme = ArticleThemesManager.shared.currentTheme
|
let theme = ArticleThemesManager.shared.currentTheme
|
||||||
|
@ -1,103 +0,0 @@
|
|||||||
//
|
|
||||||
// WebViewProvider.swift
|
|
||||||
// NetNewsWire-iOS
|
|
||||||
//
|
|
||||||
// Created by Maurice Parker on 9/21/19.
|
|
||||||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import RSCore
|
|
||||||
import WebKit
|
|
||||||
|
|
||||||
/// WKWebView has an awful behavior of a flash to white on first load when in dark mode.
|
|
||||||
/// Keep a queue of WebViews where we've already done a trivial load so that by the time we need them in the UI, they're past the flash-to-shite part of their lifecycle.
|
|
||||||
class WebViewProvider: NSObject {
|
|
||||||
|
|
||||||
private let articleIconSchemeHandler: ArticleIconSchemeHandler
|
|
||||||
private let operationQueue = MainThreadOperationQueue()
|
|
||||||
private var queue = NSMutableArray()
|
|
||||||
|
|
||||||
init(coordinator: SceneCoordinator) {
|
|
||||||
articleIconSchemeHandler = ArticleIconSchemeHandler(coordinator: coordinator)
|
|
||||||
super.init()
|
|
||||||
replenishQueueIfNeeded()
|
|
||||||
}
|
|
||||||
|
|
||||||
func replenishQueueIfNeeded() {
|
|
||||||
operationQueue.add(WebViewProviderReplenishQueueOperation(queue: queue, articleIconSchemeHandler: articleIconSchemeHandler))
|
|
||||||
}
|
|
||||||
|
|
||||||
func dequeueWebView(completion: @escaping (PreloadedWebView) -> ()) {
|
|
||||||
operationQueue.add(WebViewProviderDequeueOperation(queue: queue, articleIconSchemeHandler: articleIconSchemeHandler, completion: completion))
|
|
||||||
operationQueue.add(WebViewProviderReplenishQueueOperation(queue: queue, articleIconSchemeHandler: articleIconSchemeHandler))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class WebViewProviderReplenishQueueOperation: MainThreadOperation {
|
|
||||||
|
|
||||||
// MainThreadOperation
|
|
||||||
public var isCanceled = false
|
|
||||||
public var id: Int?
|
|
||||||
public weak var operationDelegate: MainThreadOperationDelegate?
|
|
||||||
public var name: String? = "WebViewProviderReplenishQueueOperation"
|
|
||||||
public var completionBlock: MainThreadOperation.MainThreadOperationCompletionBlock?
|
|
||||||
|
|
||||||
private let minimumQueueDepth = 3
|
|
||||||
|
|
||||||
private var queue: NSMutableArray
|
|
||||||
private var articleIconSchemeHandler: ArticleIconSchemeHandler
|
|
||||||
|
|
||||||
init(queue: NSMutableArray, articleIconSchemeHandler: ArticleIconSchemeHandler) {
|
|
||||||
self.queue = queue
|
|
||||||
self.articleIconSchemeHandler = articleIconSchemeHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
func run() {
|
|
||||||
while queue.count < minimumQueueDepth {
|
|
||||||
let webView = PreloadedWebView(articleIconSchemeHandler: articleIconSchemeHandler)
|
|
||||||
webView.preload()
|
|
||||||
queue.insert(webView, at: 0)
|
|
||||||
}
|
|
||||||
self.operationDelegate?.operationDidComplete(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class WebViewProviderDequeueOperation: MainThreadOperation {
|
|
||||||
|
|
||||||
// MainThreadOperation
|
|
||||||
public var isCanceled = false
|
|
||||||
public var id: Int?
|
|
||||||
public weak var operationDelegate: MainThreadOperationDelegate?
|
|
||||||
public var name: String? = "WebViewProviderFlushQueueOperation"
|
|
||||||
public var completionBlock: MainThreadOperation.MainThreadOperationCompletionBlock?
|
|
||||||
|
|
||||||
private var queue: NSMutableArray
|
|
||||||
private var articleIconSchemeHandler: ArticleIconSchemeHandler
|
|
||||||
private var completion: (PreloadedWebView) -> ()
|
|
||||||
|
|
||||||
init(queue: NSMutableArray, articleIconSchemeHandler: ArticleIconSchemeHandler, completion: @escaping (PreloadedWebView) -> ()) {
|
|
||||||
self.queue = queue
|
|
||||||
self.articleIconSchemeHandler = articleIconSchemeHandler
|
|
||||||
self.completion = completion
|
|
||||||
}
|
|
||||||
|
|
||||||
func run() {
|
|
||||||
if let webView = queue.lastObject as? PreloadedWebView {
|
|
||||||
self.completion(webView)
|
|
||||||
self.queue.remove(webView)
|
|
||||||
self.operationDelegate?.operationDidComplete(self)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assertionFailure("Creating PreloadedWebView in \(#function); queue has run dry.")
|
|
||||||
|
|
||||||
let webView = PreloadedWebView(articleIconSchemeHandler: articleIconSchemeHandler)
|
|
||||||
webView.preload()
|
|
||||||
self.completion(webView)
|
|
||||||
self.operationDelegate?.operationDidComplete(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -29,10 +29,10 @@ class FeedsViewController: UITableViewController, UndoableCommandRunner {
|
|||||||
private let keyboardManager = KeyboardManager(type: .sidebar)
|
private let keyboardManager = KeyboardManager(type: .sidebar)
|
||||||
override var keyCommands: [UIKeyCommand]? {
|
override var keyCommands: [UIKeyCommand]? {
|
||||||
|
|
||||||
// If the first responder is the WKWebView (PreloadedWebView) we don't want to supply any keyboard
|
// If the first responder is the WKWebView we don't want to supply any keyboard
|
||||||
// commands that the system is looking for by going up the responder chain. They will interfere with
|
// commands that the system is looking for by going up the responder chain. They will interfere with
|
||||||
// the WKWebViews built in hardware keyboard shortcuts, specifically the up and down arrow keys.
|
// the WKWebViews built in hardware keyboard shortcuts, specifically the up and down arrow keys.
|
||||||
guard let current = UIResponder.currentFirstResponder, !(current is PreloadedWebView) else { return nil }
|
guard let current = UIResponder.currentFirstResponder, !(current is WKWebView) else { return nil }
|
||||||
|
|
||||||
return keyboardManager.keyCommands
|
return keyboardManager.keyCommands
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,6 @@ class SceneCoordinator: NSObject, UndoableCommandRunner {
|
|||||||
return rootSplitViewController.undoManager
|
return rootSplitViewController.undoManager
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy var webViewProvider = WebViewProvider(coordinator: self)
|
|
||||||
|
|
||||||
private var panelMode: PanelMode = .unset
|
private var panelMode: PanelMode = .unset
|
||||||
|
|
||||||
private var activityManager = ActivityManager()
|
private var activityManager = ActivityManager()
|
||||||
|
@ -34,10 +34,10 @@ class TimelineViewController: UITableViewController, UndoableCommandRunner {
|
|||||||
private let keyboardManager = KeyboardManager(type: .timeline)
|
private let keyboardManager = KeyboardManager(type: .timeline)
|
||||||
override var keyCommands: [UIKeyCommand]? {
|
override var keyCommands: [UIKeyCommand]? {
|
||||||
|
|
||||||
// If the first responder is the WKWebView (PreloadedWebView) we don't want to supply any keyboard
|
// If the first responder is the WKWebView we don't want to supply any keyboard
|
||||||
// commands that the system is looking for by going up the responder chain. They will interfere with
|
// commands that the system is looking for by going up the responder chain. They will interfere with
|
||||||
// the WKWebViews built in hardware keyboard shortcuts, specifically the up and down arrow keys.
|
// the WKWebViews built in hardware keyboard shortcuts, specifically the up and down arrow keys.
|
||||||
guard let current = UIResponder.currentFirstResponder, !(current is PreloadedWebView) else { return nil }
|
guard let current = UIResponder.currentFirstResponder, !(current is WKWebView) else { return nil }
|
||||||
|
|
||||||
return keyboardManager.keyCommands
|
return keyboardManager.keyCommands
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user