<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[287979] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/287979">287979</a></dd>
<dt>Author</dt> <dd>pangle@apple.com</dd>
<dt>Date</dt> <dd>2022-01-13 08:22:10 -0800 (Thu, 13 Jan 2022)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: Implement `frameURL` option for `devtools.inspectedWindow.eval` command
https://bugs.webkit.org/show_bug.cgi?id=222568

Reviewed by Devin Rousso.

Source/WebInspectorUI:

New test: Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm

Add support for evaluating script from an extension in a specific frame on the page by referring to it by the
frame's URL. Frame URLs are matched in three steps, first looking for an exact URL match, including query
parameters and fragment identifier. If no match is found and the provided `options.frameURL` does not have any
fragment identifier or query parameters, a check is then made against each known frame again, this time
excluding their fragment identifier. If that check still fails to find a frame for the URL, we perform one more
pass, this time excluding the fragment identifier and query parameters for each known frame.

* UserInterface/Controllers/WebInspectorExtensionController.js:
(WI.WebInspectorExtensionController.prototype.evaluateScriptForExtension):
(WI.WebInspectorExtensionController.prototype.reloadForExtension):
- Drive-by removal of trailing spaces.
(WI.WebInspectorExtensionController.prototype._frameForFrameURL):

Source/WebKit:

New test: Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm

Correct the API to indicate that `frameURL` and `contextSecurityOrigin` are nullable parameters.

* UIProcess/API/Cocoa/_WKInspectorExtension.h:

Tools:

