Title: [286799] trunk
Revision
286799
Author
bb...@apple.com
Date
2021-12-09 12:55:16 -0800 (Thu, 09 Dec 2021)

Log Message

[Cocoa] Web Inspector: provide a way for _WKInspectorExtension clients to be to notified when an extension tab navigates
https://bugs.webkit.org/show_bug.cgi?id=233935
<rdar://86123899>

Reviewed by Patrick Angle.

Source/WebCore:

Add new InspectorFrontendHost hooks to notify the client about didNavigateExtensionTab().

* inspector/InspectorFrontendClient.h:
(WebCore::InspectorFrontendClient::didNavigateExtensionTab):
* inspector/InspectorFrontendHost.cpp:
(WebCore::InspectorFrontendHost::didNavigateExtensionTab):
* inspector/InspectorFrontendHost.h:
* inspector/InspectorFrontendHost.idl:

Source/WebInspectorUI:

In order instrument all loads inside the extension iframe, we cannot rely on the <iframe src> attribute
to query the currently loaded page, or to change the current page. Use a helper method to query and set
the iframe location indirectly using `document.location`.

* UserInterface/Protocol/InspectorFrontendAPI.js:

* UserInterface/Controllers/WebInspectorExtensionController.js:
(WI.WebInspectorExtensionController.prototype.createTabForExtension):
(WI.WebInspectorExtensionController.prototype.showExtensionTab):
Standardize on returning {"result": value} from these methods.

