Title: [291517] trunk
Revision
291517
Author
[email protected]
Date
2022-03-18 18:03:20 -0700 (Fri, 18 Mar 2022)

Log Message

Web Inspector: REGRESSION(?): Emulate User Gesture doesn't work
https://bugs.webkit.org/show_bug.cgi?id=232584
<rdar://problem/84899576>

Reviewed by Patrick Angle.

Source/_javascript_Core:

* inspector/agents/InspectorDebuggerAgent.h:
* inspector/agents/InspectorDebuggerAgent.cpp:
(Inspector::InspectorDebuggerAgent::evaluateOnCallFrame):
* inspector/agents/InspectorRuntimeAgent.h:
* inspector/agents/InspectorRuntimeAgent.cpp:
(Inspector::InspectorRuntimeAgent::evaluate):
(Inspector::InspectorRuntimeAgent::callFunctionOn):
Create overloads for these (protocol) methods so that we can avoid having to fetch the same
`InjectedScript` more than once (i.e. if the subclass fetches the `InjectedScript` and then
called into the baseclass, which also fetches the same `InjectedScript`).

* debugger/Debugger.h:
(JSC::Debugger::Client::debuggerWillEvaluate):
(JSC::Debugger::Client::debuggerDidEvaluate):
* debugger/Debugger.cpp:
(JSC::Debugger::evaluateBreakpointActions):
Pass along the current `JSGlobalObject` to eventually derive a relevant `WebCore::Document`.

Source/WebCore:

Recently some new web APIs have gone a step further by using a new way to detect one-time
user interaction called [transient activation](https://html.spec.whatwg.org/multipage/interaction.html#transient-activation).
In order to support invoking these APIs from Web Inspector, `UserGestureEmulationScope`
needs to be adjusted to support marking the context as having recently been interacted with,
which turns out to just involve plumbing a `Document` through to the `UserGestureIndicator`,
as the rest has already been implemented.

Tests: inspector/debugger/breakpoint-action-emulateUserGesture-hasTransientActiviation.html
       inspector/debugger/evaluateOnCallFrame-emulateUserGesture-hasTransientActivation.html
       inspector/runtime/callFunctionOn-emulateUserGesture-hasTransientActivation.html
       inspector/runtime/evaluate-emulateUserGesture-hasTransientActivation.html

* inspector/agents/page/PageDebuggerAgent.h:
* inspector/agents/page/PageDebuggerAgent.cpp:
(WebCore::PageDebuggerAgent::evaluateOnCallFrame):
(WebCore::PageDebuggerAgent::debuggerWillEvaluate):
(WebCore::PageDebuggerAgent::debuggerDidEvaluate):
* inspector/agents/page/PageRuntimeAgent.cpp:
(WebCore::PageRuntimeAgent::evaluate):
(WebCore::PageRuntimeAgent::callFunctionOn):
* inspector/agents/page/UserGestureEmulationScope.h:
* inspector/agents/page/UserGestureEmulationScope.cpp:
(WebCore::UserGestureEmulationScope::UserGestureEmulationScope):
Derive a `Document` from the `JSGlobalObject` of the relevant `InjectedScript`.

* inspector/InspectorFrontendClientLocal.cpp:
(WebCore::InspectorFrontendClientLocal::openURLExternally):
* inspector/InspectorFrontendHost.cpp:
(WebCore::FrontendMenuProvider::contextMenuItemSelected):
* inspector/agents/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::navigate):
Drive-by: Pass the relevant `Document` to the `UserGestureIndicator` just in case the Web
          Inspector frontend needs it.

* page/DOMWindow.h:
* testing/Internals.idl:
* testing/Internals.h:
* testing/Internals.cpp:
(WebCore::Internals::hasTransientActivation): Added.
Expose `DOMWindow::hasTransientActivation` to tests.

LayoutTests:

* inspector/debugger/breakpoint-action-emulateUserGesture-hasTransientActiviation.html: Added.
* inspector/debugger/breakpoint-action-emulateUserGesture-hasTransientActiviation-expected.txt: Added.
* inspector/debugger/evaluateOnCallFrame-emulateUserGesture-hasTransientActivation.html: Added.
* inspector/debugger/evaluateOnCallFrame-emulateUserGesture-hasTransientActivation-expected.txt: Added.
* inspector/runtime/callFunctionOn-emulateUserGesture-hasTransientActivation.html: Added.
* inspector/runtime/callFunctionOn-emulateUserGesture-hasTransientActivation-expected.txt: Added.
* inspector/runtime/evaluate-emulateUserGesture-hasTransientActivation.html: Added.
* inspector/runtime/evaluate-emulateUserGesture-hasTransientActivation-expected.txt: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (291516 => 291517)


--- trunk/LayoutTests/ChangeLog	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/LayoutTests/ChangeLog	2022-03-19 01:03:20 UTC (rev 291517)
@@ -1,3 +1,20 @@
+2022-03-18  Devin Rousso  <[email protected]>
+
+        Web Inspector: REGRESSION(?): Emulate User Gesture doesn't work
+        https://bugs.webkit.org/show_bug.cgi?id=232584
+        <rdar://problem/84899576>
+
+        Reviewed by Patrick Angle.
+
+        * inspector/debugger/breakpoint-action-emulateUserGesture-hasTransientActiviation.html: Added.
+        * inspector/debugger/breakpoint-action-emulateUserGesture-hasTransientActiviation-expected.txt: Added.
+        * inspector/debugger/evaluateOnCallFrame-emulateUserGesture-hasTransientActivation.html: Added.
+        * inspector/debugger/evaluateOnCallFrame-emulateUserGesture-hasTransientActivation-expected.txt: Added.
+        * inspector/runtime/callFunctionOn-emulateUserGesture-hasTransientActivation.html: Added.
+        * inspector/runtime/callFunctionOn-emulateUserGesture-hasTransientActivation-expected.txt: Added.
+        * inspector/runtime/evaluate-emulateUserGesture-hasTransientActivation.html: Added.
+        * inspector/runtime/evaluate-emulateUserGesture-hasTransientActivation-expected.txt: Added.
+
 2022-03-18  Ryan Haddad  <[email protected]>
 
         [macOS arm64] webrtc/vp9-profile2.html is consistently timing out

