From 0b6683d0734a32302c23ae9e60316c615cb014e4 Mon Sep 17 00:00:00 2001 From: Ben Ubois Date: Wed, 18 Sep 2019 22:03:23 -0700 Subject: [PATCH 1/3] Render with evaluateJavaScript. Replaced loadHTMLString based rendering for improved performance. --- .../Detail/DetailWebViewController.swift | 22 +- NetNewsWire.xcodeproj/project.pbxproj | 20 +- .../Article Rendering/ArticleRenderer.swift | 72 +------ Shared/Article Rendering/page.html | 202 ++++++++++++++++++ 4 files changed, 236 insertions(+), 80 deletions(-) create mode 100644 Shared/Article Rendering/page.html diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index 4b9cd8f82..9e18fe44b 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -100,7 +100,13 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { NotificationCenter.default.addObserver(self, selector: #selector(webInspectorEnabledDidChange(_:)), name: .WebInspectorEnabledDidChange, object: nil) - reloadHTML() + webView.loadHTMLString(template(), baseURL: nil) + } + + func template() -> String { + let path = Bundle.main.path(forResource: "page", ofType: "html")! + let s = try! NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue) + return s as String } // MARK: Scrolling @@ -162,6 +168,9 @@ extension DetailWebViewController: WKNavigationDelegate { } // MARK: - Private +struct TemplateData: Codable { + let body: String +} private extension DetailWebViewController { @@ -179,8 +188,17 @@ private extension DetailWebViewController { case .extracted(let article, let extractedArticle): html = ArticleRenderer.articleHTML(article: article, extractedArticle: extractedArticle, style: style) } + + let templateData = TemplateData(body: html) + + let encoder = JSONEncoder() + var render = "error();" + if let data = try? encoder.encode(templateData) { + let json = String(data: data, encoding: .utf8)! + render = "render(\(json));" + } - webView.loadHTMLString(html, baseURL: nil) + webView.evaluateJavaScript(render) } func fetchScrollInfo(_ callback: @escaping (ScrollInfo?) -> Void) { diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index e250e0e26..36f833f0c 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -372,6 +372,8 @@ 84FF69B11FC3793300DC198E /* FaviconURLFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FF69B01FC3793300DC198E /* FaviconURLFinder.swift */; }; 9EA33BB92318F8C10097B644 /* AccountsFeedlyWebWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA33BB72318F8C10097B644 /* AccountsFeedlyWebWindowController.swift */; }; 9EA33BBA2318F8C10097B644 /* AccountsFeedlyWeb.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9EA33BB82318F8C10097B644 /* AccountsFeedlyWeb.xib */; }; + B528F81E23333C7E00E735DD /* page.html in Resources */ = {isa = PBXBuildFile; fileRef = B528F81D23333C7E00E735DD /* page.html */; }; + B528F81F23333C7E00E735DD /* page.html in Resources */ = {isa = PBXBuildFile; fileRef = B528F81D23333C7E00E735DD /* page.html */; }; D553738B20186C20006D8857 /* Article+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D553737C20186C1F006D8857 /* Article+Scriptability.swift */; }; D57BE6E0204CD35F00D11AAC /* NSScriptCommand+NetNewsWire.swift in Sources */ = {isa = PBXBuildFile; fileRef = D57BE6DF204CD35F00D11AAC /* NSScriptCommand+NetNewsWire.swift */; }; D5907D7F2004AC00005947E5 /* NSApplication+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5907D7E2004AC00005947E5 /* NSApplication+Scriptability.swift */; }; @@ -1051,10 +1053,11 @@ 84F9EAE4213660A100CF2DE4 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = Frameworks/Vendor/Sparkle.framework; sourceTree = SOURCE_ROOT; }; 84FF69B01FC3793300DC198E /* FaviconURLFinder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FaviconURLFinder.swift; sourceTree = ""; }; - B24EFD482330FF99006C6242 /* NetNewsWire-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NetNewsWire-Bridging-Header.h"; sourceTree = ""; }; - B24EFD5923310109006C6242 /* WKPreferencesPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WKPreferencesPrivate.h; sourceTree = ""; }; 9EA33BB72318F8C10097B644 /* AccountsFeedlyWebWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsFeedlyWebWindowController.swift; sourceTree = ""; }; 9EA33BB82318F8C10097B644 /* AccountsFeedlyWeb.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountsFeedlyWeb.xib; sourceTree = ""; }; + B24EFD482330FF99006C6242 /* NetNewsWire-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NetNewsWire-Bridging-Header.h"; sourceTree = ""; }; + B24EFD5923310109006C6242 /* WKPreferencesPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WKPreferencesPrivate.h; sourceTree = ""; }; + B528F81D23333C7E00E735DD /* page.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = page.html; sourceTree = ""; }; D519E74722EE553300923F27 /* NetNewsWire_safariextension_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetNewsWire_safariextension_target.xcconfig; sourceTree = ""; }; D553737C20186C1F006D8857 /* Article+Scriptability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Article+Scriptability.swift"; sourceTree = ""; }; D57BE6DF204CD35F00D11AAC /* NSScriptCommand+NetNewsWire.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSScriptCommand+NetNewsWire.swift"; sourceTree = ""; }; @@ -1381,6 +1384,7 @@ isa = PBXGroup; children = ( 849A977D1ED9EC42007D329B /* ArticleRenderer.swift */, + B528F81D23333C7E00E735DD /* page.html */, 848362FE2262A30E00DA1D35 /* template.html */, ); path = "Article Rendering"; @@ -2223,16 +2227,16 @@ TargetAttributes = { 513C5CE5232571C2003D4054 = { CreatedOnToolsVersion = 11.0; - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = DY2XQRVWN9; ProvisioningStyle = Automatic; }; 6581C73220CED60000F4AD34 = { DevelopmentTeam = SHJK2V3AJG; - ProvisioningStyle = Automatic; + ProvisioningStyle = Manual; }; 840D617B2029031C009BC708 = { CreatedOnToolsVersion = 9.3; - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = DY2XQRVWN9; ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.BackgroundModes = { @@ -2243,7 +2247,7 @@ 849C645F1ED37A5D003D8FC0 = { CreatedOnToolsVersion = 8.2.1; DevelopmentTeam = SHJK2V3AJG; - ProvisioningStyle = Automatic; + ProvisioningStyle = Manual; SystemCapabilities = { com.apple.HardenedRuntime = { enabled = 1; @@ -2252,7 +2256,7 @@ }; 849C64701ED37A5D003D8FC0 = { CreatedOnToolsVersion = 8.2.1; - DevelopmentTeam = SHJK2V3AJG; + DevelopmentTeam = 9C84TZ7Q6Z; ProvisioningStyle = Automatic; TestTargetID = 849C645F1ED37A5D003D8FC0; }; @@ -2491,6 +2495,7 @@ 511D43EF231FBDE900FB1562 /* LaunchScreenPad.storyboard in Resources */, 511D43D2231FA62C00FB1562 /* GlobalKeyboardShortcuts.plist in Resources */, 84C9FCA12262A1B300D921D6 /* Main.storyboard in Resources */, + B528F81F23333C7E00E735DD /* page.html in Resources */, 51F85BF32272531500C787DC /* Dedication.rtf in Resources */, 84C9FCA42262A1B800D921D6 /* LaunchScreenPhone.storyboard in Resources */, 51F85BEB22724CB600C787DC /* About.rtf in Resources */, @@ -2532,6 +2537,7 @@ 848363052262A3CC00DA1D35 /* AddFolderSheet.xib in Resources */, 5144EA52227B8E4500D19003 /* AccountsFeedbin.xib in Resources */, 8405DDA222168920008CE1BF /* TimelineTableView.xib in Resources */, + B528F81E23333C7E00E735DD /* page.html in Resources */, 8483630E2262A3FE00DA1D35 /* MainWindow.storyboard in Resources */, 55E15BCB229D65A900D6602A /* AccountsReaderAPI.xib in Resources */, 84BAE64921CEDAF20046DB56 /* CrashReporterWindow.xib in Resources */, diff --git a/Shared/Article Rendering/ArticleRenderer.swift b/Shared/Article Rendering/ArticleRenderer.swift index 5359bb414..e79fcc69d 100644 --- a/Shared/Article Rendering/ArticleRenderer.swift +++ b/Shared/Article Rendering/ArticleRenderer.swift @@ -328,87 +328,17 @@ private extension ArticleRenderer { return dateFormatter.string(from: date) } - #if os(macOS) - func renderHTML(withBody body: String) -> String { - - var s = "\n\n" + var s = "" if let baseURL = baseURL { s += ("") } s += title.htmlBySurroundingWithTag("title") - s += styleString().htmlBySurroundingWithTag("style") - - s += """ - - - - """ - - s += "\n\n\n\n" s += body - s += "\n\n" - - //print(s) - return s } - - #else - - func renderHTML(withBody body: String) -> String { - - var s = "\n" - if let baseURL = baseURL { - s += ("") - } - s += "\n" - s += title.htmlBySurroundingWithTag("title") - s += styleString().htmlBySurroundingWithTag("style") - s += """ - - - """ - - s += "\n\n\n\n" - s += body - s += "\n\n" - - return s - - } - - #endif - } // MARK: - Article extension diff --git a/Shared/Article Rendering/page.html b/Shared/Article Rendering/page.html new file mode 100644 index 000000000..af99dbbaa --- /dev/null +++ b/Shared/Article Rendering/page.html @@ -0,0 +1,202 @@ + + + + + + + + From 1c9117ab8e9d2702c7fa259993c7d1ef66da5fa1 Mon Sep 17 00:00:00 2001 From: Ben Ubois Date: Wed, 18 Sep 2019 22:39:07 -0700 Subject: [PATCH 2/3] Reset scroll position to top on render. Prevents an issue where the next article would inherit the previous article's scroll position. --- Shared/Article Rendering/page.html | 1 + 1 file changed, 1 insertion(+) diff --git a/Shared/Article Rendering/page.html b/Shared/Article Rendering/page.html index af99dbbaa..b25dc0312 100644 --- a/Shared/Article Rendering/page.html +++ b/Shared/Article Rendering/page.html @@ -182,6 +182,7 @@ function render(data) { document.body.innerHTML = data.body; + window.scrollTo(0, 0); var anchors = document.getElementsByTagName("a"); for (var i = 0; i < anchors.length; i++) { anchors[i].addEventListener("mouseenter", function() { mouseDidEnterLink(this) }); From 1728f4d1981f8d40752c620bed154f94575a9e49 Mon Sep 17 00:00:00 2001 From: Ben Ubois Date: Wed, 18 Sep 2019 22:53:25 -0700 Subject: [PATCH 3/3] Made indents consistent. --- Shared/Article Rendering/page.html | 166 ++++++++++++++--------------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/Shared/Article Rendering/page.html b/Shared/Article Rendering/page.html index b25dc0312..78d2b6e69 100644 --- a/Shared/Article Rendering/page.html +++ b/Shared/Article Rendering/page.html @@ -2,138 +2,138 @@