* UserInterface/Views/WebInspectorExtensionTabContentView.js:
(WI.WebInspectorExtensionTabContentView):
(WI.WebInspectorExtensionTabContentView.prototype.whenPageAvailable): Added.
(WI.WebInspectorExtensionTabContentView.prototype._extensionFrameDidLoad):
Trigger a load of the actual requested page by evaluating `document.location.href = ""
in the context of the extension tab iframe. Notify clients when this non-initial load completes.

(WI.WebInspectorExtensionTabContentView.prototype.async _maybeDispatchDidNavigateExtensionTab):
Dispatch didNavigateExtensionTab with the new URL when the extension tab iframe completes a load.
Don't notify the client if the extension tab has not yet loaded.

Source/WebKit:

Add plumbing to notify clients when an extension tab loads. This is implemented similarly to
-inspectorExtension:didShowExtensionTab: and -inspectorExtension:didHideExtensionTab:.

* UIProcess/API/APIInspectorExtensionClient.h:
(API::InspectorExtensionClient::didNavigateExtensionTab):

* UIProcess/API/Cocoa/_WKInspectorExtensionDelegate.h:

* UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.h:
* UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.mm:
(WebKit::InspectorExtensionDelegate::InspectorExtensionDelegate):
(WebKit::InspectorExtensionDelegate::InspectorExtensionClient::didNavigateExtensionTab):

* UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.messages.in:
* UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.h:
* UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.cpp:
(WebKit::WebInspectorUIExtensionControllerProxy::didNavigateExtensionTab):

* WebProcess/Inspector/RemoteWebInspectorUI.h:
* WebProcess/Inspector/RemoteWebInspectorUI.cpp:
(WebKit::RemoteWebInspectorUI::didNavigateExtensionTab):

* WebProcess/Inspector/WebInspectorUI.h:
* WebProcess/Inspector/WebInspectorUI.cpp:
(WebKit::WebInspectorUI::didHideExtensionTab):
(WebKit::WebInspectorUI::didNavigateExtensionTab):

* WebProcess/Inspector/WebInspectorUIExtensionController.h:
* WebProcess/Inspector/WebInspectorUIExtensionController.cpp:
(WebKit::WebInspectorUIExtensionController::createTabForExtension):
Standardize on returning {result: value} for showExtensionTab.

(WebKit::WebInspectorUIExtensionController::showExtensionTab):
Standardize on returning {result: value} for showExtensionTab.
Also, there's no need to inspect the result value if it's not an error.

(WebKit::WebInspectorUIExtensionController::didNavigateExtensionTab):
Add plumbing.

Tools:

Add API test coverage for -inspectorExtension:didNavigateTabWithIdentifier:newURL:

* TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm:
(TEST):
Drive-by, fix an outdated completion handler type signature.

* TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionDelegate.mm:
(-[InspectorExtensionDelegateForTesting inspectorExtension:didNavigateTabWithIdentifier:newURL:]):
(TEST):
Add a test case which exercises the new delegate method.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (286798 => 286799)


--- trunk/Source/WebCore/ChangeLog	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebCore/ChangeLog	2021-12-09 20:55:16 UTC (rev 286799)
@@ -1,3 +1,20 @@
+2021-12-08  BJ Burg  <bb...@apple.com>
+
+        [Cocoa] Web Inspector: provide a way for _WKInspectorExtension clients to be to notified when an extension tab navigates
+        https://bugs.webkit.org/show_bug.cgi?id=233935
+        <rdar://86123899>
+
+        Reviewed by Patrick Angle.
+
+        Add new InspectorFrontendHost hooks to notify the client about didNavigateExtensionTab().
+
+        * inspector/InspectorFrontendClient.h:
+        (WebCore::InspectorFrontendClient::didNavigateExtensionTab):
+        * inspector/InspectorFrontendHost.cpp:
+        (WebCore::InspectorFrontendHost::didNavigateExtensionTab):
+        * inspector/InspectorFrontendHost.h:
+        * inspector/InspectorFrontendHost.idl:
+
 2021-12-09  Said Abou-Hallawa  <s...@apple.com>
 
         [GPU Process] [Filters] Add the encoding and decoding for LightSource

Modified: trunk/Source/WebCore/inspector/InspectorFrontendClient.h (286798 => 286799)


--- trunk/Source/WebCore/inspector/InspectorFrontendClient.h	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebCore/inspector/InspectorFrontendClient.h	2021-12-09 20:55:16 UTC (rev 286799)
@@ -122,6 +122,7 @@
     virtual bool supportsWebExtensions() { return false; }
     virtual void didShowExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&) { }
     virtual void didHideExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&) { }
+    virtual void didNavigateExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&, const URL&) { }
     virtual void inspectedPageDidNavigate(const URL&) { }
 #endif
 

Modified: trunk/Source/WebCore/inspector/InspectorFrontendHost.cpp (286798 => 286799)


--- trunk/Source/WebCore/inspector/InspectorFrontendHost.cpp	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebCore/inspector/InspectorFrontendHost.cpp	2021-12-09 20:55:16 UTC (rev 286799)
@@ -707,6 +707,14 @@
     m_client->didHideExtensionTab(extensionID, extensionTabID);
 }
 
+void InspectorFrontendHost::didNavigateExtensionTab(const String& extensionID, const String& extensionTabID, const String& newURLString)
+{
+    if (!m_client)
+        return;
+    
+    m_client->didNavigateExtensionTab(extensionID, extensionTabID, { URL(), newURLString });
+}
+
 void InspectorFrontendHost::inspectedPageDidNavigate(const String& newURLString)
 {
     if (!m_client)

Modified: trunk/Source/WebCore/inspector/InspectorFrontendHost.h (286798 => 286799)


--- trunk/Source/WebCore/inspector/InspectorFrontendHost.h	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebCore/inspector/InspectorFrontendHost.h	2021-12-09 20:55:16 UTC (rev 286799)
@@ -143,6 +143,7 @@
 #if ENABLE(INSPECTOR_EXTENSIONS)
     void didShowExtensionTab(const String& extensionID, const String& extensionTabID);
     void didHideExtensionTab(const String& extensionID, const String& extensionTabID);
+    void didNavigateExtensionTab(const String& extensionID, const String& extensionTabID, const String& url);
     void inspectedPageDidNavigate(const String& url);
     ExceptionOr<JSC::JSValue> evaluateScriptInExtensionTab(HTMLIFrameElement& extensionFrame, const String& scriptSource);
 #endif

Modified: trunk/Source/WebCore/inspector/InspectorFrontendHost.idl (286798 => 286799)


--- trunk/Source/WebCore/inspector/InspectorFrontendHost.idl	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebCore/inspector/InspectorFrontendHost.idl	2021-12-09 20:55:16 UTC (rev 286799)
@@ -100,6 +100,7 @@
     readonly attribute boolean supportsWebExtensions;
     [Conditional=INSPECTOR_EXTENSIONS] undefined didShowExtensionTab(DOMString extensionID, DOMString extensionTabID);
     [Conditional=INSPECTOR_EXTENSIONS] undefined didHideExtensionTab(DOMString extensionID, DOMString extensionTabID);
+    [Conditional=INSPECTOR_EXTENSIONS] undefined didNavigateExtensionTab(DOMString extensionID, DOMString extensionTabID, DOMString newURL);
     [Conditional=INSPECTOR_EXTENSIONS] undefined inspectedPageDidNavigate(DOMString newURL);
     [Conditional=INSPECTOR_EXTENSIONS] any evaluateScriptInExtensionTab(HTMLIFrameElement extensionFrame, DOMString scriptSource);
 };

Modified: trunk/Source/WebInspectorUI/ChangeLog (286798 => 286799)


--- trunk/Source/WebInspectorUI/ChangeLog	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebInspectorUI/ChangeLog	2021-12-09 20:55:16 UTC (rev 286799)
@@ -1,3 +1,33 @@
+2021-12-08  BJ Burg  <bb...@apple.com>
+
+        [Cocoa] Web Inspector: provide a way for _WKInspectorExtension clients to be to notified when an extension tab navigates
+        https://bugs.webkit.org/show_bug.cgi?id=233935
+        <rdar://86123899>
+
+        Reviewed by Patrick Angle.
+
+        In order instrument all loads inside the extension iframe, we cannot rely on the <iframe src> attribute
+        to query the currently loaded page, or to change the current page. Use a helper method to query and set
+        the iframe location indirectly using `document.location`.
+
+        * UserInterface/Protocol/InspectorFrontendAPI.js:
+
+        * UserInterface/Controllers/WebInspectorExtensionController.js:
+        (WI.WebInspectorExtensionController.prototype.createTabForExtension):
+        (WI.WebInspectorExtensionController.prototype.showExtensionTab):
+        Standardize on returning {"result": value} from these methods.
+
+        * UserInterface/Views/WebInspectorExtensionTabContentView.js:
+        (WI.WebInspectorExtensionTabContentView):
+        (WI.WebInspectorExtensionTabContentView.prototype.whenPageAvailable): Added.
+        (WI.WebInspectorExtensionTabContentView.prototype._extensionFrameDidLoad):
+        Trigger a load of the actual requested page by evaluating `document.location.href = ""
+        in the context of the extension tab iframe. Notify clients when this non-initial load completes.
+
+        (WI.WebInspectorExtensionTabContentView.prototype.async _maybeDispatchDidNavigateExtensionTab):
+        Dispatch didNavigateExtensionTab with the new URL when the extension tab iframe completes a load.
+        Don't notify the client if the extension tab has not yet loaded.
+
 2021-12-09  Razvan Caliman  <rcali...@apple.com>
 
         Web Inspector: Enable fuzzy matching for CSS completions

Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/WebInspectorExtensionController.js (286798 => 286799)


