diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift index 44dc42137..7d80f7bf3 100644 --- a/Mac/AppDelegate.swift +++ b/Mac/AppDelegate.swift @@ -386,7 +386,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, alert.buttons[0].keyEquivalent = "\r" - let response = alert.runModal() + _ = alert.runModal() } } diff --git a/Mac/Base.lproj/Preferences.storyboard b/Mac/Base.lproj/Preferences.storyboard index ec3c0ba73..ddf26b887 100644 --- a/Mac/Base.lproj/Preferences.storyboard +++ b/Mac/Base.lproj/Preferences.storyboard @@ -527,16 +527,16 @@ - + - + - + - + @@ -643,7 +643,7 @@ - + @@ -698,16 +698,16 @@ - + - + - + - + @@ -810,7 +810,7 @@ - + diff --git a/Mac/CrashReporter/CrashReportWindowController.swift b/Mac/CrashReporter/CrashReportWindowController.swift index 7c7ce9ee7..5579e0ef3 100644 --- a/Mac/CrashReporter/CrashReportWindowController.swift +++ b/Mac/CrashReporter/CrashReportWindowController.swift @@ -8,7 +8,7 @@ import AppKit -final class CrashReportWindowController: NSWindowController { +@MainActor final class CrashReportWindowController: NSWindowController { @IBOutlet var textView: NSTextView! { didSet { diff --git a/Mac/CrashReporter/CrashReporter.swift b/Mac/CrashReporter/CrashReporter.swift index b37810a9d..09d1db06b 100644 --- a/Mac/CrashReporter/CrashReporter.swift +++ b/Mac/CrashReporter/CrashReporter.swift @@ -16,7 +16,7 @@ import CrashReporter // At some point this code should probably move into RSCore, so Rainier and any other // future apps can use it. -struct CrashReporter { +@MainActor struct CrashReporter { struct DefaultsKey { static let sendCrashLogsAutomaticallyKey = "SendCrashLogsAutomatically" diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index 71cca81c8..f1e5b2afe 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -98,6 +98,8 @@ final class DetailWebViewController: NSViewController { userContentController.add(self, name: MessageName.windowDidScroll) userContentController.add(self, name: MessageName.mouseDidEnter) userContentController.add(self, name: MessageName.mouseDidExit) + userContentController.addUserScript(forResource: "inject", withExtension: "js") + configuration.userContentController = userContentController webView = DetailWebView(frame: NSRect.zero, configuration: configuration) diff --git a/Mac/Preferences/Accounts/AccountCell.swift b/Mac/Preferences/Accounts/AccountCell.swift index 7a1dbecef..b6fb2eef3 100644 --- a/Mac/Preferences/Accounts/AccountCell.swift +++ b/Mac/Preferences/Accounts/AccountCell.swift @@ -8,7 +8,7 @@ import AppKit -class AccountCell: NSTableCellView { +@MainActor class AccountCell: NSTableCellView { private var originalImage: NSImage? diff --git a/Mac/Preferences/Accounts/AccountsAddCloudKitWindowController.swift b/Mac/Preferences/Accounts/AccountsAddCloudKitWindowController.swift index 6c01d9ef9..945453122 100644 --- a/Mac/Preferences/Accounts/AccountsAddCloudKitWindowController.swift +++ b/Mac/Preferences/Accounts/AccountsAddCloudKitWindowController.swift @@ -17,7 +17,7 @@ enum AccountsAddCloudKitWindowControllerError: LocalizedError { } } -class AccountsAddCloudKitWindowController: NSWindowController { +@MainActor class AccountsAddCloudKitWindowController: NSWindowController { @IBOutlet weak var limitationsAndSolutionsTextField: NSTextField! diff --git a/Mac/Preferences/Accounts/AccountsAddLocalWindowController.swift b/Mac/Preferences/Accounts/AccountsAddLocalWindowController.swift index 8aedbccd7..373ffea30 100644 --- a/Mac/Preferences/Accounts/AccountsAddLocalWindowController.swift +++ b/Mac/Preferences/Accounts/AccountsAddLocalWindowController.swift @@ -9,7 +9,7 @@ import AppKit import Account -class AccountsAddLocalWindowController: NSWindowController { +@MainActor class AccountsAddLocalWindowController: NSWindowController { @IBOutlet private weak var nameTextField: NSTextField! @IBOutlet private weak var localAccountNameTextField: NSTextField! diff --git a/Mac/Preferences/Accounts/AccountsDetailViewController.swift b/Mac/Preferences/Accounts/AccountsDetailViewController.swift index 3fe5487ee..6b395249e 100644 --- a/Mac/Preferences/Accounts/AccountsDetailViewController.swift +++ b/Mac/Preferences/Accounts/AccountsDetailViewController.swift @@ -9,7 +9,7 @@ import AppKit import Account -final class AccountsDetailViewController: NSViewController, NSTextFieldDelegate { +@MainActor final class AccountsDetailViewController: NSViewController, NSTextFieldDelegate { @IBOutlet weak var typeLabel: NSTextField! @IBOutlet weak var nameTextField: NSTextField! diff --git a/Mac/Preferences/Accounts/AccountsFeedbinWindowController.swift b/Mac/Preferences/Accounts/AccountsFeedbinWindowController.swift index 6ac802851..687e0c864 100644 --- a/Mac/Preferences/Accounts/AccountsFeedbinWindowController.swift +++ b/Mac/Preferences/Accounts/AccountsFeedbinWindowController.swift @@ -12,7 +12,7 @@ import RSCore import RSWeb import Secrets -class AccountsFeedbinWindowController: NSWindowController, Logging { +@MainActor class AccountsFeedbinWindowController: NSWindowController, Logging { @IBOutlet weak var signInTextField: NSTextField! @IBOutlet weak var noAccountTextField: NSTextField! diff --git a/Mac/Preferences/Accounts/AccountsNewsBlurWindowController.swift b/Mac/Preferences/Accounts/AccountsNewsBlurWindowController.swift index 0af42818e..9cb726e17 100644 --- a/Mac/Preferences/Accounts/AccountsNewsBlurWindowController.swift +++ b/Mac/Preferences/Accounts/AccountsNewsBlurWindowController.swift @@ -12,7 +12,7 @@ import RSWeb import RSCore import Secrets -class AccountsNewsBlurWindowController: NSWindowController, Logging { +@MainActor class AccountsNewsBlurWindowController: NSWindowController, Logging { @IBOutlet weak var signInTextField: NSTextField! @IBOutlet weak var noAccountTextField: NSTextField! diff --git a/Mac/Preferences/Accounts/AccountsPreferencesViewController.swift b/Mac/Preferences/Accounts/AccountsPreferencesViewController.swift index 307f5b8b5..66a0173cb 100644 --- a/Mac/Preferences/Accounts/AccountsPreferencesViewController.swift +++ b/Mac/Preferences/Accounts/AccountsPreferencesViewController.swift @@ -17,7 +17,7 @@ protocol AccountsPreferencesAddAccountDelegate { } // MARK: - AccountsPreferencesViewController -final class AccountsPreferencesViewController: NSViewController { +@MainActor final class AccountsPreferencesViewController: NSViewController { @IBOutlet weak var tableView: NSTableView! @IBOutlet weak var detailView: NSView! diff --git a/Mac/Preferences/Accounts/AccountsReaderAPIWindowController.swift b/Mac/Preferences/Accounts/AccountsReaderAPIWindowController.swift index b127003db..e282f327e 100644 --- a/Mac/Preferences/Accounts/AccountsReaderAPIWindowController.swift +++ b/Mac/Preferences/Accounts/AccountsReaderAPIWindowController.swift @@ -12,7 +12,7 @@ import RSWeb import RSCore import Secrets -class AccountsReaderAPIWindowController: NSWindowController, Logging { +@MainActor class AccountsReaderAPIWindowController: NSWindowController, Logging { @IBOutlet weak var titleImageView: NSImageView! @IBOutlet weak var titleLabel: NSTextField! diff --git a/Mac/Preferences/Advanced/AdvancedPreferencesViewController.swift b/Mac/Preferences/Advanced/AdvancedPreferencesViewController.swift index a48e9fe91..53ccc3aee 100644 --- a/Mac/Preferences/Advanced/AdvancedPreferencesViewController.swift +++ b/Mac/Preferences/Advanced/AdvancedPreferencesViewController.swift @@ -8,11 +8,10 @@ import AppKit -final class AdvancedPreferencesViewController: NSViewController { +@MainActor final class AdvancedPreferencesViewController: NSViewController { @IBOutlet var releaseBuildsButton: NSButton! @IBOutlet var testBuildsButton: NSButton! - @IBOutlet weak var privacyPolicyTextField: NSTextField! let releaseBuildsURL = Bundle.main.infoDictionary!["SUFeedURL"]! as! String let testBuildsURL = Bundle.main.infoDictionary!["FeedURLForTestBuilds"]! as! String @@ -35,7 +34,6 @@ final class AdvancedPreferencesViewController: NSViewController { NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil) didRegisterForNotification = true } - privacyPolicyTextField.attributedStringValue = AppAssets.privacyPolicyLink } @IBAction func updateTypeButtonClicked(_ sender: Any?) { diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointDetailViewController.swift b/Mac/Preferences/ExtensionPoints/ExtensionPointDetailViewController.swift index f94d0ae59..0a97d68ae 100644 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointDetailViewController.swift +++ b/Mac/Preferences/ExtensionPoints/ExtensionPointDetailViewController.swift @@ -8,7 +8,7 @@ import Cocoa -class ExtensionPointDetailViewController: NSViewController { +@MainActor class ExtensionPointDetailViewController: NSViewController { @IBOutlet weak var imageView: NSImageView! @IBOutlet weak var titleLabel: NSTextField! diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointEnableWindowController.swift b/Mac/Preferences/ExtensionPoints/ExtensionPointEnableWindowController.swift index f8aed7ff5..1af42d40e 100644 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointEnableWindowController.swift +++ b/Mac/Preferences/ExtensionPoints/ExtensionPointEnableWindowController.swift @@ -11,7 +11,7 @@ import AuthenticationServices import OAuthSwift import Secrets -class ExtensionPointEnableWindowController: NSWindowController { +@MainActor class ExtensionPointEnableWindowController: NSWindowController { @IBOutlet weak var imageView: NSImageView! @IBOutlet weak var titleLabel: NSTextField! diff --git a/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift b/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift index d79525d30..16a797a80 100644 --- a/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift +++ b/Mac/Preferences/ExtensionPoints/ExtensionPointPreferencesViewController.swift @@ -16,7 +16,7 @@ protocol ExtensionPointPreferencesEnabler: AnyObject { func enable(_ extensionPointType: ExtensionPoint.Type) } -final class ExtensionPointPreferencesViewController: NSViewController { +@MainActor final class ExtensionPointPreferencesViewController: NSViewController { @IBOutlet weak var tableView: NSTableView! @IBOutlet weak var detailView: NSView! diff --git a/Mac/Preferences/General/GeneralPrefencesViewController.swift b/Mac/Preferences/General/GeneralPrefencesViewController.swift index 19fa9b7a0..0b55a756d 100644 --- a/Mac/Preferences/General/GeneralPrefencesViewController.swift +++ b/Mac/Preferences/General/GeneralPrefencesViewController.swift @@ -11,7 +11,7 @@ import RSCore import RSWeb import UserNotifications -final class GeneralPreferencesViewController: NSViewController { +@MainActor final class GeneralPreferencesViewController: NSViewController { private var userNotificationSettings: UNNotificationSettings? diff --git a/Mac/Preferences/PreferencesControlsBackgroundView.swift b/Mac/Preferences/PreferencesControlsBackgroundView.swift index 36353dd6b..307109c50 100644 --- a/Mac/Preferences/PreferencesControlsBackgroundView.swift +++ b/Mac/Preferences/PreferencesControlsBackgroundView.swift @@ -9,7 +9,7 @@ import AppKit import RSCore -final class PreferencesControlsBackgroundView: NSView { +@MainActor final class PreferencesControlsBackgroundView: NSView { private let lightModeFillColor = NSColor(white: 0.97, alpha: 1.0) private let darkModeFillColor = NSColor(red: 0.32, green: 0.34, blue: 0.35, alpha: 1.0) diff --git a/Mac/Preferences/PreferencesTableViewBackgroundView.swift b/Mac/Preferences/PreferencesTableViewBackgroundView.swift index 34548e429..df9fce2db 100644 --- a/Mac/Preferences/PreferencesTableViewBackgroundView.swift +++ b/Mac/Preferences/PreferencesTableViewBackgroundView.swift @@ -8,7 +8,7 @@ import AppKit -final class PreferencesTableViewBackgroundView: NSView { +@MainActor final class PreferencesTableViewBackgroundView: NSView { let lightBorderColor = NSColor(white: 0.71, alpha: 1.0) let darkBorderColor = NSColor(red: 0.41, green: 0.43, blue: 0.44, alpha: 1.0) diff --git a/Mac/Preferences/PreferencesWindowController.swift b/Mac/Preferences/PreferencesWindowController.swift index 738aa5d81..f4d7b898f 100644 --- a/Mac/Preferences/PreferencesWindowController.swift +++ b/Mac/Preferences/PreferencesWindowController.swift @@ -28,7 +28,7 @@ private struct ToolbarItemIdentifier { static let Advanced = "Advanced" } -class PreferencesWindowController : NSWindowController, NSToolbarDelegate { +@MainActor class PreferencesWindowController : NSWindowController, NSToolbarDelegate { private let windowWidth = CGFloat(512.0) // Width is constant for all views; only the height changes private var viewControllers = [String: NSViewController]() diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 56fae063f..567cad45d 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -207,6 +207,12 @@ 514C16DE24D2EF15009A3AFA /* RSTree in Frameworks */ = {isa = PBXBuildFile; productRef = 514C16DD24D2EF15009A3AFA /* RSTree */; }; 514C16DF24D2EF15009A3AFA /* RSTree in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 514C16DD24D2EF15009A3AFA /* RSTree */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 514C16E124D2EF38009A3AFA /* RSCoreResources in Frameworks */ = {isa = PBXBuildFile; productRef = 514C16E024D2EF38009A3AFA /* RSCoreResources */; }; + 514DE4C129DDFD16001B0D79 /* WKUserContentController-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514DE4C029DDFD16001B0D79 /* WKUserContentController-Extensions.swift */; }; + 514DE4C329DE0609001B0D79 /* inject.js in Resources */ = {isa = PBXBuildFile; fileRef = 514DE4C229DE0609001B0D79 /* inject.js */; }; + 514DE4C429DE0609001B0D79 /* inject.js in Resources */ = {isa = PBXBuildFile; fileRef = 514DE4C229DE0609001B0D79 /* inject.js */; }; + 514DE4C529DE0609001B0D79 /* inject.js in Resources */ = {isa = PBXBuildFile; fileRef = 514DE4C229DE0609001B0D79 /* inject.js */; }; + 514DE4C629DE4536001B0D79 /* WKUserContentController-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514DE4C029DDFD16001B0D79 /* WKUserContentController-Extensions.swift */; }; + 514DE4C729DE4537001B0D79 /* WKUserContentController-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514DE4C029DDFD16001B0D79 /* WKUserContentController-Extensions.swift */; }; 5153A35428DC5CEB0036C545 /* RSCore in Frameworks */ = {isa = PBXBuildFile; productRef = DF2A8F32289BFBD9002455AD /* RSCore */; }; 5154368B229404D1005E1CDF /* FaviconGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51EF0F76227716200050506E /* FaviconGenerator.swift */; }; 515A50E6243D07A90089E588 /* ExtensionPointManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 515A50E5243D07A90089E588 /* ExtensionPointManager.swift */; }; @@ -1228,6 +1234,8 @@ 5148F44A2336DB4700F8CD8B /* MasterTimelineTitleView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MasterTimelineTitleView.xib; sourceTree = ""; }; 5148F4542336DB7000F8CD8B /* MasterTimelineTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasterTimelineTitleView.swift; sourceTree = ""; }; 514B7C8223205EFB00BAC947 /* RootSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootSplitViewController.swift; sourceTree = ""; }; + 514DE4C029DDFD16001B0D79 /* WKUserContentController-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WKUserContentController-Extensions.swift"; sourceTree = ""; }; + 514DE4C229DE0609001B0D79 /* inject.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = inject.js; sourceTree = ""; }; 515A50E5243D07A90089E588 /* ExtensionPointManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointManager.swift; sourceTree = ""; }; 515A5147243E64BA0089E588 /* ExtensionPointEnableWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPointEnableWindowController.swift; sourceTree = ""; }; 515A516D243E7F950089E588 /* ExtensionPointDetail.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExtensionPointDetail.xib; sourceTree = ""; }; @@ -2145,13 +2153,14 @@ 51C452A822650DA100C03939 /* Article Rendering */ = { isa = PBXGroup; children = ( - 51D0214526ED617100FF2E0F /* core.css */, - B27EEBDF244D15F2000932E6 /* stylesheet.css */, - 848362FE2262A30E00DA1D35 /* template.html */, - 517630032336215100E15FFF /* main.js */, - 49F40DEF2335B71000552BF4 /* newsfoot.js */, 849A977D1ED9EC42007D329B /* ArticleRenderer.swift */, 51DC07972552083500A3F79F /* ArticleTextSize.swift */, + 51D0214526ED617100FF2E0F /* core.css */, + 514DE4C229DE0609001B0D79 /* inject.js */, + 517630032336215100E15FFF /* main.js */, + 49F40DEF2335B71000552BF4 /* newsfoot.js */, + B27EEBDF244D15F2000932E6 /* stylesheet.css */, + 848362FE2262A30E00DA1D35 /* template.html */, ); path = "Article Rendering"; sourceTree = ""; @@ -2374,6 +2383,7 @@ 51F85BF42273625800C787DC /* Bundle-Extensions.swift */, 5108F6B52375E612001ABC45 /* CacheCleaner.swift */, 516AE9DE2372269A007DEEAA /* IconImage.swift */, + 51D205EE28E3CF8D007C46EF /* LinkTextField.swift */, 849A97971ED9EFAA007D329B /* Node-Extensions.swift */, B24E9ABA245AB88300DA5718 /* NSAttributedString+NetNewsWire.swift */, 519279F728E23F5F000AE856 /* NSEvent-Extensions.swift */, @@ -2382,7 +2392,7 @@ 51126DA3225FDE2F00722696 /* RSImage-Extensions.swift */, 84411E701FE5FBFA004B527F /* SmallIconProvider.swift */, 51BC4ADD247277DF000A6ED8 /* URL-Extensions.swift */, - 51D205EE28E3CF8D007C46EF /* LinkTextField.swift */, + 514DE4C029DDFD16001B0D79 /* WKUserContentController-Extensions.swift */, ); path = Extensions; sourceTree = ""; @@ -3386,6 +3396,7 @@ 65ED406A235DEF6C0081F399 /* newsfoot.js in Resources */, 5103A9992421643300410853 /* blank.html in Resources */, 65ED406B235DEF6C0081F399 /* CrashReporterWindow.xib in Resources */, + 514DE4C429DE0609001B0D79 /* inject.js in Resources */, 65ED406C235DEF6C0081F399 /* Credits.rtf in Resources */, 65ED406D235DEF6C0081F399 /* Inspector.storyboard in Resources */, 65ED406E235DEF6C0081F399 /* AddWebFeedSheet.xib in Resources */, @@ -3426,6 +3437,7 @@ 51DEE81A26FBFF84006DAA56 /* Promenade.nnwtheme in Resources */, 1768140B2564BB8300D98635 /* NetNewsWire_iOSwidgetextension_target.xcconfig in Resources */, 5103A9B424216A4200410853 /* blank.html in Resources */, + 514DE4C529DE0609001B0D79 /* inject.js in Resources */, 51D0214826ED617100FF2E0F /* core.css in Resources */, 84C9FCA42262A1B800D921D6 /* LaunchScreenPhone.storyboard in Resources */, 516A093B2360A4A000EAE89B /* SettingsTableViewCell.xib in Resources */, @@ -3468,6 +3480,7 @@ 5142194B2353C1CF00E07E2C /* main_mac.js in Resources */, DFCE4F9128EF26F100405869 /* About.plist in Resources */, 84C9FC8C22629E8F00D921D6 /* KeyboardShortcuts.html in Resources */, + 514DE4C329DE0609001B0D79 /* inject.js in Resources */, B27EEBF9244D15F3000932E6 /* stylesheet.css in Resources */, 5144EA3B227A379E00D19003 /* ImportOPMLSheet.xib in Resources */, 844B5B691FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist in Resources */, @@ -3928,6 +3941,7 @@ 519279F928E23F5F000AE856 /* NSEvent-Extensions.swift in Sources */, 65ED4015235DEF6C0081F399 /* AccountsDetailViewController.swift in Sources */, 65ED4016235DEF6C0081F399 /* DetailViewController.swift in Sources */, + 514DE4C729DE4537001B0D79 /* WKUserContentController-Extensions.swift in Sources */, 5117715624E1EA0F00A2A836 /* ArticleExtractorButton.swift in Sources */, 65ED4017235DEF6C0081F399 /* AppDelegate.swift in Sources */, 65ED4018235DEF6C0081F399 /* PreferencesTableViewBackgroundView.swift in Sources */, @@ -4151,6 +4165,7 @@ 84DEE56622C32CA4005FC42C /* SmartFeedDelegate.swift in Sources */, 512E09012268907400BDCFDD /* MasterFeedTableViewSectionHeader.swift in Sources */, 512392BF24E33A3C00F11704 /* RedditSelectSortTableViewController.swift in Sources */, + 514DE4C629DE4536001B0D79 /* WKUserContentController-Extensions.swift in Sources */, 516AE9E02372269A007DEEAA /* IconImage.swift in Sources */, 519ED456244828C3007F8E94 /* AddExtensionPointViewController.swift in Sources */, 51C45268226508F600C03939 /* MasterFeedUnreadCountView.swift in Sources */, @@ -4347,6 +4362,7 @@ 510C418124E5D1AE008226FD /* ExtensionContainers.swift in Sources */, 51EC114C2149FE3300B296E3 /* FolderTreeMenu.swift in Sources */, 849ADEE42359817E000E1B81 /* NNW3ImportController.swift in Sources */, + 514DE4C129DDFD16001B0D79 /* WKUserContentController-Extensions.swift in Sources */, 179C39EB26F76B3800D4E741 /* ArticleThemePlist.swift in Sources */, 849A97A31ED9F180007D329B /* FolderTreeControllerDelegate.swift in Sources */, 51126DA4225FDE2F00722696 /* RSImage-Extensions.swift in Sources */, diff --git a/Shared/Article Extractor/ArticleExtractor.swift b/Shared/Article Extractor/ArticleExtractor.swift index 1fd4d151b..1b6cdd4f3 100644 --- a/Shared/Article Extractor/ArticleExtractor.swift +++ b/Shared/Article Extractor/ArticleExtractor.swift @@ -40,10 +40,10 @@ class ArticleExtractor: Logging { let clientURL = "https://extract.feedbin.com/parser" let username = SecretsManager.provider.mercuryClientId - let signiture = articleLink.hmacUsingSHA1(key: SecretsManager.provider.mercuryClientSecret) + let signature = articleLink.hmacUsingSHA1(key: SecretsManager.provider.mercuryClientSecret) if let base64URL = articleLink.data(using: .utf8)?.base64EncodedString() { - let fullURL = "\(clientURL)/\(username)/\(signiture)?base64_url=\(base64URL)" + let fullURL = "\(clientURL)/\(username)/\(signature)?base64_url=\(base64URL)" if let url = URL(string: fullURL) { self.url = url return diff --git a/Shared/Article Rendering/inject.js b/Shared/Article Rendering/inject.js new file mode 100644 index 000000000..957c23af6 --- /dev/null +++ b/Shared/Article Rendering/inject.js @@ -0,0 +1,44 @@ +function fixYouTube() { + var checkForVideoTimer = null; + + function callback(event) { + var fullScreenButtonOld = document.querySelector("button.ytp-fullscreen-button"); + var fullScreenButton = fullScreenButtonOld.cloneNode(true); + fullScreenButton.style = false; + fullScreenButton.setAttribute("aria-disabled", "false"); + fullScreenButton.onclick = function() { + var player = document.querySelector("video"); + player.webkitRequestFullScreen(); + }; + fullScreenButtonOld.parentNode.replaceChild(fullScreenButton, fullScreenButtonOld); + } + + function checkForVideo() { + var video = document.querySelector("video"); + if (video) { + clearInterval(checkForVideoTimer); + + var goFullScreen = function() { + video.webkitRequestFullScreen(); + }; + + var fullScreenButtonOld = document.querySelector("button.ytp-fullscreen-button"); + var fullScreenButton = fullScreenButtonOld.cloneNode(true); + fullScreenButton.style = false; + fullScreenButton.setAttribute("aria-disabled", "false"); + fullScreenButton.onclick = goFullScreen; + fullScreenButtonOld.parentNode.replaceChild(fullScreenButton, fullScreenButtonOld); + } + } + + const hostname = window.location.hostname; + if (hostname.endsWith(".youtube.com") || hostname.endsWith(".youtube-nocookie.com")) { + checkForVideoTimer = setInterval(checkForVideo, 100); + } + + document.addEventListener('webkitfullscreenchange', fullScreenChange, true); +} + +document.addEventListener("DOMContentLoaded", function(event) { + fixYouTube(); +}); diff --git a/Shared/Article Rendering/main.js b/Shared/Article Rendering/main.js index f072c9bdd..53c8f93b3 100644 --- a/Shared/Article Rendering/main.js +++ b/Shared/Article Rendering/main.js @@ -156,19 +156,18 @@ function removeWpSmiley() { } } -function addYouTubeVideos() { +function addYouTubeVideo() { const titleURL = document.querySelector(".articleTitle A").getAttribute("href") const youTubeLink = "https://www.youtube.com/watch?v=" if (!titleURL.startsWith(youTubeLink)) { return; } - - // Dynamically add the YouTube frame + const bodyContainer = document.querySelector("#bodyContainer"); bodyContainer.setAttribute("style", "position: relative; padding-bottom: 56.25%; height: 100%; max-width: 100% !important; overflow: hidden;") - + var youTubeFrame = document.createElement("iFrame"); - youTubeFrame.setAttribute("src", "https://www.youtube.com/embed/" + titleURL.substring(youTubeLink.length)); + youTubeFrame.setAttribute("src", "https://www.youtube.com/embed/" + titleURL.substring(youTubeLink.length) + "?fs=0&rel=0"); youTubeFrame.setAttribute("style", "position: absolute; top: 0; left: 0; width: 100%; height: 100%;"); youTubeFrame.setAttribute("title", "YouTube video player"); youTubeFrame.setAttribute("frameborder", "0"); @@ -186,6 +185,6 @@ function processPage() { flattenPreElements(); styleLocalFootnotes(); removeWpSmiley(); - addYouTubeVideos(); + addYouTubeVideo(); postRenderProcessing(); } diff --git a/Shared/Exporters/OPMLExporter.swift b/Shared/Exporters/OPMLExporter.swift index cba135a17..46d232e11 100644 --- a/Shared/Exporters/OPMLExporter.swift +++ b/Shared/Exporters/OPMLExporter.swift @@ -10,7 +10,7 @@ import Foundation import Account import RSCore -struct OPMLExporter { +@MainActor struct OPMLExporter { static func OPMLString(with account: Account, title: String) -> String { diff --git a/Shared/Extensions/CacheCleaner.swift b/Shared/Extensions/CacheCleaner.swift index b80896c5d..14046d523 100644 --- a/Shared/Extensions/CacheCleaner.swift +++ b/Shared/Extensions/CacheCleaner.swift @@ -10,7 +10,7 @@ import Foundation import RSWeb import RSCore -struct CacheCleaner: Logging { +@MainActor struct CacheCleaner: Logging { static func purgeIfNecessary() { diff --git a/Shared/Extensions/WKUserContentController-Extensions.swift b/Shared/Extensions/WKUserContentController-Extensions.swift new file mode 100644 index 000000000..635449185 --- /dev/null +++ b/Shared/Extensions/WKUserContentController-Extensions.swift @@ -0,0 +1,21 @@ +// +// WKUserContentController-Extensions.swift +// NetNewsWire +// +// Created by Maurice Parker on 4/5/23. +// Copyright © 2023 Ranchero Software. All rights reserved. +// + +import Foundation +import WebKit + +extension WKUserContentController { + + func addUserScript(forResource res: String, withExtension ext: String) { + if let url = Bundle.main.url(forResource: res, withExtension: ext), let source = try? String(contentsOf: url) { + let userScript = WKUserScript(source: source, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: false) + addUserScript(userScript) + } + } + +} diff --git a/Shared/Importers/DefaultFeeds.opml b/Shared/Importers/DefaultFeeds.opml index 04132dbaa..ecac3d91e 100644 --- a/Shared/Importers/DefaultFeeds.opml +++ b/Shared/Importers/DefaultFeeds.opml @@ -5,12 +5,17 @@ + + + + + diff --git a/Shared/Importers/DefaultFeedsImporter.swift b/Shared/Importers/DefaultFeedsImporter.swift index 8ed67d3b9..d02b2cec3 100644 --- a/Shared/Importers/DefaultFeedsImporter.swift +++ b/Shared/Importers/DefaultFeedsImporter.swift @@ -10,7 +10,7 @@ import Foundation import Account import RSCore -struct DefaultFeedsImporter { +@MainActor struct DefaultFeedsImporter { static func importDefaultFeeds(account: Account) { let defaultFeedsURL = Bundle.main.url(forResource: "DefaultFeeds", withExtension: "opml")! diff --git a/iOS/Article/WebViewController.swift b/iOS/Article/WebViewController.swift index 375a7d926..295e2e2ca 100644 --- a/iOS/Article/WebViewController.swift +++ b/iOS/Article/WebViewController.swift @@ -545,6 +545,7 @@ private extension WebViewController { webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasClicked) webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasShown) webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.showFeedInspector) + webView.configuration.userContentController.addUserScript(forResource: "inject", withExtension: "js") self.renderPage(webView)