Add test coverage for evaluating script on an inspected page from an extension, including evaluating on an inner
frame.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm:
(TEST):
* TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionEvaluateScriptOnPage.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersWebInspectorExtensionControllerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/WebInspectorExtensionController.js</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitUIProcessAPICocoa_WKInspectorExtensionh">trunk/Source/WebKit/UIProcess/API/Cocoa/_WKInspectorExtension.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKitCocoaWKInspectorExtensionmm">trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkToolsTestWebKitAPITestsWebKitCocoaWKInspectorExtensionEvaluateScriptOnPagehtml">trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionEvaluateScriptOnPage.html</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKitCocoaWKInspectorExtensionEvaluateScriptOnPageInnerFramehtml">trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (287978 => 287979)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog    2022-01-13 15:22:22 UTC (rev 287978)
+++ trunk/Source/WebInspectorUI/ChangeLog       2022-01-13 16:22:10 UTC (rev 287979)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2022-01-13  Patrick Angle  <pangle@apple.com>
+
+        Web Inspector: Implement `frameURL` option for `devtools.inspectedWindow.eval` command
+        https://bugs.webkit.org/show_bug.cgi?id=222568
+
+        Reviewed by Devin Rousso.
+
+        New test: Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm
+
+        Add support for evaluating script from an extension in a specific frame on the page by referring to it by the
+        frame's URL. Frame URLs are matched in three steps, first looking for an exact URL match, including query
+        parameters and fragment identifier. If no match is found and the provided `options.frameURL` does not have any
+        fragment identifier or query parameters, a check is then made against each known frame again, this time
+        excluding their fragment identifier. If that check still fails to find a frame for the URL, we perform one more
+        pass, this time excluding the fragment identifier and query parameters for each known frame.
+
+        * UserInterface/Controllers/WebInspectorExtensionController.js:
+        (WI.WebInspectorExtensionController.prototype.evaluateScriptForExtension):
+        (WI.WebInspectorExtensionController.prototype.reloadForExtension):
+        - Drive-by removal of trailing spaces.
+        (WI.WebInspectorExtensionController.prototype._frameForFrameURL):
+
</ins><span class="cx"> 2022-01-12  Elliott Williams  <emw@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [Xcode] Configure each project for the legacy build system
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersWebInspectorExtensionControllerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/WebInspectorExtensionController.js (287978 => 287979)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/WebInspectorExtensionController.js 2022-01-13 15:22:22 UTC (rev 287978)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/WebInspectorExtensionController.js    2022-01-13 16:22:10 UTC (rev 287979)
</span><span class="lines">@@ -133,10 +133,10 @@
</span><span class="cx">             return WI.WebInspectorExtension.ErrorCode.InvalidRequest;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        // FIXME: <rdar://problem/74180355> implement execution context selection options
-        if (frameURL) {
-            WI.reportInternalError("evaluateScriptForExtension: the 'frameURL' option is not yet implemented.");
-            return WI.WebInspectorExtension.ErrorCode.NotImplemented;
</del><ins>+        let frame = this._frameForFrameURL(frameURL);
+        if (!frame) {
+            WI.reportInternalError("evaluateScriptForExtension: No frame matched provided frameURL: " + frameURL);
+            return WI.WebInspectorExtension.ErrorCode.InvalidRequest;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (contextSecurityOrigin) {
</span><span class="lines">@@ -149,7 +149,12 @@
</span><span class="cx">             return WI.WebInspectorExtension.ErrorCode.NotImplemented;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        let evaluationContext = WI.runtimeManager.activeExecutionContext;
</del><ins>+        let evaluationContext = frame.pageExecutionContext;
+        if (!evaluationContext) {
+            WI.reportInternalError("evaluateScriptForExtension: No 'pageExecutionContext' was present for frame with URL: " + frame.url);
+            return WI.WebInspectorExtension.ErrorCode.ContextDestroyed;
+        }
+
</ins><span class="cx">         return evaluationContext.target.RuntimeAgent.evaluate.invoke({
</span><span class="cx">             expression: scriptSource,
</span><span class="cx">             objectGroup: "extension-evaluation",
</span><span class="lines">@@ -165,7 +170,7 @@
</span><span class="cx">             return wasThrown ? {"error": resultOrError.description} : {"result": value};
</span><span class="cx">         }).catch((error) => error.description);
</span><span class="cx">     }
</span><del>-    
</del><ins>+
</ins><span class="cx">     reloadForExtension(extensionID, {ignoreCache, userAgent, injectedScript} = {})
</span><span class="cx">     {
</span><span class="cx">         let extension = this._extensionForExtensionIDMap.get(extensionID);
</span><span class="lines">@@ -184,14 +189,14 @@
</span><span class="cx">             WI.reportInternalError("reloadForExtension: the 'injectedScript' option is not yet implemented.");
</span><span class="cx">             return WI.WebInspectorExtension.ErrorCode.NotImplemented;
</span><span class="cx">         }
</span><del>-        
</del><ins>+
</ins><span class="cx">         let target = WI.assumingMainTarget();
</span><span class="cx">         if (!target.hasCommand("Page.reload"))
</span><span class="cx">             return WI.WebInspectorExtension.ErrorCode.InvalidRequest;
</span><del>-        
</del><ins>+
</ins><span class="cx">         return target.PageAgent.reload.invoke({ignoreCache});
</span><span class="cx">     }
</span><del>-    
</del><ins>+
</ins><span class="cx">     showExtensionTab(extensionTabID, options = {})
</span><span class="cx">     {
</span><span class="cx">         let tabContentView = this._extensionTabContentViewForExtensionTabIDMap.get(extensionTabID);
</span><span class="lines">@@ -393,6 +398,42 @@
</span><span class="cx">         return {anchorTabType, anchorTabIndex, distanceFromAnchorTab};
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    _frameForFrameURL(frameURL)
+    {
+        if (!frameURL)
+            return WI.networkManager.mainFrame;
+
+        function findFrame(frameURL, adjustKnownFrameURL) {
+            return WI.networkManager.frames.find((knownFrame) => {
+                let knownFrameURL = new URL(knownFrame.url);
+                adjustKnownFrameURL?.(knownFrameURL);
+                return knownFrameURL.toString() === frameURL;
+            });
+        }
+
+        let frame = findFrame(frameURL);
+        if (frame)
+            return frame;
+
+        let frameURLParts = new URL(frameURL);
+        if (frameURLParts.hash.length)
+            return null;
+
+        frame = findFrame(frameURL, (knownFrameURL) => {
+            knownFrameURL.hash = "";
+        });
+        if (frame)
+            return frame;
+
+        if (frameURLParts.search.length)
+            return null;
+
+        return findFrame(frameURL, (knownFrameURL) => {
+            knownFrameURL.hash = "";
+            knownFrameURL.search = "";
+        });
+    }
+
</ins><span class="cx">     _handleMainResourceDidChange(event)
</span><span class="cx">     {
</span><span class="cx">         if (!event.target.isMainFrame())
</span></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (287978 => 287979)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2022-01-13 15:22:22 UTC (rev 287978)
+++ trunk/Source/WebKit/ChangeLog       2022-01-13 16:22:10 UTC (rev 287979)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2022-01-13  Patrick Angle  <pangle@apple.com>
+
+        Web Inspector: Implement `frameURL` option for `devtools.inspectedWindow.eval` command
+        https://bugs.webkit.org/show_bug.cgi?id=222568
+
+        Reviewed by Devin Rousso.
+
+        New test: Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm
+
+        Correct the API to indicate that `frameURL` and `contextSecurityOrigin` are nullable parameters.
+
+        * UIProcess/API/Cocoa/_WKInspectorExtension.h:
+
</ins><span class="cx"> 2022-01-12  John Wilander  <wilander@apple.com>
</span><span class="cx"> 
</span><span class="cx">         PCM: Same-site triggering events should support ephemeral measurement
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessAPICocoa_WKInspectorExtensionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKInspectorExtension.h (287978 => 287979)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKInspectorExtension.h  2022-01-13 15:22:22 UTC (rev 287978)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKInspectorExtension.h     2022-01-13 16:22:10 UTC (rev 287979)
</span><span class="lines">@@ -63,7 +63,7 @@
</span><span class="cx">  * scriptSource is treated as a top-level evaluation. By default, the script is evaluated in the inspected page's script context.
</span><span class="cx">  * The inspected page ultimately controls its execution context and the result of this evaluation. Thus, the result shall be treated as untrusted input.
</span><span class="cx">  */
</span><del>-- (void)evaluateScript:(NSString *)scriptSource frameURL:(NSURL *)frameURL contextSecurityOrigin:(NSURL *)contextSecurityOrigin useContentScriptContext:(BOOL)useContentScriptContext completionHandler:(void(^)(NSError * _Nullable, id result))completionHandler;
</del><ins>+- (void)evaluateScript:(NSString *)scriptSource frameURL:(NSURL * _Nullable)frameURL contextSecurityOrigin:(NSURL * _Nullable)contextSecurityOrigin useContentScriptContext:(BOOL)useContentScriptContext completionHandler:(void(^)(NSError * _Nullable, id result))completionHandler;
</ins><span class="cx"> 
</span><span class="cx"> /**
</span><span class="cx">  * @abstract Evaluates JavaScript in the context of a Web Inspector tab created by this _WKInspectorExtension.
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (287978 => 287979)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog    2022-01-13 15:22:22 UTC (rev 287978)
+++ trunk/Tools/ChangeLog       2022-01-13 16:22:10 UTC (rev 287979)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2022-01-13  Patrick Angle  <pangle@apple.com>
+
+        Web Inspector: Implement `frameURL` option for `devtools.inspectedWindow.eval` command
+        https://bugs.webkit.org/show_bug.cgi?id=222568
+
+        Reviewed by Devin Rousso.
+
+        Add test coverage for evaluating script on an inspected page from an extension, including evaluating on an inner
+        frame.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm:
+        (TEST):
+        * TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionEvaluateScriptOnPage.html: Added.
+        * TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html: Added.
+
</ins><span class="cx"> 2022-01-12  Jonathan Bedard  <jbedard@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [EWS] Load contributors from stand-alone class
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (287978 => 287979)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2022-01-13 15:22:22 UTC (rev 287978)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj   2022-01-13 16:22:10 UTC (rev 287979)
</span><span class="lines">@@ -169,6 +169,8 @@
</span><span class="cx">          2EB29D5E1F762DB90023A5F1 /* dump-datatransfer-types.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2EB29D5D1F762DA50023A5F1 /* dump-datatransfer-types.html */; };
</span><span class="cx">          2EBD9D0A2134730D002DA758 /* video.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 07CD32F72065B72A0064A4BE /* video.html */; };
</span><span class="cx">          2EC7034A26AF5E88002B2D37 /* KeyboardEventTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2EC7034926AF5E88002B2D37 /* KeyboardEventTests.mm */; };
</span><ins>+               2ED88823277125AB00DB7E99 /* WKInspectorExtensionEvaluateScriptOnPage.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2ED8882127711F1200DB7E99 /* WKInspectorExtensionEvaluateScriptOnPage.html */; };
+               2ED88824277125AB00DB7E99 /* WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2ED888222771203A00DB7E99 /* WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html */; };
</ins><span class="cx">           2EFF06C31D88621E0004BB30 /* large-video-offscreen.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2EFF06C21D8862120004BB30 /* large-video-offscreen.html */; };
</span><span class="cx">          2EFF06C51D8867760004BB30 /* change-video-source-on-click.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2EFF06C41D8867700004BB30 /* change-video-source-on-click.html */; };
</span><span class="cx">          2EFF06C71D886A580004BB30 /* change-video-source-on-end.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2EFF06C61D886A560004BB30 /* change-video-source-on-end.html */; };
</span><span class="lines">@@ -1634,6 +1636,8 @@
</span><span class="cx">                          CE14F1A4181873B0001C2705 /* WillPerformClientRedirectToURLCrash.html in Copy Resources */,
</span><span class="cx">                          468F2F942368DAF100F4B864 /* window-open-then-document-open.html in Copy Resources */,
</span><span class="cx">                          A5E2027515B21F6E00C13E14 /* WindowlessWebViewWithMedia.html in Copy Resources */,
</span><ins>+                               2ED88823277125AB00DB7E99 /* WKInspectorExtensionEvaluateScriptOnPage.html in Copy Resources */,
+                               2ED88824277125AB00DB7E99 /* WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html in Copy Resources */,
</ins><span class="cx">                   );
</span><span class="cx">                  name = "Copy Resources";
</span><span class="cx">                  runOnlyForDeploymentPostprocessing = 0;
</span><span class="lines">@@ -1857,6 +1861,8 @@
</span><span class="cx">          2EB29D5D1F762DA50023A5F1 /* dump-datatransfer-types.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "dump-datatransfer-types.html"; sourceTree = "<group>"; };
</span><span class="cx">          2EC7034926AF5E88002B2D37 /* KeyboardEventTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyboardEventTests.mm; sourceTree = "<group>"; };
</span><span class="cx">          2ECFF5541D9B12F800B55394 /* NowPlayingControlsTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NowPlayingControlsTests.mm; sourceTree = "<group>"; };
</span><ins>+               2ED8882127711F1200DB7E99 /* WKInspectorExtensionEvaluateScriptOnPage.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = WKInspectorExtensionEvaluateScriptOnPage.html; sourceTree = "<group>"; };
+               2ED888222771203A00DB7E99 /* WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html; sourceTree = "<group>"; };
</ins><span class="cx">           2EFF06C21D8862120004BB30 /* large-video-offscreen.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-offscreen.html"; sourceTree = "<group>"; };
</span><span class="cx">          2EFF06C41D8867700004BB30 /* change-video-source-on-click.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "change-video-source-on-click.html"; sourceTree = "<group>"; };
</span><span class="cx">          2EFF06C61D886A560004BB30 /* change-video-source-on-end.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "change-video-source-on-end.html"; sourceTree = "<group>"; };
</span><span class="lines">@@ -4252,6 +4258,8 @@
</span><span class="cx">                          51714EB31CF8C761004723C4 /* WebProcessKillIDBCleanup-2.html */,
</span><span class="cx">                          5120C83B1E674E350025B250 /* WebsiteDataStoreCustomPaths.html */,
</span><span class="cx">                          2E131C171D83A97E001BA36C /* wide-autoplaying-video-with-audio.html */,
</span><ins>+                               2ED8882127711F1200DB7E99 /* WKInspectorExtensionEvaluateScriptOnPage.html */,
+                               2ED888222771203A00DB7E99 /* WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html */,
</ins><span class="cx">                   );
</span><span class="cx">                  name = Resources;
</span><span class="cx">                  sourceTree = "<group>";
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKitCocoaWKInspectorExtensionmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm (287978 => 287979)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm      2022-01-13 15:22:22 UTC (rev 287978)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtension.mm 2022-01-13 16:22:10 UTC (rev 287979)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #import "DeprecatedGlobalValues.h"
</span><span class="cx"> #import "TestCocoa.h"
</span><span class="cx"> #import "TestInspectorURLSchemeHandler.h"
</span><ins>+#import "TestNavigationDelegate.h"
</ins><span class="cx"> #import "Utilities.h"
</span><span class="cx"> #import <WebKit/WKPreferencesPrivate.h>
</span><span class="cx"> #import <WebKit/WKWebViewPrivate.h>
</span><span class="lines">@@ -382,4 +383,127 @@
</span><span class="cx">     TestWebKitAPI::Util::run(&pendingCallbackWasCalled);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+TEST(WKInspectorExtension, EvaluateScriptOnPage)
+{
+    resetGlobalState();
+
+    auto webViewConfiguration = adoptNS([WKWebViewConfiguration new]);
+    webViewConfiguration.get().preferences._developerExtrasEnabled = YES;
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto uiDelegate = adoptNS([UIDelegateForTestingInspectorExtension new]);
+    auto navigationDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
+
+    auto *testPageFileURL = [NSBundle.mainBundle URLForResource:@"WKInspectorExtensionEvaluateScriptOnPage" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+
+    [webView setUIDelegate:uiDelegate.get()];
+    [webView setNavigationDelegate:navigationDelegate.get()];
+    [webView loadFileURL:testPageFileURL allowingReadAccessToURL:testPageFileURL.URLByDeletingLastPathComponent];
+    [navigationDelegate waitForDidFinishNavigation];
+
+    [[webView _inspector] show];
+    TestWebKitAPI::Util::run(&didAttachLocalInspectorCalled);
+
+    auto extensionID = [NSUUID UUID].UUIDString;
+    auto extensionBundleIdentifier = @"org.webkit.TestWebKitAPI.FourthExtension";
+    auto extensionDisplayName = @"FourthExtension";
+
+    // Register the test extension.
+    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([InspectorExtensionDelegateForTestingInspectorExtension new]);
+    [sharedInspectorExtension setDelegate:extensionDelegate.get()];
+
+    // Create and show an extension tab.
+    auto iconURL = [NSURL URLWithString:@"test-resource://FourthExtension/InspectorExtension-TabIcon-30x30.png"];
+    auto sourceURL = [NSURL URLWithString:@"test-resource://FourthExtension/InspectorExtension-basic-tab.html"];
+
+    pendingCallbackWasCalled = false;
+    [sharedInspectorExtension createTabWithName:@"FourthExtension-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;
+    didShowExtensionTabWasCalled = false;
+    [[webView _inspector] showExtensionTabWithIdentifier:sharedExtensionTabIdentifier.get() completionHandler:^(NSError *error) {
+        EXPECT_NULL(error);
+
+        pendingCallbackWasCalled = true;
+    }];
+    TestWebKitAPI::Util::run(&pendingCallbackWasCalled);
+    TestWebKitAPI::Util::run(&didShowExtensionTabWasCalled);
+
+    auto mainFrameSecretString = @"42-mainFrame";
+    auto innerFrameSecretString = @"42-innerFrame";
+    auto scriptSource = @"document.getElementById('secret').innerText";
+
+    // Test main frame evaluation.
+    pendingCallbackWasCalled = false;
+    [sharedInspectorExtension evaluateScript:scriptSource frameURL:nil contextSecurityOrigin:nil useContentScriptContext:false completionHandler:^(NSError *error, NSDictionary *result) {
+        EXPECT_NULL(error);
+        EXPECT_NOT_NULL(result);
+        EXPECT_NS_EQUAL(result, mainFrameSecretString);
+
+        pendingCallbackWasCalled = true;
+    }];
+    TestWebKitAPI::Util::run(&pendingCallbackWasCalled);
+
+    // Test main frame evaluation failure.
+    pendingCallbackWasCalled = false;
+    [sharedInspectorExtension evaluateScript:@"[].x.x" frameURL:nil contextSecurityOrigin:nil useContentScriptContext:false completionHandler:^(NSError *error, NSDictionary *result) {
+        EXPECT_NULL(result);
+        EXPECT_NOT_NULL(error);
+
+        pendingCallbackWasCalled = true;
+    }];
+    TestWebKitAPI::Util::run(&pendingCallbackWasCalled);
+
+    // Test loose frameURL evaluation.
+    auto *testPageInnerFrameFileURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html", [[testPageFileURL URLByDeletingLastPathComponent] absoluteString]]];
+
+    pendingCallbackWasCalled = false;
+    [sharedInspectorExtension evaluateScript:scriptSource frameURL:testPageInnerFrameFileURL contextSecurityOrigin:nil useContentScriptContext:false completionHandler:^(NSError *error, NSDictionary *result) {
+        EXPECT_NULL(error);
+        EXPECT_NOT_NULL(result);
+        EXPECT_NS_EQUAL(result, innerFrameSecretString);
+
+        pendingCallbackWasCalled = true;
+    }];
+    TestWebKitAPI::Util::run(&pendingCallbackWasCalled);
+
+    // Test strict frameURL evaluation.
+    auto *testPageInnerFrameStrictFileURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@?query=param#fragment", [testPageInnerFrameFileURL absoluteString]]];
+
+    pendingCallbackWasCalled = false;
+    [sharedInspectorExtension evaluateScript:scriptSource frameURL:testPageInnerFrameStrictFileURL contextSecurityOrigin:nil useContentScriptContext:false completionHandler:^(NSError *error, NSDictionary *result) {
+        EXPECT_NULL(error);
+        EXPECT_NOT_NULL(result);
+        EXPECT_NS_EQUAL(result, innerFrameSecretString);
+
+        pendingCallbackWasCalled = true;
+    }];
+    TestWebKitAPI::Util::run(&pendingCallbackWasCalled);
+
+    // Unregister the test extension.
+    pendingCallbackWasCalled = false;
+    [[webView _inspector] unregisterExtension:sharedInspectorExtension.get() completionHandler:^(NSError * error) {
+        EXPECT_NULL(error);
+
+        pendingCallbackWasCalled = true;
+    }];
+    TestWebKitAPI::Util::run(&pendingCallbackWasCalled);
+}
+
</ins><span class="cx"> #endif // ENABLE(INSPECTOR_EXTENSIONS)
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKitCocoaWKInspectorExtensionEvaluateScriptOnPagehtml"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionEvaluateScriptOnPage.html (0 => 287979)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionEvaluateScriptOnPage.html                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionEvaluateScriptOnPage.html   2022-01-13 16:22:10 UTC (rev 287979)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+<html>
+    <head>Test page to be inspected</head>
+    <body>
+        <p>Test page to be inspected.</p>
+        <p id="secret">42-mainFrame</p>
+        <iframe src="./WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html?query=param#fragment"></iframe>
+    </body>
+</html>
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKitCocoaWKInspectorExtensionEvaluateScriptOnPageInnerFramehtml"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html (0 => 287979)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html                              (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKInspectorExtensionEvaluateScriptOnPageInnerFrame.html 2022-01-13 16:22:10 UTC (rev 287979)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+<html>
+    <head>Test inner frame to be inspected</head>
+    <body>
+        <p>Test inner frame to be inspected.</p>
+        <p id="secret">42-innerFrame</p>
+    </body>
+</html>
</ins></span></pre>
</div>
</div>

</body>
</html>