diff --git a/Mac/AppDefaults.swift b/Mac/AppDefaults.swift index b5e56d235..7250cd2c6 100644 --- a/Mac/AppDefaults.swift +++ b/Mac/AppDefaults.swift @@ -37,6 +37,9 @@ struct AppDefaults { static let timelineShowsSeparators = "CorreiaSeparators" static let showTitleOnMainWindow = "KafasisTitleMode" static let hideDockUnreadCount = "JustinMillerHideDockUnreadCount" + + static let webInspectorEnabled = "WebInspectorEnabled" + static let webInspectorStartsAttached = "__WebInspectorPageGroupLevel1__.WebKit2InspectorStartsAttached" } private static let smallestFontSizeRawValue = FontSize.small.rawValue @@ -139,6 +142,24 @@ struct AppDefaults { return bool(for: Key.hideDockUnreadCount) } + static var webInspectorEnabled: Bool { + get { + return bool(for: Key.webInspectorEnabled) + } + set { + setBool(for: Key.webInspectorEnabled, newValue) + } + } + + static var webInspectorStartsAttached: Bool { + get { + return bool(for: Key.webInspectorStartsAttached) + } + set { + setBool(for: Key.webInspectorStartsAttached, newValue) + } + } + static var timelineSortDirection: ComparisonResult { get { return sortDirection(for: Key.timelineSortDirection) diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift index cc05f2812..d09174bbd 100644 --- a/Mac/AppDelegate.swift +++ b/Mac/AppDelegate.swift @@ -314,6 +314,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, if item.action == #selector(showAddFeedWindow(_:)) || item.action == #selector(showAddFolderWindow(_:)) { return !isDisplayingSheet && !AccountManager.shared.activeAccounts.isEmpty } + if item.action == #selector(toggleWebInspectorEnabled(_:)) { + (item as! NSMenuItem).state = AppDefaults.webInspectorEnabled ? .on : .off + } return true } @@ -535,6 +538,18 @@ extension AppDelegate { @IBAction func debugSearch(_ sender: Any?) { AccountManager.shared.defaultAccount.debugRunSearch() } + + @IBAction func toggleWebInspectorEnabled(_ sender: Any?) { + let newValue = !AppDefaults.webInspectorEnabled + AppDefaults.webInspectorEnabled = newValue + + // An attached inspector can display incorrectly on certain setups (like mine); default to displaying in a separate window, + // and reset the default to a separate window when the preference is toggled off and on again in case the inspector is + // accidentally reattached. + + AppDefaults.webInspectorStartsAttached = false + NotificationCenter.default.post(name: .WebInspectorEnabledDidChange, object: newValue) + } } private extension AppDelegate { diff --git a/Mac/Base.lproj/Main.storyboard b/Mac/Base.lproj/Main.storyboard index 13c78b0d4..9aeaf4d10 100644 --- a/Mac/Base.lproj/Main.storyboard +++ b/Mac/Base.lproj/Main.storyboard @@ -476,6 +476,13 @@ + + + + + + + diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index b4b92ad52..9e889db4b 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -27,6 +27,15 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { } } } + + private var webInspectorEnabled: Bool { + get { + return webView.configuration.preferences._developerExtrasEnabled + } + set { + webView.configuration.preferences._developerExtrasEnabled = newValue + } + } private var waitingForFirstReload = false private let keyboardDelegate = DetailKeyboardDelegate() @@ -87,6 +96,10 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { webView.isHidden = true waitingForFirstReload = true + webInspectorEnabled = AppDefaults.webInspectorEnabled + + NotificationCenter.default.addObserver(self, selector: #selector(webInspectorEnabledDidChange(_:)), name: .WebInspectorEnabledDidChange, object: nil) + reloadHTML() } @@ -185,6 +198,10 @@ private extension DetailWebViewController { callback(scrollInfo) } } + + @objc func webInspectorEnabledDidChange(_ notification: Notification) { + self.webInspectorEnabled = notification.object! as! Bool + } } // MARK: - ScrollInfo diff --git a/Mac/NetNewsWire-Bridging-Header.h b/Mac/NetNewsWire-Bridging-Header.h new file mode 100644 index 000000000..3f547bcf1 --- /dev/null +++ b/Mac/NetNewsWire-Bridging-Header.h @@ -0,0 +1,9 @@ +// +// NetNewsWire-Bridging-Header.h +// NetNewsWire +// +// Created by Nate Weaver on 2019-09-17. +// Copyright © 2019 Ranchero Software. All rights reserved. +// + +#import "WKPreferencesPrivate.h" diff --git a/Mac/WKPreferencesPrivate.h b/Mac/WKPreferencesPrivate.h new file mode 100644 index 000000000..232e10fc1 --- /dev/null +++ b/Mac/WKPreferencesPrivate.h @@ -0,0 +1,15 @@ +// +// WKPreferencesPrivate.h +// NetNewsWire +// +// Created by Nate Weaver on 2019-09-17. +// Copyright © 2019 Ranchero Software. All rights reserved. +// + +#import + +@interface WKPreferences (Private) + +@property (nonatomic, setter=_setDeveloperExtrasEnabled:) BOOL _developerExtrasEnabled API_AVAILABLE(macos(10.11), ios(9.0)); + +@end diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 7467594d5..745af6010 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -1037,6 +1037,8 @@ 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 = ""; }; D519E74722EE553300923F27 /* NetNewsWire_safariextension_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetNewsWire_safariextension_target.xcconfig; 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 = ""; }; 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 = ""; }; D5907CDC2002F0BE005947E5 /* NetNewsWire_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NetNewsWire_project_release.xcconfig; sourceTree = ""; }; @@ -1785,6 +1787,8 @@ 6581C73620CED60100F4AD34 /* SafariExtension */, 84C9FC8322629E8F00D921D6 /* Resources */, 84FB9A2C1EDCD6A4003D53B9 /* Frameworks */, + B24EFD482330FF99006C6242 /* NetNewsWire-Bridging-Header.h */, + B24EFD5923310109006C6242 /* WKPreferencesPrivate.h */, ); path = Mac; sourceTree = ""; diff --git a/Shared/AppNotifications.swift b/Shared/AppNotifications.swift index b847f1988..3fd03355a 100644 --- a/Shared/AppNotifications.swift +++ b/Shared/AppNotifications.swift @@ -13,6 +13,7 @@ extension Notification.Name { static let InspectableObjectsDidChange = Notification.Name("TimelineSelectionDidChangeNotification") static let UserDidAddFeed = Notification.Name("UserDidAddFeedNotification") static let UserDidRequestSidebarSelection = Notification.Name("UserDidRequestSidebarSelectionNotification") + static let WebInspectorEnabledDidChange = Notification.Name("WebInspectorEnabledDidChange") } typealias UserInfoDictionary = [AnyHashable: Any] diff --git a/Shared/Article Rendering/ArticleRenderer.swift b/Shared/Article Rendering/ArticleRenderer.swift index d2a32d525..49554ac25 100644 --- a/Shared/Article Rendering/ArticleRenderer.swift +++ b/Shared/Article Rendering/ArticleRenderer.swift @@ -342,6 +342,9 @@ private extension ArticleRenderer { anchors[i].addEventListener("mouseenter", function() { mouseDidEnterLink(this) }); anchors[i].addEventListener("mouseleave", function() { mouseDidExitLink(this) }); } + + document.getElementsByTagName("body")[0].querySelectorAll("style, link[rel=stylesheet]").forEach(element => element.remove()); + document.getElementsByTagName("body")[0].querySelectorAll("[style]").forEach(element => element.removeAttribute("style")); } function mouseDidEnterLink(anchor) { @@ -376,7 +379,20 @@ private extension ArticleRenderer { s += "\n" s += title.htmlBySurroundingWithTag("title") s += styleString().htmlBySurroundingWithTag("style") - s += "\n\n\n\n" + s += """ + + + + """ + + s += "\n\n\n\n" s += body s += "\n\n" diff --git a/xcconfig/NetNewsWire_macapp_target.xcconfig b/xcconfig/NetNewsWire_macapp_target.xcconfig index a8e1f1a98..3dbe4ae53 100644 --- a/xcconfig/NetNewsWire_macapp_target.xcconfig +++ b/xcconfig/NetNewsWire_macapp_target.xcconfig @@ -38,4 +38,5 @@ CODE_SIGN_ENTITLEMENTS = Mac/Resources/NetNewsWire.entitlements INFOPLIST_FILE = Mac/Resources/Info.plist LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.NetNewsWire-Evergreen -PRODUCT_NAME = NetNewsWire \ No newline at end of file +PRODUCT_NAME = NetNewsWire +SWIFT_OBJC_BRIDGING_HEADER = Mac/NetNewsWire-Bridging-Header.h