--- trunk/Source/WebInspectorUI/UserInterface/Controllers/WebInspectorExtensionController.js	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/WebInspectorExtensionController.js	2021-12-09 20:55:16 UTC (rev 286799)
@@ -93,7 +93,7 @@
         WI.tabBrowser.addTabForContentView(tabContentView, {suppressAnimations: true});
 
         // The calling convention is to return an error string or a result object.
-        return {extensionTabID};
+        return {"result": extensionTabID};
     }
 
     evaluateScriptForExtension(extensionID, scriptSource, {frameURL, contextSecurityOrigin, useContentScriptContext} = {})
@@ -183,6 +183,10 @@
         }
 
         tabContentView.visible = true;
+
+        // Clients expect to be able to use evaluateScriptInExtensionTab() when this method
+        // returns, so wait for the extension tab to finish its loading sequence. Wrap the result.
+        return tabContentView.whenPageAvailable().then((sourceURL) => { return {"result": sourceURL}; });
     }
 
     hideExtensionTab(extensionTabID, options = {})

Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendAPI.js (286798 => 286799)


--- trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendAPI.js	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/InspectorFrontendAPI.js	2021-12-09 20:55:16 UTC (rev 286799)
@@ -210,8 +210,11 @@
         return WI.sharedApp.extensionController.unregisterExtension(extensionID);
     },
 
-    // Returns a WI.WebInspectorExtension.ErrorCode if an error occurred, otherwise an object
-    // with an 'extensionTabID' key representing the tab identifier for the newly created tab.
+    // Returns a string (WI.WebInspectorExtension.ErrorCode) if an error occurred that prevented creating a tab.
+    // Returns a Promise that is resolved if the evaluation completes and rejected if there was an internal error.
+    // When the promise is fulfilled, it will be either:
+    // - resolved with an object containing a 'result' key and value that is the tab identifier for the new tab.
+    // - rejected with an object containing an 'error' key and value that is the exception that was thrown while evaluating script.
     createTabForExtension(extensionID, tabName, tabIconURL, sourceURL)
     {
         return WI.sharedApp.extensionController.createTabForExtension(extensionID, tabName, tabIconURL, sourceURL);
@@ -233,7 +236,11 @@
         return WI.sharedApp.extensionController.reloadForExtension(extensionID, {ignoreCache, userAgent, injectedScript});
     },
 
-    // Returns a WI.WebInspectorExtension.ErrorCode if an error occurred, otherwise nothing.
+    // Returns a string (WI.WebInspectorExtension.ErrorCode) if an error occurred before attempting to switch tabs.
+    // Returns a Promise that is resolved if the tab could be shown and rejected if the tab could not be shown.
+    // When the promise is fulfilled, it will be either:
+    // - resolved with no value.
+    // - rejected with an object containing an 'error' key and value that is the exception that was thrown while showing the tab.
     showExtensionTab(extensionTabID)
     {
         return WI.sharedApp.extensionController.showExtensionTab(extensionTabID);

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/WebInspectorExtensionTabContentView.js (286798 => 286799)


--- trunk/Source/WebInspectorUI/UserInterface/Views/WebInspectorExtensionTabContentView.js	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/WebInspectorExtensionTabContentView.js	2021-12-09 20:55:16 UTC (rev 286799)
@@ -40,11 +40,11 @@
         this._tabInfo = tabInfo;
         this._sourceURL = sourceURL;
 
+        this._iframeFinishedInitialLoad = false;
+        this._whenPageAvailablePromise = new WI.WrappedPromise;
+
         this._iframeElement = this.element.appendChild(document.createElement("iframe"));
         this._iframeElement.addEventListener("load", this._extensionFrameDidLoad.bind(this));
-        this._iframeElement.src = ""
-
-        this._frameContentDidLoad = false;
     }
 
     // Static
@@ -73,6 +73,11 @@
         return true;
     }
 
