Web Inspector: consolidate code that hosts the Inspector page inside a WKWebView
authorbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Oct 2017 17:28:53 +0000 (17:28 +0000)
committerbburg@apple.com <bburg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Oct 2017 17:28:53 +0000 (17:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=177661
<rdar://problem/34740286>

Reviewed by Joseph Pecoraro.

Move code that sets up and controls the inspector WebView into WKInspectorViewController.
This will be shared between RemoteWebInspectorProxy and WebInspectorProxy eventually,
but for now just pull out code from RemoteWebInspectorProxy. The next patch will move
over WebInspectorProxy.

WKInspectorViewController uses the ObjC API for setting up the WKWebView's delegates.
Previously, a WKWebView was used but the delegates were set up using the C API. In
a few cases it uses delegate methods to ask the owning [Remote]WebInspectorProxy some
things. In general, WKInspectorViewController doesn't dig into any internals of
WebPageProxy or WebInspectorProxy; that is delegated to the client.

* UIProcess/RemoteWebInspectorProxy.h:
(WebKit::RemoteWebInspectorProxy::isUnderTest const): Add a method stub for now.
We might want to enable tests for a _WKRemoteWebInspectorViewController-based UI
in the future, and WebInspectorProxy has the same method. Add this and connect it
to the view controller delegate method.

(WebKit::RemoteWebInspectorProxy::webView const):
This returns a plain WKWebView type now.

* UIProcess/mac/RemoteWebInspectorProxyMac.mm:
(-[WKRemoteWebInspectorProxyObjCAdapter inspectorViewControllerInspectorDidCrash:]):
(-[WKRemoteWebInspectorProxyObjCAdapter inspectorViewControllerInspectorIsUnderTest:]):
(-[WKRemoteWebInspectorProxyObjCAdapter webViewWebContentProcessDidTerminate:]): Deleted.
(-[WKRemoteWebInspectorProxyObjCAdapter webView:decidePolicyForNavigationAction:decisionHandler:]): Deleted.
Make the ObjCAdapter forward view controller delegate calls to the C++ class.
It no longer needs to be the delegate of the WebView, as the view controller handles that.

(WebKit::RemoteWebInspectorProxy::platformCreateFrontendPageAndWindow):
Clean up and move WKWebView setup code into the view controller.

(WebKit::RemoteWebInspectorProxy::platformCloseFrontendPageAndWindow):
The m_inspectorPage is closed by the caller before calling this method, so we don't need to do it here.

(WebKit::RemoteWebInspectorProxy::platformBringToFront):
(WebKit::RemoteWebInspectorProxy::platformSave):
(WebKit::RemoteWebInspectorProxy::platformAppend):
(WebKit::RemoteWebInspectorProxy::platformStartWindowDrag):
Use webView() instead of m_webView.

* UIProcess/mac/WKInspectorViewController.h: Added.
* UIProcess/mac/WKInspectorViewController.mm: Added.
(-[WKInspectorWKWebView tag]):
(-[WKInspectorViewController initWithInspectedPage:]):
(-[WKInspectorViewController dealloc]):
(-[WKInspectorViewController delegate]):
(-[WKInspectorViewController webView]):
(-[WKInspectorViewController setDelegate:]):
(-[WKInspectorViewController configuration]):
(-[WKInspectorViewController _webView:getWindowFrameWithCompletionHandler:]):
(-[WKInspectorViewController _webView:setWindowFrame:]):
(-[WKInspectorViewController webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:]):
(-[WKInspectorViewController _webView:decideDatabaseQuotaForSecurityOrigin:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:]):
(-[WKInspectorViewController webViewWebContentProcessDidTerminate:]):
(-[WKInspectorViewController webView:decidePolicyForNavigationAction:decisionHandler:]):
Move code from RemoteWebInspectorProxyMac into here.

* UIProcess/mac/WebInspectorProxyMac.mm:
(WebKit::WebInspectorProxy::createFrontendWindow):
Remove commented out code left over from the last time that this method got moved around.

* WebKit.xcodeproj/project.pbxproj:
Add new class.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223770 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/RemoteWebInspectorProxy.h
Source/WebKit/UIProcess/mac/RemoteWebInspectorProxyMac.mm
Source/WebKit/UIProcess/mac/WKInspectorViewController.h [new file with mode: 0644]
Source/WebKit/UIProcess/mac/WKInspectorViewController.mm [new file with mode: 0644]
Source/WebKit/UIProcess/mac/WebInspectorProxyMac.mm
Source/WebKit/WebKit.xcodeproj/project.pbxproj

index 73fbcce..9c170a2 100644 (file)
@@ -1,3 +1,75 @@
+2017-09-30  Brian Burg  <bburg@apple.com>
+
+        Web Inspector: consolidate code that hosts the Inspector page inside a WKWebView
+        https://bugs.webkit.org/show_bug.cgi?id=177661
+        <rdar://problem/34740286>
+
+        Reviewed by Joseph Pecoraro.
+
+        Move code that sets up and controls the inspector WebView into WKInspectorViewController.
+        This will be shared between RemoteWebInspectorProxy and WebInspectorProxy eventually,
+        but for now just pull out code from RemoteWebInspectorProxy. The next patch will move
+        over WebInspectorProxy.
+
+        WKInspectorViewController uses the ObjC API for setting up the WKWebView's delegates.
+        Previously, a WKWebView was used but the delegates were set up using the C API. In
+        a few cases it uses delegate methods to ask the owning [Remote]WebInspectorProxy some
+        things. In general, WKInspectorViewController doesn't dig into any internals of
+        WebPageProxy or WebInspectorProxy; that is delegated to the client.
+
+        * UIProcess/RemoteWebInspectorProxy.h:
+        (WebKit::RemoteWebInspectorProxy::isUnderTest const): Add a method stub for now.
+        We might want to enable tests for a _WKRemoteWebInspectorViewController-based UI
+        in the future, and WebInspectorProxy has the same method. Add this and connect it
+        to the view controller delegate method.
+
+        (WebKit::RemoteWebInspectorProxy::webView const):
+        This returns a plain WKWebView type now.
+
+        * UIProcess/mac/RemoteWebInspectorProxyMac.mm:
+        (-[WKRemoteWebInspectorProxyObjCAdapter inspectorViewControllerInspectorDidCrash:]):
+        (-[WKRemoteWebInspectorProxyObjCAdapter inspectorViewControllerInspectorIsUnderTest:]):
+        (-[WKRemoteWebInspectorProxyObjCAdapter webViewWebContentProcessDidTerminate:]): Deleted.
+        (-[WKRemoteWebInspectorProxyObjCAdapter webView:decidePolicyForNavigationAction:decisionHandler:]): Deleted.
+        Make the ObjCAdapter forward view controller delegate calls to the C++ class.
+        It no longer needs to be the delegate of the WebView, as the view controller handles that.
+
+        (WebKit::RemoteWebInspectorProxy::platformCreateFrontendPageAndWindow):
+        Clean up and move WKWebView setup code into the view controller.
+
+        (WebKit::RemoteWebInspectorProxy::platformCloseFrontendPageAndWindow):
+        The m_inspectorPage is closed by the caller before calling this method, so we don't need to do it here.
+
+        (WebKit::RemoteWebInspectorProxy::platformBringToFront):
+        (WebKit::RemoteWebInspectorProxy::platformSave):
+        (WebKit::RemoteWebInspectorProxy::platformAppend):
+        (WebKit::RemoteWebInspectorProxy::platformStartWindowDrag):
+        Use webView() instead of m_webView.
+
+        * UIProcess/mac/WKInspectorViewController.h: Added.
+        * UIProcess/mac/WKInspectorViewController.mm: Added.
+        (-[WKInspectorWKWebView tag]):
+        (-[WKInspectorViewController initWithInspectedPage:]):
+        (-[WKInspectorViewController dealloc]):
+        (-[WKInspectorViewController delegate]):
+        (-[WKInspectorViewController webView]):
+        (-[WKInspectorViewController setDelegate:]):
+        (-[WKInspectorViewController configuration]):
+        (-[WKInspectorViewController _webView:getWindowFrameWithCompletionHandler:]):
+        (-[WKInspectorViewController _webView:setWindowFrame:]):
+        (-[WKInspectorViewController webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:]):
+        (-[WKInspectorViewController _webView:decideDatabaseQuotaForSecurityOrigin:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:]):
+        (-[WKInspectorViewController webViewWebContentProcessDidTerminate:]):
+        (-[WKInspectorViewController webView:decidePolicyForNavigationAction:decisionHandler:]):
+        Move code from RemoteWebInspectorProxyMac into here.
+
+        * UIProcess/mac/WebInspectorProxyMac.mm:
+        (WebKit::WebInspectorProxy::createFrontendWindow):
+        Remove commented out code left over from the last time that this method got moved around.
+
+        * WebKit.xcodeproj/project.pbxproj:
+        Add new class.
+
 2017-10-20  Zan Dobersek  <zdobersek@igalia.com>
 
         [WK2] Drop 'CoordinatedGraphics' as a platform prefix from generate-forwarding-headers.pl
index 981abe7..75d9eaf 100644 (file)
@@ -35,8 +35,9 @@
 #if PLATFORM(MAC)
 OBJC_CLASS NSURL;
 OBJC_CLASS NSWindow;
+OBJC_CLASS WKInspectorViewController;
 OBJC_CLASS WKRemoteWebInspectorProxyObjCAdapter;
-OBJC_CLASS WKWebInspectorWKWebView;
+OBJC_CLASS WKWebView;
 #endif
 
 namespace WebKit {
@@ -61,6 +62,8 @@ public:
 
     void setClient(RemoteWebInspectorProxyClient* client) { m_client = client; }
 
+    bool isUnderTest() const { return false; }
+
     void invalidate();
 
     void load(const String& debuggableType, const String& backendCommandsURL);
@@ -71,7 +74,7 @@ public:
 
 #if PLATFORM(MAC)
     NSWindow *window() const { return m_window.get(); }
-    WKWebInspectorWKWebView *webView() const { return m_webView.get(); }
+    WKWebView *webView() const;
 #endif
 
 #if PLATFORM(GTK)
@@ -111,7 +114,7 @@ private:
     WebPageProxy* m_inspectorPage { nullptr };
 
 #if PLATFORM(MAC)
-    RetainPtr<WKWebInspectorWKWebView> m_webView;
+    RetainPtr<WKInspectorViewController> m_inspectorView;
     RetainPtr<NSWindow> m_window;
     RetainPtr<WKRemoteWebInspectorProxyObjCAdapter> m_objCAdapter;
     HashMap<String, RetainPtr<NSURL>> m_suggestedToActualURLMap;
index ef5711c..c899e49 100644 (file)
@@ -31,9 +31,9 @@
 #import "RemoteWebInspectorProxyMessages.h"
 #import "RemoteWebInspectorUIMessages.h"
 #import "WKFrameInfo.h"
+#import "WKInspectorViewController.h"
 #import "WKNavigationAction.h"
 #import "WKNavigationDelegate.h"
-#import "WKWebInspectorWKWebView.h"
 #import "WKWebViewInternal.h"
 #import "WebInspectorProxy.h"
 #import "WebPageGroup.h"
@@ -42,7 +42,7 @@
 
 using namespace WebKit;
 
-@interface WKRemoteWebInspectorProxyObjCAdapter : NSObject <WKNavigationDelegate> {
+@interface WKRemoteWebInspectorProxyObjCAdapter : NSObject <WKInspectorViewControllerDelegate> {
     RemoteWebInspectorProxy* _inspectorProxy;
 }
 - (instancetype)initWithRemoteWebInspectorProxy:(RemoteWebInspectorProxy*)inspectorProxy;
@@ -60,51 +60,39 @@ using namespace WebKit;
     return self;
 }
 
-- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
+- (void)inspectorViewControllerInspectorDidCrash:(WKInspectorViewController *)inspectorViewController
 {
     _inspectorProxy->closeFromCrash();
 }
 
-- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
+- (BOOL)inspectorViewControllerInspectorIsUnderTest:(WKInspectorViewController *)inspectorViewController
 {
-    // Allow non-main frames to navigate anywhere.
-    if (!navigationAction.targetFrame.isMainFrame) {
-        decisionHandler(WKNavigationActionPolicyAllow);
-        return;
-    }
-
-    // Allow loading of the main inspector file.
-    if (WebInspectorProxy::isMainOrTestInspectorPage(navigationAction.request.URL)) {
-        decisionHandler(WKNavigationActionPolicyAllow);
-        return;
-    }
-
-    // Prevent everything else.
-    decisionHandler(WKNavigationActionPolicyCancel);
+    return _inspectorProxy->isUnderTest();
 }
 
 @end
 
 namespace WebKit {
 
-WebPageProxy* RemoteWebInspectorProxy::platformCreateFrontendPageAndWindow()
+WKWebView *RemoteWebInspectorProxy::webView() const
 {
-    NSRect initialFrame = NSMakeRect(0, 0, WebInspectorProxy::initialWindowWidth, WebInspectorProxy::initialWindowHeight);
-    auto configuration = WebInspectorProxy::createFrontendConfiguration(nullptr, false);
+    return m_inspectorView.get().webView;
+}
 
+WebPageProxy* RemoteWebInspectorProxy::platformCreateFrontendPageAndWindow()
+{
     m_objCAdapter = adoptNS([[WKRemoteWebInspectorProxyObjCAdapter alloc] initWithRemoteWebInspectorProxy:this]);
 
-    m_webView = adoptNS([[WKWebInspectorWKWebView alloc] initWithFrame:initialFrame configuration:configuration.get()]);
-    [m_webView setNavigationDelegate:m_objCAdapter.get()];
+    m_inspectorView = adoptNS([[WKInspectorViewController alloc] initWithInspectedPage:nil]);
+    [m_inspectorView.get() setDelegate:m_objCAdapter.get()];
 
     m_window = WebInspectorProxy::createFrontendWindow(NSZeroRect);
 
-    NSView *contentView = [m_window contentView];
-    [m_webView setFrame:[contentView bounds]];
-    [m_webView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
-    [contentView addSubview:m_webView.get()];
+    NSView *contentView = m_window.get().contentView;
+    [webView() setFrame:contentView.bounds];
+    [contentView addSubview:webView()];
 
-    return m_webView->_page.get();
+    return webView()->_page.get();
 }
 
 void RemoteWebInspectorProxy::platformCloseFrontendPageAndWindow()
@@ -115,22 +103,19 @@ void RemoteWebInspectorProxy::platformCloseFrontendPageAndWindow()
         m_window = nil;
     }
 
-    if (m_webView) {
-        WebPageProxy* inspectorPage = m_webView->_page.get();
-        inspectorPage->close();
-        [m_webView setNavigationDelegate:nil];
-        m_webView = nil;
+    if (m_inspectorView) {
+        [m_inspectorView.get() setDelegate:nil];
+        m_inspectorView = nil;
     }
 
     if (m_objCAdapter)
         m_objCAdapter = nil;
 }
 
-
 void RemoteWebInspectorProxy::platformBringToFront()
 {
     [m_window makeKeyAndOrderFront:nil];
-    [m_window makeFirstResponder:m_webView.get()];
+    [m_window makeFirstResponder:webView()];
 }
 
 void RemoteWebInspectorProxy::platformSave(const String& suggestedURL, const String& content, bool base64Encoded, bool forceSaveDialog)
@@ -168,8 +153,7 @@ void RemoteWebInspectorProxy::platformSave(const String& suggestedURL, const Str
         } else
             [contentCopy writeToURL:actualURL atomically:YES encoding:NSUTF8StringEncoding error:NULL];
 
-        WebPageProxy* inspectorPage = m_webView->_page.get();
-        inspectorPage->process().send(Messages::RemoteWebInspectorUI::DidSave([actualURL absoluteString]), inspectorPage->pageID());
+        m_inspectorPage->process().send(Messages::RemoteWebInspectorUI::DidSave([actualURL absoluteString]), m_inspectorPage->pageID());
     };
 
     if (!forceSaveDialog) {
@@ -215,13 +199,13 @@ void RemoteWebInspectorProxy::platformAppend(const String& suggestedURL, const S
     [handle writeData:[content dataUsingEncoding:NSUTF8StringEncoding]];
     [handle closeFile];
 
-    WebPageProxy* inspectorPage = m_webView->_page.get();
+    WebPageProxy* inspectorPage = webView()->_page.get();
     inspectorPage->process().send(Messages::RemoteWebInspectorUI::DidAppend([actualURL absoluteString]), inspectorPage->pageID());
 }
 
 void RemoteWebInspectorProxy::platformStartWindowDrag()
 {
-    m_webView->_page->startWindowDrag();
+    webView()->_page->startWindowDrag();
 }
 
 void RemoteWebInspectorProxy::platformOpenInNewTab(const String& url)
diff --git a/Source/WebKit/UIProcess/mac/WKInspectorViewController.h b/Source/WebKit/UIProcess/mac/WKInspectorViewController.h
new file mode 100644 (file)
index 0000000..8b932ca
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#import <WebKit/WKFoundation.h>
+
+#if PLATFORM(MAC) && WK_API_ENABLED
+
+OBJC_CLASS WKWebView;
+
+namespace WebKit {
+class WebPageProxy;
+}
+
+@protocol WKInspectorViewControllerDelegate;
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface WKInspectorViewController : NSObject
+
+@property (nonatomic, readonly) WKWebView *webView;
+@property (nonatomic, weak) id <WKInspectorViewControllerDelegate> delegate;
+
+- (instancetype)initWithInspectedPage:(WebKit::WebPageProxy* _Nullable)inspectedPage;
+
+@end
+
+@protocol WKInspectorViewControllerDelegate <NSObject>
+@optional
+- (void)inspectorViewControllerInspectorDidCrash:(WKInspectorViewController *)inspectorViewController;
+- (BOOL)inspectorViewControllerInspectorIsUnderTest:(WKInspectorViewController *)inspectorViewController;
+@end
+
+NS_ASSUME_NONNULL_END
+
+#endif // PLATFORM(MAC) && WK_API_ENABLED
diff --git a/Source/WebKit/UIProcess/mac/WKInspectorViewController.mm b/Source/WebKit/UIProcess/mac/WKInspectorViewController.mm
new file mode 100644 (file)
index 0000000..465df1c
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "WKInspectorViewController.h"
+
+#if PLATFORM(MAC) && WK_API_ENABLED
+
+#import "WKFrameInfo.h"
+#import "WKNavigationAction.h"
+#import "WKNavigationDelegate.h"
+#import "WKOpenPanelParameters.h"
+#import "WKPreferencesPrivate.h"
+#import "WKProcessPoolInternal.h"
+#import "WKUIDelegatePrivate.h"
+#import "WKWebView.h"
+#import "WKWebViewConfigurationPrivate.h"
+#import "WeakObjCPtr.h"
+#import "WebInspectorProxy.h"
+#import "WebInspectorUtilities.h"
+#import "WebPageProxy.h"
+
+// FIXME: this should be declared in the ObjC API; currently it's in the C SPI.
+const NSInteger WKInspectorViewTag = 1000;
+
+using namespace WebKit;
+
+// Clients need to be able to tell whether a subview is a docked inspector view, so override the tag.
+@interface WKInspectorWKWebView : WKWebView
+@end
+
+@implementation WKInspectorWKWebView
+- (NSInteger)tag
+{
+    return WKInspectorViewTag;
+}
+@end
+
+@interface WKInspectorViewController () <WKUIDelegate, WKNavigationDelegate>
+@end
+
+@implementation WKInspectorViewController {
+    WebPageProxy* _inspectedPage;
+    RetainPtr<WKInspectorWKWebView> _webView;
+    WebKit::WeakObjCPtr<id <WKInspectorViewControllerDelegate>> _delegate;
+}
+
+- (instancetype)initWithInspectedPage:(WebKit::WebPageProxy* _Nullable)inspectedPage
+{
+    if (!(self = [super init]))
+        return nil;
+
+    // The (local) inspected page is nil if the controller is hosting a Remote Web Inspector view.
+    _inspectedPage = inspectedPage;
+
+    return self;
+}
+
+- (void)dealloc
+{
+    if (_webView) {
+        [_webView setUIDelegate:nil];
+        [_webView setNavigationDelegate:nil];
+        _webView = nil;
+    }
+
+    [super dealloc];
+}
+
+- (id <WKInspectorViewControllerDelegate>)delegate
+{
+    return _delegate.getAutoreleased();
+}
+
+- (WKWebView *)webView
+{
+    // Construct lazily so the client can set the delegate before the WebView is created.
+    if (!_webView) {
+        NSRect initialFrame = NSMakeRect(0, 0, WebInspectorProxy::initialWindowWidth, WebInspectorProxy::initialWindowHeight);
+        _webView = adoptNS([[WKInspectorWKWebView alloc] initWithFrame:initialFrame configuration:[self configuration]]);
+        [_webView setUIDelegate:self];
+        [_webView setNavigationDelegate:self];
+        [_webView _setAutomaticallyAdjustsContentInsets:NO];
+        [_webView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+    }
+
+    return _webView.get();
+}
+
+- (void)setDelegate:(id <WKInspectorViewControllerDelegate>)delegate
+{
+    _delegate = delegate;
+}
+
+- (WKWebViewConfiguration *)configuration
+{
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+
+    WKPreferences *preferences = configuration.get().preferences;
+    preferences._allowFileAccessFromFileURLs = YES;
+    [configuration _setAllowUniversalAccessFromFileURLs:YES];
+    preferences._storageBlockingPolicy = _WKStorageBlockingPolicyAllowAll;
+    preferences._javaScriptRuntimeFlags = 0;
+
+#ifndef NDEBUG
+    // Allow developers to inspect the Web Inspector in debug builds without changing settings.
+    preferences._developerExtrasEnabled = YES;
+    preferences._logsPageMessagesToSystemConsoleEnabled = YES;
+#endif
+
+    if (!!_delegate && [_delegate respondsToSelector:@selector(inspectorViewControllerInspectorIsUnderTest:)]) {
+        if ([_delegate inspectorViewControllerInspectorIsUnderTest:self]) {
+            preferences._hiddenPageDOMTimerThrottlingEnabled = NO;
+            preferences._pageVisibilityBasedProcessSuppressionEnabled = NO;
+        }
+    }
+
+    [configuration setProcessPool: ::WebKit::wrapper(inspectorProcessPool(inspectorLevelForPage(_inspectedPage)))];
+    [configuration _setGroupIdentifier:inspectorPageGroupIdentifierForPage(_inspectedPage)];
+
+    return configuration.autorelease();
+}
+
+// MARK: WKUIDelegate methods
+
+- (void)_webView:(WKWebView *)webView getWindowFrameWithCompletionHandler:(void (^)(CGRect))completionHandler
+{
+    if (!_webView.get().window)
+        completionHandler(CGRectZero);
+    else
+        completionHandler(NSRectToCGRect([webView frame]));
+}
+
+- (void)_webView:(WKWebView *)webView setWindowFrame:(CGRect)frame
+{
+    if (!_webView.get().window)
+        return;
+
+    [_webView.get().window setFrame:NSRectFromCGRect(frame) display:YES];
+}
+
+- (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray<NSURL *> * _Nullable URLs))completionHandler
+{
+    NSOpenPanel *openPanel = [NSOpenPanel openPanel];
+    openPanel.allowsMultipleSelection = parameters.allowsMultipleSelection;
+
+    auto reportSelectedFiles = ^(NSInteger result) {
+        if (result == NSModalResponseOK)
+            completionHandler(openPanel.URLs);
+        else
+            completionHandler(nil);
+    };
+
+    if (_webView.get().window)
+        [openPanel beginSheetModalForWindow:_webView.get().window completionHandler:reportSelectedFiles];
+    else
+        reportSelectedFiles([openPanel runModal]);
+}
+
+- (void)_webView:(WKWebView *)webView decideDatabaseQuotaForSecurityOrigin:(WKSecurityOrigin *)securityOrigin currentQuota:(unsigned long long)currentQuota currentOriginUsage:(unsigned long long)currentOriginUsage currentDatabaseUsage:(unsigned long long)currentUsage expectedUsage:(unsigned long long)expectedUsage decisionHandler:(void (^)(unsigned long long newQuota))decisionHandler
+{
+    decisionHandler(std::max<unsigned long long>(expectedUsage, currentUsage * 1.25));
+}
+
+// MARK: WKNavigationDelegate methods
+
+- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
+{
+    if (!!_delegate && [_delegate respondsToSelector:@selector(inspectorViewControllerInspectorDidCrash:)])
+        [_delegate inspectorViewControllerInspectorDidCrash:self];
+}
+
+- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
+{
+    // Allow non-main frames to navigate anywhere.
+    if (!navigationAction.targetFrame.isMainFrame) {
+        decisionHandler(WKNavigationActionPolicyAllow);
+        return;
+    }
+
+    // Allow loading of the main inspector file.
+    if (WebInspectorProxy::isMainOrTestInspectorPage(navigationAction.request.URL)) {
+        decisionHandler(WKNavigationActionPolicyAllow);
+        return;
+    }
+
+    // Prevent everything else.
+    decisionHandler(WKNavigationActionPolicyCancel);
+}
+
+@end
+
+#endif // PLATFORM(MAC) && WK_API_ENABLED
index b023fd0..cb76c76 100644 (file)
@@ -222,9 +222,7 @@ RetainPtr<WKWebViewConfiguration> WebInspectorProxy::createFrontendConfiguration
 RetainPtr<NSWindow> WebInspectorProxy::createFrontendWindow(NSRect savedWindowFrame)
 {
     NSRect windowFrame = !NSIsEmptyRect(savedWindowFrame) ? savedWindowFrame : NSMakeRect(0, 0, initialWindowWidth, initialWindowHeight);
-
     auto window = adoptNS([[NSWindow alloc] initWithContentRect:windowFrame styleMask:windowStyleMask backing:NSBackingStoreBuffered defer:NO]);
-    // [window setDelegate:m_inspectorProxyObjCAdapter.get()];
     [window setMinSize:NSMakeSize(minimumWindowWidth, minimumWindowHeight)];
     [window setReleasedWhenClosed:NO];
     [window setCollectionBehavior:([window collectionBehavior] | NSWindowCollectionBehaviorFullScreenPrimary)];
index 6fdbfa6..f625bf3 100644 (file)
                99249AD51F1F1E5600B62FBB /* AutomationFrontendDispatchers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99249AD31F1F1E3300B62FBB /* AutomationFrontendDispatchers.cpp */; };
                99249AD61F1F1E5F00B62FBB /* AutomationFrontendDispatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = 99249AD41F1F1E3300B62FBB /* AutomationFrontendDispatchers.h */; };
                9946EF861E7B027000541E79 /* WebAutomationSessionIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9946EF851E7B026600541E79 /* WebAutomationSessionIOS.mm */; };
+               994BADF31F7D781100B571E7 /* WKInspectorViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 994BADF21F7D77EB00B571E7 /* WKInspectorViewController.mm */; };
+               994BADF41F7D781400B571E7 /* WKInspectorViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 994BADF11F7D77EA00B571E7 /* WKInspectorViewController.h */; };
                9955A6EC1C7980C200EB6A93 /* WebAutomationSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 9955A6EB1C7980BB00EB6A93 /* WebAutomationSession.h */; };
                9955A6ED1C7980CA00EB6A93 /* WebAutomationSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9955A6EA1C7980BB00EB6A93 /* WebAutomationSession.cpp */; };
                9955A6EF1C79810800EB6A93 /* Automation.json in Headers */ = {isa = PBXBuildFile; fileRef = 9955A6E91C7980BB00EB6A93 /* Automation.json */; settings = {ATTRIBUTES = (Private, ); }; };
                99249AD31F1F1E3300B62FBB /* AutomationFrontendDispatchers.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AutomationFrontendDispatchers.cpp; sourceTree = "<group>"; };
                99249AD41F1F1E3300B62FBB /* AutomationFrontendDispatchers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AutomationFrontendDispatchers.h; sourceTree = "<group>"; };
                9946EF851E7B026600541E79 /* WebAutomationSessionIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebAutomationSessionIOS.mm; sourceTree = "<group>"; };
+               994BADF11F7D77EA00B571E7 /* WKInspectorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKInspectorViewController.h; sourceTree = "<group>"; };
+               994BADF21F7D77EB00B571E7 /* WKInspectorViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKInspectorViewController.mm; sourceTree = "<group>"; };
                9955A6E91C7980BB00EB6A93 /* Automation.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Automation.json; sourceTree = "<group>"; };
                9955A6EA1C7980BB00EB6A93 /* WebAutomationSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebAutomationSession.cpp; sourceTree = "<group>"; };
                9955A6EB1C7980BB00EB6A93 /* WebAutomationSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebAutomationSession.h; sourceTree = "<group>"; };
                                CDCA85C6132ABA4E00E961DF /* WKFullScreenWindowController.mm */,
                                9321D5851A38EE3C008052BE /* WKImmediateActionController.h */,
                                9321D5871A38EE74008052BE /* WKImmediateActionController.mm */,