Added: trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-hasTransientActiviation-expected.txt (0 => 291517)


--- trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-hasTransientActiviation-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-hasTransientActiviation-expected.txt	2022-03-19 01:03:20 UTC (rev 291517)
@@ -0,0 +1,18 @@
+Tests for Debugger.BreakpointAction emulateUserGesture parameter.
+
+
+== Running test suite: Debugger.BreakpointAction
+-- Running test case: Debugger.BreakpointAction.emulateUserGesture.hasTransientActivation.false
+Pausing...
+before debugger
+No transient activation
+Resuming...
+after debugger
+
+-- Running test case: Debugger.BreakpointAction.emulateUserGesture.hasTransientActivation.true
+Pausing...
+before debugger
+Has transient activation
+Resuming...
+after debugger
+

Added: trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-hasTransientActiviation.html (0 => 291517)


--- trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-hasTransientActiviation.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-hasTransientActiviation.html	2022-03-19 01:03:20 UTC (rev 291517)
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function triggerPause() {
+    TestPage.addResult("before debugger");
+    debugger;
+    TestPage.addResult("after debugger");
+}
+
+function testEmulateUserGesture() {
+    if (window.internals)
+        TestPage.addResult(window.internals.hasTransientActivation() ? "Has transient activation" : "No transient activation");
+}
+
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("Debugger.BreakpointAction");
+
+    suite.addTestCase({
+        name: "Debugger.BreakpointAction.emulateUserGesture.hasTransientActivation.false",
+        description: "Evalute with the emulateUserGesture option set to false.",
+        async test() {
+            let action = "" WI.BreakpointAction(WI.BreakpointAction.Type.Evaluate, {data: `testEmulateUserGesture()`, emulateUserGesture: false});
+            WI.debuggerManager.debuggerStatementsBreakpoint.addAction(action);
+
+            InspectorTest.log("Pausing...");
+            let pausedPromise = WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Paused);
+            let evaluatePromise = InspectorTest.evaluateInPage("triggerPause()");
+            await pausedPromise;
+
+            InspectorTest.assert(WI.debuggerManager.activeCallFrame, "Should have active call frame.");
+
+            InspectorTest.log("Resuming...");
+            await Promise.all([
+                WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Resumed),
+                WI.debuggerManager.resume(),
+            ]);
+
+            WI.debuggerManager.debuggerStatementsBreakpoint.removeAction(action);
+
+            await evaluatePromise;
+        }
+    });
+
+    suite.addTestCase({
+        name: "Debugger.BreakpointAction.emulateUserGesture.hasTransientActivation.true",
+        description: "Evalute with the emulateUserGesture option set to true.",
+        async test() {
+            let action = "" WI.BreakpointAction(WI.BreakpointAction.Type.Evaluate, {data: `testEmulateUserGesture()`, emulateUserGesture: true});
+            WI.debuggerManager.debuggerStatementsBreakpoint.addAction(action);
+
+            InspectorTest.log("Pausing...");
+            let pausedPromise = WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Paused);
+            let evaluatePromise = InspectorTest.evaluateInPage("triggerPause()");
+            await pausedPromise;
+
+            InspectorTest.assert(WI.debuggerManager.activeCallFrame, "Should have active call frame.");
+
+            InspectorTest.log("Resuming...");
+            await Promise.all([
+                WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Resumed),
+                WI.debuggerManager.resume(),
+            ]);
+
+            WI.debuggerManager.debuggerStatementsBreakpoint.removeAction(action);
+
+            await evaluatePromise;
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Tests for Debugger.BreakpointAction emulateUserGesture parameter.</p>
+</body>
+</html>

Added: trunk/LayoutTests/inspector/debugger/evaluateOnCallFrame-emulateUserGesture-hasTransientActivation-expected.txt (0 => 291517)


--- trunk/LayoutTests/inspector/debugger/evaluateOnCallFrame-emulateUserGesture-hasTransientActivation-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/debugger/evaluateOnCallFrame-emulateUserGesture-hasTransientActivation-expected.txt	2022-03-19 01:03:20 UTC (rev 291517)
@@ -0,0 +1,18 @@
+Tests for Debugger.evaluateOnCallFrame emulateUserGesture option.
+
+
+== Running test suite: Debugger.evaluateOnCallFrame
+-- Running test case: Debugger.evaluateOnCallFrame.emulateUserGesture.hasTransientActivation.false
+Pausing...
+before debugger
+No transient activation
+Resuming...
+after debugger
+
+-- Running test case: Debugger.evaluateOnCallFrame.emulateUserGesture.hasTransientActivation.true
+Pausing...
+before debugger
+Has transient activation
+Resuming...
+after debugger
+

Added: trunk/LayoutTests/inspector/debugger/evaluateOnCallFrame-emulateUserGesture-hasTransientActivation.html (0 => 291517)


--- trunk/LayoutTests/inspector/debugger/evaluateOnCallFrame-emulateUserGesture-hasTransientActivation.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/debugger/evaluateOnCallFrame-emulateUserGesture-hasTransientActivation.html	2022-03-19 01:03:20 UTC (rev 291517)
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function triggerPause() {
+    TestPage.addResult("before debugger");
+    debugger;
+    TestPage.addResult("after debugger");
+}
+
+function testEmulateUserGesture() {
+    if (window.internals)
+        TestPage.addResult(window.internals.hasTransientActivation() ? "Has transient activation" : "No transient activation");
+}
+
+function test()
+{
+    const _expression_ = `testEmulateUserGesture()`;
+    const objectGroup = "test";
+
+    let suite = InspectorTest.createAsyncSuite("Debugger.evaluateOnCallFrame");
+
+    suite.addTestCase({
+        name: "Debugger.evaluateOnCallFrame.emulateUserGesture.hasTransientActivation.false",
+        description: "Evalute with the emulateUserGesture option set to false.",
+        async test() {
+            InspectorTest.assert(!WI.debuggerManager.paused, "Should not be paused.");
+
+            InspectorTest.log("Pausing...");
+            let pausedPromise = WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Paused);
+            let evaluatePromise = InspectorTest.evaluateInPage("triggerPause()");
+            await pausedPromise;
+
+            InspectorTest.assert(WI.debuggerManager.activeCallFrame, "Should have active call frame.");
+            await DebuggerAgent.evaluateOnCallFrame.invoke({callFrameId: WI.debuggerManager.activeCallFrame.id, _expression_, objectGroup, emulateUserGesture: false});
+
+            InspectorTest.log("Resuming...");
+            await Promise.all([
+                WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Resumed),
+                WI.debuggerManager.resume(),
+            ]);
+
+            await evaluatePromise;
+        }
+    });
+
+    suite.addTestCase({
+        name: "Debugger.evaluateOnCallFrame.emulateUserGesture.hasTransientActivation.true",
+        description: "Evalute with the emulateUserGesture option set to true.",
+        async test() {
+            InspectorTest.assert(!WI.debuggerManager.paused, "Should not be paused.");
+
+            InspectorTest.log("Pausing...");
+            let pausedPromise = WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Paused);
+            let evaluatePromise = InspectorTest.evaluateInPage("triggerPause()");
+            await pausedPromise;
+
+            InspectorTest.assert(WI.debuggerManager.activeCallFrame, "Should have active call frame.");
+            await DebuggerAgent.evaluateOnCallFrame.invoke({callFrameId: WI.debuggerManager.activeCallFrame.id, _expression_, objectGroup, emulateUserGesture: true});
+
+            InspectorTest.log("Resuming...");
+            await Promise.all([
+                WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Resumed),
+                WI.debuggerManager.resume(),
+            ]);
+
+            await evaluatePromise;
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Tests for Debugger.evaluateOnCallFrame emulateUserGesture option.</p>
+</body>
+</html>

Added: trunk/LayoutTests/inspector/runtime/callFunctionOn-emulateUserGesture-hasTransientActivation-expected.txt (0 => 291517)


--- trunk/LayoutTests/inspector/runtime/callFunctionOn-emulateUserGesture-hasTransientActivation-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/runtime/callFunctionOn-emulateUserGesture-hasTransientActivation-expected.txt	2022-03-19 01:03:20 UTC (rev 291517)
@@ -0,0 +1,9 @@
+Tests for Runtime.callFunctionOn emulateUserGesture option.
+
+
+== Running test suite: Runtime.callFunctionOn
+-- Running test case: Runtime.callFunctionOn.emulateUserGesture.hasTransientActivation.false
+No transient activation
+-- Running test case: Runtime.callFunctionOn.emulateUserGesture.hasTransientActivation.true
+Has transient activation
+

Added: trunk/LayoutTests/inspector/runtime/callFunctionOn-emulateUserGesture-hasTransientActivation.html (0 => 291517)


--- trunk/LayoutTests/inspector/runtime/callFunctionOn-emulateUserGesture-hasTransientActivation.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/runtime/callFunctionOn-emulateUserGesture-hasTransientActivation.html	2022-03-19 01:03:20 UTC (rev 291517)
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+
+function load() {
+    document.getElementById("test").addEventListener("click", (event) => {
+        if (window.internals)
+            TestPage.addResult(window.internals.hasTransientActivation() ? "Has transient activation" : "No transient activation");
+    });
+
+    runTest();
+}
+
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("Runtime.callFunctionOn");
+
+    suite.addTestCase({
+        name: "Runtime.callFunctionOn.emulateUserGesture.hasTransientActivation.false",
+        description: "Check that callFunctionOn is not considered a user interaction when emulateUserGesture is false.",
+        async test() {
+            let testElement = await RuntimeAgent.evaluate.invoke({_expression_: `document.getElementById("test")`});
+            await RuntimeAgent.callFunctionOn.invoke({functionDeclaration: `function() { this.click(); }`, emulateUserGesture: false, objectId: testElement.result.objectId});
+        },
+    });
+
+    suite.addTestCase({
+        name: "Runtime.callFunctionOn.emulateUserGesture.hasTransientActivation.true",
+        description: "Check that callFunctionOn is considered a user interaction when emulateUserGesture is true.",
+        async test() {
+            let testElement = await RuntimeAgent.evaluate.invoke({_expression_: `document.getElementById("test")`});
+            await RuntimeAgent.callFunctionOn.invoke({functionDeclaration: `function() { this.click(); }`, emulateUserGesture: true, objectId: testElement.result.objectId});
+        },
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="load()">
+    <p>Tests for Runtime.callFunctionOn emulateUserGesture option.</p>
+    <a id="test"></a>
+</body>
+</html>

Added: trunk/LayoutTests/inspector/runtime/evaluate-emulateUserGesture-hasTransientActivation-expected.txt (0 => 291517)


--- trunk/LayoutTests/inspector/runtime/evaluate-emulateUserGesture-hasTransientActivation-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/runtime/evaluate-emulateUserGesture-hasTransientActivation-expected.txt	2022-03-19 01:03:20 UTC (rev 291517)
@@ -0,0 +1,9 @@
+Tests for Runtime emulateUserGesture option.
+
+
+== Running test suite: Runtime.evaluate
+-- Running test case: Runtime.evaluate.emulateUserGesture.hasTransientActivation.false
+No transient activation
+-- Running test case: Runtime.evaluate.emulateUserGesture.hasTransientActivation.true
+Has transient activation
+

Added: trunk/LayoutTests/inspector/runtime/evaluate-emulateUserGesture-hasTransientActivation.html (0 => 291517)


--- trunk/LayoutTests/inspector/runtime/evaluate-emulateUserGesture-hasTransientActivation.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/runtime/evaluate-emulateUserGesture-hasTransientActivation.html	2022-03-19 01:03:20 UTC (rev 291517)
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+
+function load() {
+    document.getElementById("test").addEventListener("click", (event) => {
+        if (window.internals)
+            TestPage.addResult(window.internals.hasTransientActivation() ? "Has transient activation" : "No transient activation");
+    });
+
+    runTest();
+}
+
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("Runtime.evaluate");
+
+    suite.addTestCase({
+        name: "Runtime.evaluate.emulateUserGesture.hasTransientActivation.false",
+        description: "Check that the evaluation is not considered a user interaction when emulateUserGesture is false.",
+        async test() {
+            await RuntimeAgent.evaluate.invoke({_expression_: `document.getElementById("test").click()`, emulateUserGesture: false});
+        },
+    });
+
+    suite.addTestCase({
+        name: "Runtime.evaluate.emulateUserGesture.hasTransientActivation.true",
+        description: "Check that the evaluation is considered a user interaction when emulateUserGesture is true.",
+        async test() {
+            await RuntimeAgent.evaluate.invoke({_expression_: `document.getElementById("test").click()`, emulateUserGesture: true});
+        },
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="load()">
+    <p>Tests for Runtime emulateUserGesture option.</p>
+    <a id="test"></a>
+</body>
+</html>

Modified: trunk/Source/_javascript_Core/ChangeLog (291516 => 291517)


--- trunk/Source/_javascript_Core/ChangeLog	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/_javascript_Core/ChangeLog	2022-03-19 01:03:20 UTC (rev 291517)
@@ -1,3 +1,29 @@
+2022-03-18  Devin Rousso  <[email protected]>
+
+        Web Inspector: REGRESSION(?): Emulate User Gesture doesn't work
+        https://bugs.webkit.org/show_bug.cgi?id=232584
+        <rdar://problem/84899576>
+
+        Reviewed by Patrick Angle.
+
+        * inspector/agents/InspectorDebuggerAgent.h:
+        * inspector/agents/InspectorDebuggerAgent.cpp:
+        (Inspector::InspectorDebuggerAgent::evaluateOnCallFrame):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::evaluate):
+        (Inspector::InspectorRuntimeAgent::callFunctionOn):
+        Create overloads for these (protocol) methods so that we can avoid having to fetch the same
+        `InjectedScript` more than once (i.e. if the subclass fetches the `InjectedScript` and then
+        called into the baseclass, which also fetches the same `InjectedScript`).
+
+        * debugger/Debugger.h:
+        (JSC::Debugger::Client::debuggerWillEvaluate):
+        (JSC::Debugger::Client::debuggerDidEvaluate):
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::evaluateBreakpointActions):
+        Pass along the current `JSGlobalObject` to eventually derive a relevant `WebCore::Document`.
+
 2022-03-18  Yusuke Suzuki  <[email protected]>
 
         [JSC] Reduce # of registers used in RegExpTestInline to allow using unlinked DFG in x64

Modified: trunk/Source/_javascript_Core/debugger/Debugger.cpp (291516 => 291517)


--- trunk/Source/_javascript_Core/debugger/Debugger.cpp	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/_javascript_Core/debugger/Debugger.cpp	2022-03-19 01:03:20 UTC (rev 291517)
@@ -637,7 +637,7 @@
 
     for (const auto& action : breakpoint.actions()) {
         if (m_client)
-            m_client->debuggerWillEvaluate(*this, action);
+            m_client->debuggerWillEvaluate(*this, globalObject, action);
 
         auto& debuggerCallFrame = currentDebuggerCallFrame();
 
@@ -679,7 +679,7 @@
         }
 
         if (m_client)
-            m_client->debuggerDidEvaluate(*this, action);
+            m_client->debuggerDidEvaluate(*this, globalObject, action);
 
         if (!isAttached(globalObject))
             return;

Modified: trunk/Source/_javascript_Core/debugger/Debugger.h (291516 => 291517)


--- trunk/Source/_javascript_Core/debugger/Debugger.h	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/_javascript_Core/debugger/Debugger.h	2022-03-19 01:03:20 UTC (rev 291517)
@@ -147,8 +147,8 @@
         virtual ~Client() = default;
 
         virtual JSObject* debuggerScopeExtensionObject(Debugger&, JSGlobalObject*, DebuggerCallFrame&) { return nullptr; }
-        virtual void debuggerWillEvaluate(Debugger&, const Breakpoint::Action&) { }
-        virtual void debuggerDidEvaluate(Debugger&, const Breakpoint::Action&) { }
+        virtual void debuggerWillEvaluate(Debugger&, JSGlobalObject*, const Breakpoint::Action&) { }
+        virtual void debuggerDidEvaluate(Debugger&, JSGlobalObject*, const Breakpoint::Action&) { }
     };
 
     void setClient(Client*);

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp (291516 => 291517)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp	2022-03-19 01:03:20 UTC (rev 291517)
@@ -992,17 +992,24 @@
     return { };
 }
 
-Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> InspectorDebuggerAgent::evaluateOnCallFrame(const Protocol::Debugger::CallFrameId& callFrameId, const String& _expression_, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&&  /* emulateUserGesture */)
+Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> InspectorDebuggerAgent::evaluateOnCallFrame(const Protocol::Debugger::CallFrameId& callFrameId, const String& _expression_, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture)
 {
+    InjectedScript injectedScript = m_injectedScriptManager.injectedScriptForObjectId(callFrameId);
+    if (injectedScript.hasNoValue())
+        return makeUnexpected("Missing injected script for given callFrameId"_s);
+
+    return evaluateOnCallFrame(injectedScript, callFrameId, _expression_, objectGroup, WTFMove(includeCommandLineAPI), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(saveResult), WTFMove(emulateUserGesture));
+}
+
+Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> InspectorDebuggerAgent::evaluateOnCallFrame(InjectedScript& injectedScript, const Protocol::Debugger::CallFrameId& callFrameId, const String& _expression_, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& /* emulateUserGesture */)
+{
+    ASSERT(!injectedScript.hasNoValue());
+
     Protocol::ErrorString errorString;
 
     if (!assertPaused(errorString))
         return makeUnexpected(errorString);
 
-    InjectedScript injectedScript = m_injectedScriptManager.injectedScriptForObjectId(callFrameId);
-    if (injectedScript.hasNoValue())
-        return makeUnexpected("Missing injected script for given callFrameId"_s);
-
     JSC::Debugger::TemporarilyDisableExceptionBreakpoints temporarilyDisableExceptionBreakpoints(m_debugger);
 
     bool pauseAndMute = doNotPauseOnExceptionsAndMuteConsole && *doNotPauseOnExceptionsAndMuteConsole;

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h (291516 => 291517)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h	2022-03-19 01:03:20 UTC (rev 291517)
@@ -152,6 +152,8 @@
     virtual void internalEnable();
     virtual void internalDisable(bool isBeingDestroyed);
 
+    Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluateOnCallFrame(InjectedScript&, const Protocol::Debugger::CallFrameId&, const String& _expression_, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture);
+
     InjectedScriptManager& injectedScriptManager() const { return m_injectedScriptManager; }
     virtual InjectedScript injectedScriptForEval(Protocol::ErrorString&, std::optional<Protocol::Runtime::ExecutionContextId>&&) = 0;
 

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorRuntimeAgent.cpp (291516 => 291517)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorRuntimeAgent.cpp	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorRuntimeAgent.cpp	2022-03-19 01:03:20 UTC (rev 291517)
@@ -121,7 +121,7 @@
     return { { *result, message, WTFMove(range) } };
 }
 
-Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> InspectorRuntimeAgent::evaluate(const String& _expression_, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<Protocol::Runtime::ExecutionContextId>&& executionContextId, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& /* emulateUserGesture */)
+Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> InspectorRuntimeAgent::evaluate(const String& _expression_, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<Protocol::Runtime::ExecutionContextId>&& executionContextId, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture)
 {
     Protocol::ErrorString errorString;
 
@@ -129,6 +129,15 @@
     if (injectedScript.hasNoValue())
         return makeUnexpected(errorString);
 
+    return evaluate(injectedScript, _expression_, objectGroup, WTFMove(includeCommandLineAPI), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(saveResult), WTFMove(emulateUserGesture));
+}
+
+Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> InspectorRuntimeAgent::evaluate(InjectedScript& injectedScript, const String& _expression_, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& /* emulateUserGesture */)
+{
+    ASSERT(!injectedScript.hasNoValue());
+
+    Protocol::ErrorString errorString;
+
     RefPtr<Protocol::Runtime::RemoteObject> result;
     std::optional<bool> wasThrown;
     std::optional<int> savedResultIndex;
@@ -168,14 +177,21 @@
     });
 }
 
-Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> InspectorRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObjectId& objectId, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& /* emulateUserGesture */)
+Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> InspectorRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObjectId& objectId, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture)
 {
-    Protocol::ErrorString errorString;
-
     InjectedScript injectedScript = m_injectedScriptManager.injectedScriptForObjectId(objectId);
     if (injectedScript.hasNoValue())
         return makeUnexpected("Missing injected script for given objectId"_s);
 
+    return callFunctionOn(injectedScript, objectId, functionDeclaration, WTFMove(arguments), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(emulateUserGesture));
+}
+
+Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> InspectorRuntimeAgent::callFunctionOn(InjectedScript& injectedScript, const Protocol::Runtime::RemoteObjectId& objectId, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& /* emulateUserGesture */)
+{
+    ASSERT(!injectedScript.hasNoValue());
+
+    Protocol::ErrorString errorString;
+
     RefPtr<Protocol::Runtime::RemoteObject> result;
     std::optional<bool> wasThrown;
 

Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorRuntimeAgent.h (291516 => 291517)


--- trunk/Source/_javascript_Core/inspector/agents/InspectorRuntimeAgent.h	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorRuntimeAgent.h	2022-03-19 01:03:20 UTC (rev 291517)
@@ -81,6 +81,9 @@
 protected:
     InspectorRuntimeAgent(AgentContext&);
 
+    Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluate(InjectedScript&, const String& _expression_, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture);
+    Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> callFunctionOn(InjectedScript&, const Protocol::Runtime::RemoteObjectId&, const String& functionDeclaration, RefPtr<JSON::Array>&& arguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture);
+
     InjectedScriptManager& injectedScriptManager() { return m_injectedScriptManager; }
 
     virtual InjectedScript injectedScriptForEval(Protocol::ErrorString&, std::optional<Protocol::Runtime::ExecutionContextId>&&) = 0;

Modified: trunk/Source/WebCore/ChangeLog (291516 => 291517)


--- trunk/Source/WebCore/ChangeLog	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/WebCore/ChangeLog	2022-03-19 01:03:20 UTC (rev 291517)
@@ -1,3 +1,52 @@
+2022-03-18  Devin Rousso  <[email protected]>
+
+        Web Inspector: REGRESSION(?): Emulate User Gesture doesn't work
+        https://bugs.webkit.org/show_bug.cgi?id=232584
+        <rdar://problem/84899576>
+
+        Reviewed by Patrick Angle.
+
+        Recently some new web APIs have gone a step further by using a new way to detect one-time
+        user interaction called [transient activation](https://html.spec.whatwg.org/multipage/interaction.html#transient-activation).
+        In order to support invoking these APIs from Web Inspector, `UserGestureEmulationScope`
+        needs to be adjusted to support marking the context as having recently been interacted with,
+        which turns out to just involve plumbing a `Document` through to the `UserGestureIndicator`,
+        as the rest has already been implemented.
+
+        Tests: inspector/debugger/breakpoint-action-emulateUserGesture-hasTransientActiviation.html
+               inspector/debugger/evaluateOnCallFrame-emulateUserGesture-hasTransientActivation.html
+               inspector/runtime/callFunctionOn-emulateUserGesture-hasTransientActivation.html
+               inspector/runtime/evaluate-emulateUserGesture-hasTransientActivation.html
+
+        * inspector/agents/page/PageDebuggerAgent.h:
+        * inspector/agents/page/PageDebuggerAgent.cpp:
+        (WebCore::PageDebuggerAgent::evaluateOnCallFrame):
+        (WebCore::PageDebuggerAgent::debuggerWillEvaluate):
+        (WebCore::PageDebuggerAgent::debuggerDidEvaluate):
+        * inspector/agents/page/PageRuntimeAgent.cpp:
+        (WebCore::PageRuntimeAgent::evaluate):
+        (WebCore::PageRuntimeAgent::callFunctionOn):
+        * inspector/agents/page/UserGestureEmulationScope.h:
+        * inspector/agents/page/UserGestureEmulationScope.cpp:
+        (WebCore::UserGestureEmulationScope::UserGestureEmulationScope):
+        Derive a `Document` from the `JSGlobalObject` of the relevant `InjectedScript`.
+
+        * inspector/InspectorFrontendClientLocal.cpp:
+        (WebCore::InspectorFrontendClientLocal::openURLExternally):
+        * inspector/InspectorFrontendHost.cpp:
+        (WebCore::FrontendMenuProvider::contextMenuItemSelected):
+        * inspector/agents/InspectorPageAgent.cpp:
+        (WebCore::InspectorPageAgent::navigate):
+        Drive-by: Pass the relevant `Document` to the `UserGestureIndicator` just in case the Web
+                  Inspector frontend needs it.
+
+        * page/DOMWindow.h:
+        * testing/Internals.idl:
+        * testing/Internals.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::hasTransientActivation): Added.
+        Expose `DOMWindow::hasTransientActivation` to tests.
+
 2022-03-18  Nikolaos Mouchtaris  <[email protected]>
 
         Calc() cleanup

Modified: trunk/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp (291516 => 291517)


--- trunk/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp	2022-03-19 01:03:20 UTC (rev 291517)
@@ -264,8 +264,10 @@
 
 void InspectorFrontendClientLocal::openURLExternally(const String& url)
 {
-    UserGestureIndicator indicator { ProcessingUserGesture };
     Frame& mainFrame = m_inspectedPageController->inspectedPage().mainFrame();
+
+    UserGestureIndicator indicator { ProcessingUserGesture, mainFrame.document() };
+
     FrameLoadRequest frameLoadRequest { *mainFrame.document(), mainFrame.document()->securityOrigin(), { }, blankTargetFrameName(), InitiatedByMainFrame::Unknown };
 
     bool created;

Modified: trunk/Source/WebCore/inspector/InspectorFrontendHost.cpp (291516 => 291517)


--- trunk/Source/WebCore/inspector/InspectorFrontendHost.cpp	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/WebCore/inspector/InspectorFrontendHost.cpp	2022-03-19 01:03:20 UTC (rev 291517)
@@ -108,7 +108,7 @@
     void contextMenuItemSelected(ContextMenuAction action, const String&) override
     {
         if (m_frontendHost) {
-            UserGestureIndicator gestureIndicator(ProcessingUserGesture);
+            UserGestureIndicator gestureIndicator(ProcessingUserGesture, dynamicDowncast<Document>(executionContext(m_frontendApiObject.globalObject())));
             int itemNumber = action - ContextMenuItemBaseCustomTag;
 
             Deprecated::ScriptFunctionCall function(m_frontendApiObject, "contextMenuItemSelected", WebCore::functionCallHandlerFromAnyThread);

Modified: trunk/Source/WebCore/inspector/agents/InspectorPageAgent.cpp (291516 => 291517)


--- trunk/Source/WebCore/inspector/agents/InspectorPageAgent.cpp	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/WebCore/inspector/agents/InspectorPageAgent.cpp	2022-03-19 01:03:20 UTC (rev 291517)
@@ -409,9 +409,10 @@
 
 Protocol::ErrorStringOr<void> InspectorPageAgent::navigate(const String& url)
 {
-    UserGestureIndicator indicator { ProcessingUserGesture };
     Frame& frame = m_inspectedPage.mainFrame();
 
+    UserGestureIndicator indicator { ProcessingUserGesture, frame.document() };
+
     ResourceRequest resourceRequest { frame.document()->completeURL(url) };
     FrameLoadRequest frameLoadRequest { *frame.document(), frame.document()->securityOrigin(), WTFMove(resourceRequest), selfTargetFrameName(), InitiatedByMainFrame::Unknown };
     frameLoadRequest.disableNavigationToInvalidURL();

Modified: trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp (291516 => 291517)


--- trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp	2022-03-19 01:03:20 UTC (rev 291517)
@@ -39,6 +39,7 @@
 #include "InspectorPageAgent.h"
 #include "InstrumentingAgents.h"
 #include "JSDOMWindowCustom.h"
+#include "JSExecState.h"
 #include "Page.h"
 #include "PageConsoleClient.h"
 #include "PageDebugger.h"
@@ -69,9 +70,12 @@
 
 Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> PageDebuggerAgent::evaluateOnCallFrame(const Protocol::Debugger::CallFrameId& callFrameId, const String& _expression_, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture)
 {
-    UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture && *emulateUserGesture);
+    auto injectedScript = injectedScriptManager().injectedScriptForObjectId(callFrameId);
+    if (injectedScript.hasNoValue())
+        return makeUnexpected("Missing injected script for given callFrameId"_s);
 
-    return WebDebuggerAgent::evaluateOnCallFrame(callFrameId, _expression_, objectGroup, WTFMove(includeCommandLineAPI), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(saveResult), WTFMove(emulateUserGesture));
+    UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), dynamicDowncast<Document>(executionContext(injectedScript.globalObject())));
+    return WebDebuggerAgent::evaluateOnCallFrame(injectedScript, callFrameId, _expression_, objectGroup, WTFMove(includeCommandLineAPI), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(saveResult), WTFMove(emulateUserGesture));
 }
 
 void PageDebuggerAgent::internalEnable()
@@ -119,16 +123,14 @@
     PageConsoleClient::unmute();
 }
 
-void PageDebuggerAgent::debuggerWillEvaluate(JSC::Debugger&, const JSC::Breakpoint::Action& action)
+void PageDebuggerAgent::debuggerWillEvaluate(JSC::Debugger&, JSC::JSGlobalObject* globalObject, const JSC::Breakpoint::Action& action)
 {
-    if (action.emulateUserGesture)
-        m_breakpointActionUserGestureEmulationScopeStack.append(makeUniqueRef<UserGestureEmulationScope>(m_inspectedPage, true));
+    m_breakpointActionUserGestureEmulationScopeStack.append(makeUniqueRef<UserGestureEmulationScope>(m_inspectedPage, action.emulateUserGesture, dynamicDowncast<Document>(executionContext(globalObject))));
 }
 
-void PageDebuggerAgent::debuggerDidEvaluate(JSC::Debugger&, const JSC::Breakpoint::Action& action)
+void PageDebuggerAgent::debuggerDidEvaluate(JSC::Debugger&, JSC::JSGlobalObject*, const JSC::Breakpoint::Action&)
 {
-    if (action.emulateUserGesture)
-        m_breakpointActionUserGestureEmulationScopeStack.removeLast();
+    m_breakpointActionUserGestureEmulationScopeStack.removeLast();
 }
 
 void PageDebuggerAgent::breakpointActionLog(JSC::JSGlobalObject* lexicalGlobalObject, const String& message)

Modified: trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.h (291516 => 291517)


--- trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.h	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.h	2022-03-19 01:03:20 UTC (rev 291517)
@@ -53,8 +53,8 @@
     Inspector::Protocol::ErrorStringOr<std::tuple<Ref<Inspector::Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> evaluateOnCallFrame(const Inspector::Protocol::Debugger::CallFrameId&, const String& _expression_, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture);
 
     // JSC::Debugger::Client
-    void debuggerWillEvaluate(JSC::Debugger&, const JSC::Breakpoint::Action&);
-    void debuggerDidEvaluate(JSC::Debugger&, const JSC::Breakpoint::Action&);
+    void debuggerWillEvaluate(JSC::Debugger&, JSC::JSGlobalObject*, const JSC::Breakpoint::Action&);
+    void debuggerDidEvaluate(JSC::Debugger&, JSC::JSGlobalObject*, const JSC::Breakpoint::Action&);
 
     // JSC::Debugger::Observer
     void breakpointActionLog(JSC::JSGlobalObject*, const String& data);

Modified: trunk/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp (291516 => 291517)


--- trunk/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp	2022-03-19 01:03:20 UTC (rev 291517)
@@ -38,6 +38,7 @@
 #include "InspectorPageAgent.h"
 #include "InstrumentingAgents.h"
 #include "JSDOMWindowCustom.h"
+#include "JSExecState.h"
 #include "Page.h"
 #include "PageConsoleClient.h"
 #include "ScriptController.h"
@@ -189,14 +190,24 @@
 
 Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */, std::optional<int> /* savedResultIndex */>> PageRuntimeAgent::evaluate(const String& _expression_, const String& objectGroup, std::optional<bool>&& includeCommandLineAPI, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<Protocol::Runtime::ExecutionContextId>&& executionContextId, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& saveResult, std::optional<bool>&& emulateUserGesture)
 {
-    UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture && *emulateUserGesture);
-    return InspectorRuntimeAgent::evaluate(_expression_, objectGroup, WTFMove(includeCommandLineAPI), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(executionContextId), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(saveResult), WTFMove(emulateUserGesture));
+    Protocol::ErrorString errorString;
+
+    auto injectedScript = injectedScriptForEval(errorString, WTFMove(executionContextId));
+    if (injectedScript.hasNoValue())
+        return makeUnexpected(errorString);
+
+    UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), dynamicDowncast<Document>(executionContext(injectedScript.globalObject())));
+    return InspectorRuntimeAgent::evaluate(injectedScript, _expression_, objectGroup, WTFMove(includeCommandLineAPI), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(saveResult), WTFMove(emulateUserGesture));
 }
 
 Protocol::ErrorStringOr<std::tuple<Ref<Protocol::Runtime::RemoteObject>, std::optional<bool> /* wasThrown */>> PageRuntimeAgent::callFunctionOn(const Protocol::Runtime::RemoteObjectId& objectId, const String& _expression_, RefPtr<JSON::Array>&& optionalArguments, std::optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, std::optional<bool>&& returnByValue, std::optional<bool>&& generatePreview, std::optional<bool>&& emulateUserGesture)
 {
-    UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture && *emulateUserGesture);
-    return InspectorRuntimeAgent::callFunctionOn(objectId, _expression_, WTFMove(optionalArguments), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(emulateUserGesture));
+    auto injectedScript = injectedScriptManager().injectedScriptForObjectId(objectId);
+    if (injectedScript.hasNoValue())
+        return makeUnexpected("Missing injected script for given objectId"_s);
+
+    UserGestureEmulationScope userGestureScope(m_inspectedPage, emulateUserGesture.value_or(false), dynamicDowncast<Document>(executionContext(injectedScript.globalObject())));
+    return InspectorRuntimeAgent::callFunctionOn(injectedScript, objectId, _expression_, WTFMove(optionalArguments), WTFMove(doNotPauseOnExceptionsAndMuteConsole), WTFMove(returnByValue), WTFMove(generatePreview), WTFMove(emulateUserGesture));
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.cpp (291516 => 291517)