+    whenPageAvailable()
+    {
+        return this._whenPageAvailablePromise.promise;
+    }
+
     attached()
     {
         super.attached();
@@ -109,13 +114,35 @@
 
     _extensionFrameDidLoad()
     {
-        this._frameContentDidLoad = true;
-        this._maybeDispatchDidShowExtensionTab();
+        // Bounce from the initial empty page to the requested sourceURL.
+        if (!this._iframeFinishedInitialLoad) {
+            this._iframeFinishedInitialLoad = true;
+            WI.sharedApp.extensionController.evaluateScriptInExtensionTab(this._extensionTabID, `document.location.replace("${this._sourceURL}");`);
+            return;
+        }
+
+        // Signal that the page is available since we already bounced to the requested page.
+        if (!this._whenPageAvailablePromise.settled)
+            this._whenPageAvailablePromise.resolve(this._sourceURL);
+
+        this._maybeDispatchDidNavigateExtensionTab();
     }
 
+    async _maybeDispatchDidNavigateExtensionTab()
+    {
+        if (!this.element.isConnected)
+            return;
+
+        let payload = await WI.sharedApp.extensionController.evaluateScriptInExtensionTab(this._extensionTabID, "document.location.href");
+        console.assert(payload.result, "Should be able to unwrap evaluation in extension tab!", payload.result);
+
+        if (InspectorFrontendHost.supportsWebExtensions)
+            InspectorFrontendHost.didNavigateExtensionTab(this._extension.extensionID, this._extensionTabID, payload.result);
+    }
+
     _maybeDispatchDidShowExtensionTab()
     {
-        if (!this._frameContentDidLoad || !this.element.isConnected)
+        if (!this.element.isConnected)
             return;
 
         if (InspectorFrontendHost.supportsWebExtensions)

Modified: trunk/Source/WebKit/ChangeLog (286798 => 286799)


--- trunk/Source/WebKit/ChangeLog	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/ChangeLog	2021-12-09 20:55:16 UTC (rev 286799)
@@ -1,3 +1,50 @@
+2021-12-08  BJ Burg  <bb...@apple.com>
+
+        [Cocoa] Web Inspector: provide a way for _WKInspectorExtension clients to be to notified when an extension tab navigates
+        https://bugs.webkit.org/show_bug.cgi?id=233935
+        <rdar://86123899>
+
+        Reviewed by Patrick Angle.
+
+        Add plumbing to notify clients when an extension tab loads. This is implemented similarly to
+        -inspectorExtension:didShowExtensionTab: and -inspectorExtension:didHideExtensionTab:.
+
+        * UIProcess/API/APIInspectorExtensionClient.h:
+        (API::InspectorExtensionClient::didNavigateExtensionTab):
+
+        * UIProcess/API/Cocoa/_WKInspectorExtensionDelegate.h:
+
+        * UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.h:
+        * UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.mm:
+        (WebKit::InspectorExtensionDelegate::InspectorExtensionDelegate):
+        (WebKit::InspectorExtensionDelegate::InspectorExtensionClient::didNavigateExtensionTab):
+
+        * UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.messages.in:
+        * UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.h:
+        * UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.cpp:
+        (WebKit::WebInspectorUIExtensionControllerProxy::didNavigateExtensionTab):
+
+        * WebProcess/Inspector/RemoteWebInspectorUI.h:
+        * WebProcess/Inspector/RemoteWebInspectorUI.cpp:
+        (WebKit::RemoteWebInspectorUI::didNavigateExtensionTab):
+
+        * WebProcess/Inspector/WebInspectorUI.h:
+        * WebProcess/Inspector/WebInspectorUI.cpp:
+        (WebKit::WebInspectorUI::didHideExtensionTab):
+        (WebKit::WebInspectorUI::didNavigateExtensionTab):
+
+        * WebProcess/Inspector/WebInspectorUIExtensionController.h:
+        * WebProcess/Inspector/WebInspectorUIExtensionController.cpp:
+        (WebKit::WebInspectorUIExtensionController::createTabForExtension):
+        Standardize on returning {result: value} for showExtensionTab.
+
+        (WebKit::WebInspectorUIExtensionController::showExtensionTab):
+        Standardize on returning {result: value} for showExtensionTab.
+        Also, there's no need to inspect the result value if it's not an error.
+
+        (WebKit::WebInspectorUIExtensionController::didNavigateExtensionTab):
+        Add plumbing.
+
 2021-12-09  Brady Eidson  <beid...@apple.com>
 
         Add ability to inject messages into webpushd

Modified: trunk/Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h (286798 => 286799)


--- trunk/Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/UIProcess/API/APIInspectorExtensionClient.h	2021-12-09 20:55:16 UTC (rev 286799)
@@ -37,6 +37,7 @@
 
     virtual void didShowExtensionTab(const Inspector::ExtensionTabID&) { }
     virtual void didHideExtensionTab(const Inspector::ExtensionTabID&) { }
+    virtual void didNavigateExtensionTab(const Inspector::ExtensionTabID&, const WTF::URL&) { }
     virtual void inspectedPageDidNavigate(const WTF::URL&) { }
 };
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKInspectorExtensionDelegate.h (286798 => 286799)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKInspectorExtensionDelegate.h	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKInspectorExtensionDelegate.h	2021-12-09 20:55:16 UTC (rev 286799)
@@ -53,7 +53,16 @@
 - (void)inspectorExtension:(_WKInspectorExtension *)extension didHideTabWithIdentifier:(NSString *)tabIdentifier;
 
 /**
+ * @abstract Called when a tab associated with this extension has navigated to a new URL.
+ * @param extension The extension that created the tab.
+ * @param tabIdentifier Identifier for the tab that navigated.
+ * @param URL The new URL for the extension tab's page.
+ */
+- (void)inspectorExtension:(_WKInspectorExtension *)extension didNavigateTabWithIdentifier:(NSString *)tabIdentifier newURL:(NSURL *)newURL;
+
+/**
  * @abstract Called when the inspected page has navigated to a new URL.
+ * @param extension The extension that is being notified.
  * @param url The new URL for the inspected page.
  */
 - (void)inspectorExtension:(_WKInspectorExtension *)extension inspectedPageDidNavigate:(NSURL *)url;

Modified: trunk/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.h (286798 => 286799)


--- trunk/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.h	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.h	2021-12-09 20:55:16 UTC (rev 286799)
@@ -56,6 +56,7 @@
         // API::InspectorExtensionClient
         void didShowExtensionTab(const Inspector::ExtensionTabID&) override;
         void didHideExtensionTab(const Inspector::ExtensionTabID&) override;
+        void didNavigateExtensionTab(const Inspector::ExtensionTabID&, const URL&) override;
         void inspectedPageDidNavigate(const URL&) override;
 
         InspectorExtensionDelegate& m_inspectorExtensionDelegate;
@@ -67,6 +68,7 @@
     struct {
         bool inspectorExtensionDidShowTabWithIdentifier : 1;
         bool inspectorExtensionDidHideTabWithIdentifier : 1;
+        bool inspectorExtensionDidNavigateTabWithIdentifier : 1;
         bool inspectorExtensionInspectedPageDidNavigate : 1;
     } m_delegateMethods;
 };

