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