--- trunk/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.cpp	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.cpp	2022-03-19 01:03:20 UTC (rev 291517)
@@ -33,14 +33,15 @@
 
 #include "Chrome.h"
 #include "ChromeClient.h"
+#include "Document.h"
 #include "Page.h"
 #include "UserGestureIndicator.h"
 
 namespace WebCore {
 
-UserGestureEmulationScope::UserGestureEmulationScope(Page& inspectedPage, bool emulateUserGesture)
+UserGestureEmulationScope::UserGestureEmulationScope(Page& inspectedPage, bool emulateUserGesture, Document* document)
     : m_pageChromeClient(inspectedPage.chrome().client())
-    , m_gestureIndicator(emulateUserGesture ? std::optional<ProcessingUserGestureState>(ProcessingUserGesture) : std::nullopt)
+    , m_gestureIndicator(emulateUserGesture ? std::optional<ProcessingUserGestureState>(ProcessingUserGesture) : std::nullopt, document)
     , m_emulateUserGesture(emulateUserGesture)
     , m_userWasInteracting(false)
 {

Modified: trunk/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h (291516 => 291517)


--- trunk/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h	2022-03-19 01:03:20 UTC (rev 291517)
@@ -37,6 +37,7 @@
 namespace WebCore {
 
 class ChromeClient;
+class Document;
 class Page;
 
 class UserGestureEmulationScope {
@@ -43,7 +44,7 @@
     WTF_MAKE_NONCOPYABLE(UserGestureEmulationScope);
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    UserGestureEmulationScope(Page& inspectedPage, bool emulateUserGesture);
+    UserGestureEmulationScope(Page&, bool emulateUserGesture, Document* = nullptr);
     ~UserGestureEmulationScope();
 
 private:

Modified: trunk/Source/WebCore/page/DOMWindow.h (291516 => 291517)


--- trunk/Source/WebCore/page/DOMWindow.h	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/WebCore/page/DOMWindow.h	2022-03-19 01:03:20 UTC (rev 291517)
@@ -183,7 +183,7 @@
     void setLastActivationTimestamp(MonotonicTime lastActivationTimestamp) { m_lastActivationTimestamp = lastActivationTimestamp; }
     MonotonicTime lastActivationTimestamp() const { return m_lastActivationTimestamp; }
     void notifyActivated(MonotonicTime);
-    bool hasTransientActivation() const;
+    WEBCORE_EXPORT bool hasTransientActivation() const;
     bool consumeTransientActivation();
 
     WEBCORE_EXPORT Location& location();

Modified: trunk/Source/WebCore/testing/Internals.cpp (291516 => 291517)


--- trunk/Source/WebCore/testing/Internals.cpp	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/WebCore/testing/Internals.cpp	2022-03-19 01:03:20 UTC (rev 291517)
@@ -5112,6 +5112,15 @@
     return false;
 }
 
+bool Internals::hasTransientActivation()
+{
+    if (auto* document = contextDocument()) {
+        if (auto* window = document->domWindow())
+            return window->hasTransientActivation();
+    }
+    return false;
+}
+
 double Internals::lastHandledUserGestureTimestamp()
 {
     Document* document = contextDocument();

Modified: trunk/Source/WebCore/testing/Internals.h (291516 => 291517)


--- trunk/Source/WebCore/testing/Internals.h	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/WebCore/testing/Internals.h	2022-03-19 01:03:20 UTC (rev 291517)
@@ -811,6 +811,8 @@
 
     bool userIsInteracting();
 
+    bool hasTransientActivation();
+
     RefPtr<GCObservation> observeGC(JSC::JSValue);
 
     enum class UserInterfaceLayoutDirection : uint8_t { LTR, RTL };

Modified: trunk/Source/WebCore/testing/Internals.idl (291516 => 291517)


--- trunk/Source/WebCore/testing/Internals.idl	2022-03-19 00:59:09 UTC (rev 291516)
+++ trunk/Source/WebCore/testing/Internals.idl	2022-03-19 01:03:20 UTC (rev 291517)
@@ -869,6 +869,8 @@
 
     boolean userIsInteracting();
 
+    boolean hasTransientActivation();
+
     GCObservation? observeGC(any observed);
 
     undefined setUserInterfaceLayoutDirection(UserInterfaceLayoutDirection userInterfaceLayoutDirection);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to