Modified: trunk/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.mm (286798 => 286799)


--- trunk/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.mm	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/UIProcess/Inspector/Cocoa/InspectorExtensionDelegate.mm	2021-12-09 20:55:16 UTC (rev 286799)
@@ -41,6 +41,7 @@
 {
     m_delegateMethods.inspectorExtensionDidShowTabWithIdentifier = [delegate respondsToSelector:@selector(inspectorExtension:didShowTabWithIdentifier:)];
     m_delegateMethods.inspectorExtensionDidHideTabWithIdentifier = [delegate respondsToSelector:@selector(inspectorExtension:didHideTabWithIdentifier:)];
+    m_delegateMethods.inspectorExtensionDidNavigateTabWithIdentifier = [delegate respondsToSelector:@selector(inspectorExtension:didNavigateTabWithIdentifier:newURL:)];
     m_delegateMethods.inspectorExtensionInspectedPageDidNavigate = [delegate respondsToSelector:@selector(inspectorExtension:inspectedPageDidNavigate:)];
 
     inspectorExtension->_extension->setClient(makeUniqueRef<InspectorExtensionClient>(*this));
@@ -86,6 +87,18 @@
     [delegate inspectorExtension:m_inspectorExtensionDelegate.m_inspectorExtension.get().get() didHideTabWithIdentifier:extensionTabID];
 }
 
+void InspectorExtensionDelegate::InspectorExtensionClient::didNavigateExtensionTab(const Inspector::ExtensionTabID& extensionTabID, const WTF::URL& newURL)
+{
+    if (!m_inspectorExtensionDelegate.m_delegateMethods.inspectorExtensionDidNavigateTabWithIdentifier)
+        return;
+
+    auto& delegate = m_inspectorExtensionDelegate.m_delegate;
+    if (!delegate)
+        return;
+
+    [delegate inspectorExtension:m_inspectorExtensionDelegate.m_inspectorExtension.get().get() didNavigateTabWithIdentifier:extensionTabID newURL:newURL];
+}
+
 void InspectorExtensionDelegate::InspectorExtensionClient::inspectedPageDidNavigate(const WTF::URL& newURL)
 {
     if (!m_inspectorExtensionDelegate.m_delegateMethods.inspectorExtensionInspectedPageDidNavigate)

Modified: trunk/Source/WebKit/UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.cpp (286798 => 286799)


--- trunk/Source/WebKit/UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.cpp	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.cpp	2021-12-09 20:55:16 UTC (rev 286799)
@@ -268,6 +268,20 @@
     extensionClient->didHideExtensionTab(extensionTabID);
 }
 