+                               994BADF11F7D77EA00B571E7 /* WKInspectorViewController.h */,
+                               994BADF21F7D77EB00B571E7 /* WKInspectorViewController.mm */,
                                0FCB4E5C18BBE3D9000FCFC9 /* WKPrintingView.h */,
                                0FCB4E5D18BBE3D9000FCFC9 /* WKPrintingView.mm */,
                                513E462B1AD837560016234A /* WKSharingServicePickerDelegate.h */,
                                BCF049E711FE20F600F86A58 /* WKBundlePrivate.h in Headers */,
                                BC60C5791240A546008C5E29 /* WKBundleRangeHandle.h in Headers */,
                                BC5D24C716CD73C5007D5461 /* WKBundleRangeHandlePrivate.h in Headers */,
+                               994BADF41F7D781400B571E7 /* WKInspectorViewController.h in Headers */,
                                BC14DF9F120B635F00826C0C /* WKBundleScriptWorld.h in Headers */,
                                BC4075F6124FF0270068F20A /* WKCertificateInfo.h in Headers */,
                                BC407627124FF0400068F20A /* WKCertificateInfoMac.h in Headers */,
                                2D5C9D0519C81D8F00B3C5C1 /* WebPageOverlay.cpp in Sources */,
                                BC111B0F112F5E4F00337BAB /* WebPageProxy.cpp in Sources */,
                                1AC0273F196622D600C12B75 /* WebPageProxyCocoa.mm in Sources */,
+                               994BADF31F7D781100B571E7 /* WKInspectorViewController.mm in Sources */,
                                2DA944AF1884E9BA00ED86DB /* WebPageProxyIOS.mm in Sources */,
                                BC857E8712B71EBB00EDEB2E /* WebPageProxyMac.mm in Sources */,
                                BCBD3914125BB1A800D2C29F /* WebPageProxyMessageReceiver.cpp in Sources */,