+void WebInspectorUIExtensionControllerProxy::didNavigateExtensionTab(const Inspector::ExtensionID& extensionID, const Inspector::ExtensionTabID& extensionTabID, const WTF::URL& newURL)
+{
+    auto it = m_extensionAPIObjectMap.find(extensionID);
+    if (it == m_extensionAPIObjectMap.end())
+        return;
+
+    RefPtr<API::InspectorExtension> extension = it->value;
+    auto extensionClient = extension->client();
+    if (!extensionClient)
+        return;
+
+    extensionClient->didNavigateExtensionTab(extensionTabID, newURL);
+}
+
 void WebInspectorUIExtensionControllerProxy::inspectedPageDidNavigate(const URL& newURL)
 {
     for (auto& extension : copyToVector(m_extensionAPIObjectMap.values())) {

Modified: trunk/Source/WebKit/UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.h (286798 => 286799)


--- trunk/Source/WebKit/UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.h	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.h	2021-12-09 20:55:16 UTC (rev 286799)
@@ -68,6 +68,7 @@
     // WebInspectorUIExtensionControllerProxy IPC messages.
     void didShowExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&);
     void didHideExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&);
+    void didNavigateExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&, const URL&);
     void inspectedPageDidNavigate(const URL&);
 
     // Notifications.

Modified: trunk/Source/WebKit/UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.messages.in (286798 => 286799)


--- trunk/Source/WebKit/UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.messages.in	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/UIProcess/Inspector/WebInspectorUIExtensionControllerProxy.messages.in	2021-12-09 20:55:16 UTC (rev 286799)
@@ -25,6 +25,7 @@
 messages -> WebInspectorUIExtensionControllerProxy {
     DidShowExtensionTab(String extensionID, String extensionTabID)
     DidHideExtensionTab(String extensionID, String extensionTabID)
+    DidNavigateExtensionTab(String extensionID, String extensionTabID, URL newURL)
     InspectedPageDidNavigate(URL newURL)
 }
 

Modified: trunk/Source/WebKit/WebProcess/Inspector/RemoteWebInspectorUI.cpp (286798 => 286799)


--- trunk/Source/WebKit/WebProcess/Inspector/RemoteWebInspectorUI.cpp	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/WebProcess/Inspector/RemoteWebInspectorUI.cpp	2021-12-09 20:55:16 UTC (rev 286799)
@@ -306,6 +306,14 @@
     m_extensionController->didHideExtensionTab(extensionID, extensionTabID);
 }
 
+void RemoteWebInspectorUI::didNavigateExtensionTab(const Inspector::ExtensionID& extensionID, const Inspector::ExtensionTabID& extensionTabID, const URL& newURL)
+{
+    if (!m_extensionController)
+        return;
+
+    m_extensionController->didNavigateExtensionTab(extensionID, extensionTabID, newURL);
+}
+
 void RemoteWebInspectorUI::inspectedPageDidNavigate(const URL& newURL)
 {
     if (!m_extensionController)

Modified: trunk/Source/WebKit/WebProcess/Inspector/RemoteWebInspectorUI.h (286798 => 286799)


--- trunk/Source/WebKit/WebProcess/Inspector/RemoteWebInspectorUI.h	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/WebProcess/Inspector/RemoteWebInspectorUI.h	2021-12-09 20:55:16 UTC (rev 286799)
@@ -122,6 +122,7 @@
     bool supportsWebExtensions() override;
     void didShowExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&) override;
     void didHideExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&) override;
+    void didNavigateExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&, const URL&) override;
     void inspectedPageDidNavigate(const URL&) override;
 #endif
 

Modified: trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUI.cpp (286798 => 286799)


--- trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUI.cpp	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUI.cpp	2021-12-09 20:55:16 UTC (rev 286799)
@@ -380,6 +380,14 @@
     m_extensionController->didHideExtensionTab(extensionID, extensionTabID);
 }
 
+void WebInspectorUI::didNavigateExtensionTab(const String& extensionID, const String& extensionTabID, const URL& newURL)
+{
+    if (!m_extensionController)
+        return;
+
+    m_extensionController->didNavigateExtensionTab(extensionID, extensionTabID, newURL);
+}
+
 void WebInspectorUI::inspectedPageDidNavigate(const URL& newURL)
 {
     if (!m_extensionController)

Modified: trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUI.h (286798 => 286799)


--- trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUI.h	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUI.h	2021-12-09 20:55:16 UTC (rev 286799)
@@ -156,6 +156,7 @@
     bool supportsWebExtensions() override;
     void didShowExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&) override;
     void didHideExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&) override;
+    void didNavigateExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&, const URL&) override;
     void inspectedPageDidNavigate(const URL&) override;
 #endif
 

Modified: trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUIExtensionController.cpp (286798 => 286799)


--- trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUIExtensionController.cpp	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUIExtensionController.cpp	2021-12-09 20:55:16 UTC (rev 286799)
@@ -204,7 +204,7 @@
         }
 
         auto* frontendGlobalObject = weakThis->m_frontendClient->frontendAPIDispatcher().frontendGlobalObject();
-        JSC::JSValue foundProperty = objectResult->get(frontendGlobalObject, JSC::Identifier::fromString(frontendGlobalObject->vm(), "extensionTabID"_s));
+        JSC::JSValue foundProperty = objectResult->get(frontendGlobalObject, JSC::Identifier::fromString(frontendGlobalObject->vm(), "result"_s));
         if (!foundProperty || !foundProperty.isString()) {
             completionHandler(makeUnexpected(Inspector::ExtensionError::InternalError));
             return;
@@ -357,11 +357,19 @@
         }
 
         if (auto parsedError = weakThis->parseExtensionErrorFromEvaluationResult(result)) {
-            LOG(Inspector, "Internal error encountered while evaluating upon the frontend: %s", Inspector::extensionErrorToString(*parsedError).utf8().data());
+            if (!result.value().has_value()) {
+                auto exceptionDetails = result.value().error();
+                LOG(Inspector, "Internal error encountered while showing extension tab at %s:%d:%d: %s", exceptionDetails.sourceURL.utf8().data(), exceptionDetails.lineNumber, exceptionDetails.columnNumber, exceptionDetails.message.utf8().data());
+            } else
+                LOG(Inspector, "Internal error encountered while showing extension tab.");
+
             completionHandler(makeUnexpected(*parsedError));
             return;
         }
 
+        // If this assertion fails, then a `result.error()` was not handled above as expected.
+        ASSERT(result.has_value());
+
         completionHandler({ });
     });
 }
@@ -444,6 +452,11 @@
     WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorUIExtensionControllerProxy::DidHideExtensionTab { extensionID, extensionTabID }, m_inspectorPageIdentifier);
 }
 
+void WebInspectorUIExtensionController::didNavigateExtensionTab(const Inspector::ExtensionID& extensionID, const Inspector::ExtensionTabID& extensionTabID, const URL& newURL)
+{
+    WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorUIExtensionControllerProxy::DidNavigateExtensionTab { extensionID, extensionTabID, newURL }, m_inspectorPageIdentifier);
+}
+
 void WebInspectorUIExtensionController::inspectedPageDidNavigate(const URL& newURL)
 {
     WebProcess::singleton().parentProcessConnection()->send(Messages::WebInspectorUIExtensionControllerProxy::InspectedPageDidNavigate { newURL }, m_inspectorPageIdentifier);

Modified: trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUIExtensionController.h (286798 => 286799)


--- trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUIExtensionController.h	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Source/WebKit/WebProcess/Inspector/WebInspectorUIExtensionController.h	2021-12-09 20:55:16 UTC (rev 286799)
@@ -76,6 +76,7 @@
     // Callbacks from the frontend.
     void didShowExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&);
     void didHideExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&);
+    void didNavigateExtensionTab(const Inspector::ExtensionID&, const Inspector::ExtensionTabID&, const URL&);
     void inspectedPageDidNavigate(const URL&);
 
 private:

Modified: trunk/Tools/ChangeLog (286798 => 286799)


--- trunk/Tools/ChangeLog	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Tools/ChangeLog	2021-12-09 20:55:16 UTC (rev 286799)
@@ -1,3 +1,22 @@
+2021-12-08  BJ Burg  <bb...@apple.com>
+
+        [Cocoa] Web Inspector: provide a way for _WKInspectorExtension clients to be to notified when an extension tab navigates
+        https://bugs.webkit.org/show_bug.cgi?id=233935
+        <rdar://86123899>
+
+        Reviewed by Patrick Angle.
+
+        Add API test coverage for -inspectorExtension:didNavigateTabWithIdentifier:newURL:
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm:
+        (TEST):
+        Drive-by, fix an outdated completion handler type signature.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionDelegate.mm:
+        (-[InspectorExtensionDelegateForTesting inspectorExtension:didNavigateTabWithIdentifier:newURL:]):
+        (TEST):
+        Add a test case which exercises the new delegate method.
+
 2021-12-09  Lauro Moura  <lmo...@igalia.com>
 
         [WebXR][WPE] Build fails without openxr installed

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionDelegate.mm (286798 => 286799)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionDelegate.mm	2021-12-09 20:35:32 UTC (rev 286798)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionDelegate.mm	2021-12-09 20:55:16 UTC (rev 286799)
@@ -43,6 +43,7 @@
 #import <wtf/RetainPtr.h>
 
 static RetainPtr<NSURL> sharedNewURLAfterNavigation;
+static bool extensionTabDidNavigateWasCalled;
 
 @interface UIDelegateForTestingInspectorExtensionDelegate : NSObject <WKUIDelegate>
 @end
@@ -84,6 +85,11 @@
     didHideExtensionTabWasCalled = true;
 }
 
+- (void)inspectorExtension:(_WKInspectorExtension *)extension didNavigateTabWithIdentifier:(NSString *)tabIdentifier newURL:(NSURL *)newURL
+{
+    extensionTabDidNavigateWasCalled = true;
+}
+
 - (void)inspectorExtension:(_WKInspectorExtension *)extension inspectedPageDidNavigate:(NSURL *)newURL
 {
     inspectedPageDidNavigateWasCalled = true;
@@ -234,4 +240,98 @@
     TestWebKitAPI::Util::run(&pendingCallbackWasCalled);
 }
 
+// FIXME: Re-enable this test for debug once webkit.org/b/231847 is fixed.
+#if !defined(NDEBUG)
+TEST(WKInspectorExtensionDelegate, DISABLED_ExtensionTabNavigatedCallbacks)
+#else
+TEST(WKInspectorExtensionDelegate, ExtensionTabNavigatedCallbacks)
+#endif
+{
+    resetGlobalState();
+
+    // Hook up the test-resource: handler so that we can navigate to a different test file.
+    if (!sharedURLSchemeHandler)
+        sharedURLSchemeHandler = adoptNS([[TestInspectorURLSchemeHandler alloc] init]);
+
+    auto webViewConfiguration = adoptNS([WKWebViewConfiguration new]);
+    webViewConfiguration.get().preferences._developerExtrasEnabled = YES;
+    [webViewConfiguration setURLSchemeHandler:sharedURLSchemeHandler.get() forURLScheme:@"test-resource"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto uiDelegate = adoptNS([UIDelegateForTestingInspectorExtensionDelegate new]);
+
+    [webView setUIDelegate:uiDelegate.get()];
+
+    [[webView _inspector] show];
+    TestWebKitAPI::Util::run(&didAttachLocalInspectorCalled);
+
+    // Register the test extension.
+    auto extensionID = [NSUUID UUID].UUIDString;
+    auto extensionBundleIdentifier = @"com.apple.webkit.ThirdExtension";
+    auto extensionDisplayName = @"ThirdExtension";
+    pendingCallbackWasCalled = false;
+    [[webView _inspector] registerExtensionWithID:extensionID extensionBundleIdentifier:extensionBundleIdentifier displayName:extensionDisplayName completionHandler:^(NSError *error, _WKInspectorExtension *extension) {
+        EXPECT_NULL(error);
+        EXPECT_NOT_NULL(extension);
+        sharedInspectorExtension = extension;
+
+        pendingCallbackWasCalled = true;
+    }];
+    TestWebKitAPI::Util::run(&pendingCallbackWasCalled);
+
+    auto extensionDelegate = adoptNS([InspectorExtensionDelegateForTesting new]);
+    [sharedInspectorExtension setDelegate:extensionDelegate.get()];
+
+    auto baseURL = [NSURL URLWithString:@"http://example.com/"];
+    [webView loadHTMLString:@"<head><title>Test page to be inspected</title></head><body><p>Filler content</p></body>" baseURL:baseURL];
+    [webView _test_waitForDidFinishNavigation];
+
+    inspectedPageDidNavigateWasCalled = false;
+    TestWebKitAPI::Util::run(&inspectedPageDidNavigateWasCalled);
+    EXPECT_NS_EQUAL(sharedNewURLAfterNavigation.get().absoluteString, baseURL.absoluteString);
+    inspectedPageDidNavigateWasCalled = false;
+
+    // Create an extension tab.
+    auto iconURL = [NSURL URLWithString:@"test-resource://ThirdExtension/InspectorExtension-TabIcon-30x30.png"];
+    auto sourceURL = [NSURL URLWithString:@"test-resource://ThirdExtension/InspectorExtension-basic-tab.html"];
+
+    pendingCallbackWasCalled = false;
+    [sharedInspectorExtension createTabWithName:@"ThirdExtension-Tab" tabIconURL:iconURL sourceURL:sourceURL completionHandler:^(NSError *error, NSString *extensionTabIdentifier) {
+        EXPECT_NULL(error);
+        EXPECT_NOT_NULL(extensionTabIdentifier);
+        sharedExtensionTabIdentifier = extensionTabIdentifier;
+
+        pendingCallbackWasCalled = true;
+    }];
+    TestWebKitAPI::Util::run(&pendingCallbackWasCalled);
+
+    pendingCallbackWasCalled = false;
+    [[webView _inspector] showExtensionTabWithIdentifier:sharedExtensionTabIdentifier.get() completionHandler:^(NSError *error) {
+        EXPECT_NULL(error);
+
+        pendingCallbackWasCalled = true;
+    }];
+    TestWebKitAPI::Util::run(&pendingCallbackWasCalled);
+
+    pendingCallbackWasCalled = false;
+    extensionTabDidNavigateWasCalled = false;
+    auto newURL = [NSURL URLWithString:@"test-resource://ThirdExtension/InspectorExtension-basic-page.html"];
+    [sharedInspectorExtension evaluateScript:[NSString stringWithFormat:@"window.location.replace(\"%@\")", newURL] inTabWithIdentifier:sharedExtensionTabIdentifier.get() completionHandler:^(NSError *error, id result) {
+        EXPECT_NULL(error);
+
+        pendingCallbackWasCalled = true;
+    }];
+    TestWebKitAPI::Util::run(&pendingCallbackWasCalled);
+    TestWebKitAPI::Util::run(&extensionTabDidNavigateWasCalled);
+
+    // Unregister the test extension.
+    pendingCallbackWasCalled = false;
+    [[webView _inspector] unregisterExtension:sharedInspectorExtension.get() completionHandler:^(NSError * _Nullable error) {
+        EXPECT_NULL(error);
+
+        pendingCallbackWasCalled = true;
+    }];
+    TestWebKitAPI::Util::run(&pendingCallbackWasCalled);
+}
+
 #endif // ENABLE(INSPECTOR_EXTENSIONS)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to