Diff
Modified: trunk/LayoutTests/ChangeLog (271372 => 271373)
--- trunk/LayoutTests/ChangeLog 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/LayoutTests/ChangeLog 2021-01-11 20:13:30 UTC (rev 271373)
@@ -1,3 +1,18 @@
+2021-01-11 Devin Rousso <[email protected]>
+
+ Web Inspector: Debugger: allow breakpoint actions to be evaluated as a user gesture
+ https://bugs.webkit.org/show_bug.cgi?id=200275
+
+ Reviewed by Brian Burg.
+
+ * inspector/debugger/breakpoint-action-emulateUserGesture.html: Added.
+ * inspector/debugger/breakpoint-action-emulateUserGesture-expected.txt: Added.
+ * inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting.html: Added.
+ * inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting-expected.txt: Added.
+
+ * TestExpectations:
+ * platform/wk2/TestExpectations:
+
2021-01-11 Sihui Liu <[email protected]>
Keep newly created IDBIndex objects in deleted map when IDBTransaction is aborted
Modified: trunk/LayoutTests/TestExpectations (271372 => 271373)
--- trunk/LayoutTests/TestExpectations 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/LayoutTests/TestExpectations 2021-01-11 20:13:30 UTC (rev 271373)
@@ -1114,6 +1114,7 @@
webkit.org/b/161951 [ Debug ] inspector/debugger/paused-scopes.html [ Skip ]
# User interaction is a WK2 concept.
+inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting.html [ Skip ]
inspector/debugger/evaluateOnCallFrame-emulateUserGesture-userIsInteracting.html [ Skip ]
inspector/runtime/evaluate-emulateUserGesture-userIsInteracting.html [ Skip ]
inspector/runtime/callFunctionOn-emulateUserGesture-userIsInteracting.html [ Skip ]
Added: trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-expected.txt (0 => 271373)
--- trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-expected.txt 2021-01-11 20:13:30 UTC (rev 271373)
@@ -0,0 +1,13 @@
+Tests for Debugger.BreakpointAction emulateUserGesture parameter.
+
+
+== Running test suite: Debugger.BreakpointAction
+-- Running test case: Debugger.BreakpointAction.emulateUserGesture.false
+Before debugger
+Not in User Gesture
+After debugger
+-- Running test case: Debugger.BreakpointAction.emulateUserGesture.true
+Before debugger
+In User Gesture
+After debugger
+
Added: trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting-expected.txt (0 => 271373)
--- trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting-expected.txt 2021-01-11 20:13:30 UTC (rev 271373)
@@ -0,0 +1,13 @@
+Tests for Debugger.BreakpointAction emulateUserGesture parameter.
+
+
+== Running test suite: Debugger.BreakpointAction
+-- Running test case: Debugger.BreakpointAction.emulateUserGesture.UserIsInteracting.false
+Before debugger
+User is NOT Interacting
+After debugger
+-- Running test case: Debugger.BreakpointAction.emulateUserGesture.UserIsInteracting.true
+Before debugger
+User is Interacting
+After debugger
+
Added: trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting.html (0 => 271373)
--- trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting.html (rev 0)
+++ trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting.html 2021-01-11 20:13:30 UTC (rev 271373)
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function triggerPause() {
+ TestPage.addResult("Before debugger");
+ debugger;
+ TestPage.addResult("After debugger");
+}
+
+function testProcessingUserGesture() {
+ if (window.internals)
+ TestPage.addResult(window.internals.userIsInteracting() ? "User is Interacting" : "User is NOT Interacting");
+}
+
+function test()
+{
+ let suite = InspectorTest.createAsyncSuite("Debugger.BreakpointAction");
+
+ suite.addTestCase({
+ name: "Debugger.BreakpointAction.emulateUserGesture.UserIsInteracting.false",
+ description: "Evalute with the emulateUserGesture option set to false.",
+ async test() {
+ let action = "" WI.BreakpointAction(WI.BreakpointAction.Type.Evaluate, {data: `testProcessingUserGesture()`, emulateUserGesture: false});
+ WI.debuggerManager.debuggerStatementsBreakpoint.addAction(action);
+
+ let pausedPromise = WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Paused);
+ InspectorTest.evaluateInPage("triggerPause()");
+ await pausedPromise;
+
+ InspectorTest.assert(WI.debuggerManager.activeCallFrame, "Should have active call frame.");
+
+ await Promise.all([
+ WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Resumed),
+ WI.debuggerManager.resume(),
+ ]);
+
+ WI.debuggerManager.debuggerStatementsBreakpoint.removeAction(action);
+ }
+ });
+
+ suite.addTestCase({
+ name: "Debugger.BreakpointAction.emulateUserGesture.UserIsInteracting.true",
+ description: "Evalute with the emulateUserGesture option set to true.",
+ async test() {
+ let action = "" WI.BreakpointAction(WI.BreakpointAction.Type.Evaluate, {data: `testProcessingUserGesture()`, emulateUserGesture: true});
+ WI.debuggerManager.debuggerStatementsBreakpoint.addAction(action);
+
+ let pausedPromise = WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Paused);
+ InspectorTest.evaluateInPage("triggerPause()");
+ await pausedPromise;
+
+ InspectorTest.assert(WI.debuggerManager.activeCallFrame, "Should have active call frame.");
+
+ await Promise.all([
+ WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Resumed),
+ WI.debuggerManager.resume(),
+ ]);
+
+ WI.debuggerManager.debuggerStatementsBreakpoint.removeAction(action);
+ }
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Tests for Debugger.BreakpointAction emulateUserGesture parameter.</p>
+</body>
+</html>
Added: trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture.html (0 => 271373)
--- trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture.html (rev 0)
+++ trunk/LayoutTests/inspector/debugger/breakpoint-action-emulateUserGesture.html 2021-01-11 20:13:30 UTC (rev 271373)
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function triggerPause() {
+ TestPage.addResult("Before debugger");
+ debugger;
+ TestPage.addResult("After debugger");
+}
+
+function testProcessingUserGesture() {
+ if (window.internals)
+ TestPage.addResult(window.internals.isProcessingUserGesture() ? "In User Gesture" : "Not in User Gesture");
+}
+
+function test()
+{
+ let suite = InspectorTest.createAsyncSuite("Debugger.BreakpointAction");
+
+ suite.addTestCase({
+ name: "Debugger.BreakpointAction.emulateUserGesture.false",
+ description: "Evalute with the emulateUserGesture option set to false.",
+ async test() {
+ let action = "" WI.BreakpointAction(WI.BreakpointAction.Type.Evaluate, {data: `testProcessingUserGesture()`, emulateUserGesture: false});
+ WI.debuggerManager.debuggerStatementsBreakpoint.addAction(action);
+
+ let pausedPromise = WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Paused);
+ InspectorTest.evaluateInPage("triggerPause()");
+ await pausedPromise;
+
+ InspectorTest.assert(WI.debuggerManager.activeCallFrame, "Should have active call frame.");
+
+ await Promise.all([
+ WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Resumed),
+ WI.debuggerManager.resume(),
+ ]);
+
+ WI.debuggerManager.debuggerStatementsBreakpoint.removeAction(action);
+ }
+ });
+
+ suite.addTestCase({
+ name: "Debugger.BreakpointAction.emulateUserGesture.true",
+ description: "Evalute with the emulateUserGesture option set to true.",
+ async test() {
+ let action = "" WI.BreakpointAction(WI.BreakpointAction.Type.Evaluate, {data: `testProcessingUserGesture()`, emulateUserGesture: true});
+ WI.debuggerManager.debuggerStatementsBreakpoint.addAction(action);
+
+ let pausedPromise = WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Paused);
+ InspectorTest.evaluateInPage("triggerPause()");
+ await pausedPromise;
+
+ InspectorTest.assert(WI.debuggerManager.activeCallFrame, "Should have active call frame.");
+
+ await Promise.all([
+ WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Resumed),
+ WI.debuggerManager.resume(),
+ ]);
+
+ WI.debuggerManager.debuggerStatementsBreakpoint.removeAction(action);
+ }
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Tests for Debugger.BreakpointAction emulateUserGesture parameter.</p>
+</body>
+</html>
Modified: trunk/LayoutTests/platform/wk2/TestExpectations (271372 => 271373)
--- trunk/LayoutTests/platform/wk2/TestExpectations 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/LayoutTests/platform/wk2/TestExpectations 2021-01-11 20:13:30 UTC (rev 271373)
@@ -749,6 +749,7 @@
http/tests/privateClickMeasurement [ Pass ]
# User interaction is a WebKit2 concept.
+inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting.html [ Pass ]
inspector/debugger/evaluateOnCallFrame-emulateUserGesture-userIsInteracting.html [ Pass ]
inspector/runtime/evaluate-emulateUserGesture-userIsInteracting.html [ Pass ]
inspector/runtime/callFunctionOn-emulateUserGesture-userIsInteracting.html [ Pass ]
Modified: trunk/Source/_javascript_Core/ChangeLog (271372 => 271373)
--- trunk/Source/_javascript_Core/ChangeLog 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-01-11 20:13:30 UTC (rev 271373)
@@ -1,3 +1,31 @@
+2021-01-11 Devin Rousso <[email protected]>
+
+ Web Inspector: Debugger: allow breakpoint actions to be evaluated as a user gesture
+ https://bugs.webkit.org/show_bug.cgi?id=200275
+
+ Reviewed by Brian Burg.
+
+ * inspector/protocol/Debugger.json:
+ * debugger/Breakpoint.h:
+ Add an optional `emulateUserGesture` property to `Debugger.BreakpointAction`.
+
+ * debugger/Debugger.h:
+ (JSC::Debugger::Client::debuggerScopeExtensionObject): Renamed from `scopeExtensionObject`.
+ (JSC::Debugger::Client::debuggerWillEvaluate): Added.
+ (JSC::Debugger::Client::debuggerDidEvaluate): Added.
+ * debugger/Debugger.cpp:
+ (JSC::Debugger::evaluateBreakpointCondition):
+ (JSC::Debugger::evaluateBreakpointActions):
+ Consult the `Debugger::Client` before and after evaluating each `Breakpoint::Action`.
+ Currently this is used by `WebCore::PageDebuggerAgent` to push onto or pop from a stack of
+ `WebCore::UserGestureEmulationScope`, each corresponding to a `Breakpoint::Action` that
+ has been set with `emulateUserGesture`.
+
+ * inspector/agents/InspectorDebuggerAgent.h:
+ * inspector/agents/InspectorDebuggerAgent.cpp:
+ (Inspector::parseBreakpointOptions):
+ (Inspector::InspectorDebuggerAgent::debuggerScopeExtensionObject): Renamed from `scopeExtensionObject`.
+
2021-01-10 Yusuke Suzuki <[email protected]>
[JSC] JITCage's Gate mechanism is used in ARM64E even if JITCage is disable
Modified: trunk/Source/_javascript_Core/debugger/Breakpoint.h (271372 => 271373)
--- trunk/Source/_javascript_Core/debugger/Breakpoint.h 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/_javascript_Core/debugger/Breakpoint.h 2021-01-11 20:13:30 UTC (rev 271373)
@@ -55,6 +55,7 @@
Type type;
String data;
BreakpointActionID id { noBreakpointActionID };
+ bool emulateUserGesture { false };
};
using ActionsVector = Vector<Action>;
Modified: trunk/Source/_javascript_Core/debugger/Debugger.cpp (271372 => 271373)
--- trunk/Source/_javascript_Core/debugger/Debugger.cpp 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/_javascript_Core/debugger/Debugger.cpp 2021-01-11 20:13:30 UTC (rev 271373)
@@ -615,7 +615,7 @@
NakedPtr<Exception> exception;
DebuggerCallFrame& debuggerCallFrame = currentDebuggerCallFrame();
- JSObject* scopeExtensionObject = m_client ? m_client->scopeExtensionObject(*this, globalObject, debuggerCallFrame) : nullptr;
+ JSObject* scopeExtensionObject = m_client ? m_client->debuggerScopeExtensionObject(*this, globalObject, debuggerCallFrame) : nullptr;
JSValue result = debuggerCallFrame.evaluateWithScopeExtension(condition, scopeExtensionObject, exception);
// We can lose the debugger while executing _javascript_.
@@ -637,7 +637,10 @@
m_currentProbeBatchId++;
- for (auto& action : breakpoint.actions()) {
+ for (const auto& action : breakpoint.actions()) {
+ if (m_client)
+ m_client->debuggerWillEvaluate(*this, action);
+
auto& debuggerCallFrame = currentDebuggerCallFrame();
switch (action.type) {
@@ -649,7 +652,7 @@
case Breakpoint::Action::Type::Evaluate: {
NakedPtr<Exception> exception;
- JSObject* scopeExtensionObject = m_client ? m_client->scopeExtensionObject(*this, globalObject, debuggerCallFrame) : nullptr;
+ JSObject* scopeExtensionObject = m_client ? m_client->debuggerScopeExtensionObject(*this, globalObject, debuggerCallFrame) : nullptr;
debuggerCallFrame.evaluateWithScopeExtension(action.data, scopeExtensionObject, exception);
if (exception)
reportException(debuggerCallFrame.globalObject(), exception);
@@ -664,7 +667,7 @@
case Breakpoint::Action::Type::Probe: {
NakedPtr<Exception> exception;
- JSObject* scopeExtensionObject = m_client ? m_client->scopeExtensionObject(*this, globalObject, debuggerCallFrame) : nullptr;
+ JSObject* scopeExtensionObject = m_client ? m_client->debuggerScopeExtensionObject(*this, globalObject, debuggerCallFrame) : nullptr;
JSValue result = debuggerCallFrame.evaluateWithScopeExtension(action.data, scopeExtensionObject, exception);
JSC::JSGlobalObject* debuggerGlobalObject = debuggerCallFrame.globalObject();
if (exception)
@@ -677,6 +680,9 @@
}
}
+ if (m_client)
+ m_client->debuggerDidEvaluate(*this, action);
+
if (!isAttached(globalObject))
return;
}
Modified: trunk/Source/_javascript_Core/debugger/Debugger.h (271372 => 271373)
--- trunk/Source/_javascript_Core/debugger/Debugger.h 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/_javascript_Core/debugger/Debugger.h 2021-01-11 20:13:30 UTC (rev 271373)
@@ -144,7 +144,9 @@
public:
virtual ~Client() = default;
- virtual JSObject* scopeExtensionObject(Debugger&, JSGlobalObject*, DebuggerCallFrame&) { return nullptr; }
+ virtual JSObject* debuggerScopeExtensionObject(Debugger&, JSGlobalObject*, DebuggerCallFrame&) { return nullptr; }
+ virtual void debuggerWillEvaluate(Debugger&, const Breakpoint::Action&) { }
+ virtual void debuggerDidEvaluate(Debugger&, const Breakpoint::Action&) { }
};
void setClient(Client*);
Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp (271372 => 271373)
--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.cpp 2021-01-11 20:13:30 UTC (rev 271373)
@@ -130,6 +130,8 @@
// in the frontend across multiple backend probe actions and segregate object groups.
action.id = actionObject->getInteger(Protocol::Debugger::BreakpointAction::idKey).valueOr(JSC::noBreakpointActionID);
+ action.emulateUserGesture = actionObject->getBoolean(Protocol::Debugger::BreakpointAction::emulateUserGestureKey).valueOr(false);
+
actions.append(WTFMove(action));
}
}
@@ -1103,12 +1105,12 @@
return { };
}
-JSC::JSObject* InspectorDebuggerAgent::scopeExtensionObject(JSC::Debugger& debugger, JSC::JSGlobalObject* globalObject, JSC::DebuggerCallFrame& debuggerCallFrame)
+JSC::JSObject* InspectorDebuggerAgent::debuggerScopeExtensionObject(JSC::Debugger& debugger, JSC::JSGlobalObject* globalObject, JSC::DebuggerCallFrame& debuggerCallFrame)
{
auto injectedScript = m_injectedScriptManager.injectedScriptFor(globalObject);
ASSERT(!injectedScript.hasNoValue());
if (injectedScript.hasNoValue())
- return JSC::Debugger::Client::scopeExtensionObject(debugger, globalObject, debuggerCallFrame);
+ return JSC::Debugger::Client::debuggerScopeExtensionObject(debugger, globalObject, debuggerCallFrame);
auto* debuggerGlobalObject = debuggerCallFrame.scope()->globalObject();
auto callFrame = toJS(debuggerGlobalObject, debuggerGlobalObject, _javascript_CallFrame::create(debuggerCallFrame).ptr());
Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h (271372 => 271373)
--- trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorDebuggerAgent.h 2021-01-11 20:13:30 UTC (rev 271373)
@@ -96,7 +96,7 @@
Protocol::ErrorStringOr<void> setShouldBlackboxURL(const String& url, bool shouldBlackbox, Optional<bool>&& caseSensitive, Optional<bool>&& isRegex) final;
// JSC::Debugger::Client
- JSC::JSObject* scopeExtensionObject(JSC::Debugger&, JSC::JSGlobalObject*, JSC::DebuggerCallFrame&) final;
+ JSC::JSObject* debuggerScopeExtensionObject(JSC::Debugger&, JSC::JSGlobalObject*, JSC::DebuggerCallFrame&) final;
// JSC::Debugger::Observer
void didParseSource(JSC::SourceID, const JSC::Debugger::Script&) final;
Modified: trunk/Source/_javascript_Core/inspector/protocol/Debugger.json (271372 => 271373)
--- trunk/Source/_javascript_Core/inspector/protocol/Debugger.json 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/_javascript_Core/inspector/protocol/Debugger.json 2021-01-11 20:13:30 UTC (rev 271373)
@@ -41,7 +41,8 @@
"properties": [
{ "name": "type", "type": "string", "enum": ["log", "evaluate", "sound", "probe"], "description": "Different kinds of breakpoint actions." },
{ "name": "data", "type": "string", "optional": true, "description": "Data associated with this breakpoint type (e.g. for type \"eval\" this is the _javascript_ string to evaluate)." },
- { "name": "id", "$ref": "BreakpointActionIdentifier", "optional": true, "description": "A frontend-assigned identifier for this breakpoint action." }
+ { "name": "id", "$ref": "BreakpointActionIdentifier", "optional": true, "description": "A frontend-assigned identifier for this breakpoint action." },
+ { "name": "emulateUserGesture", "type": "boolean", "optional": true, "description": "Indicates whether this action should be executed with a user gesture or not. Defaults to <code>false<code>." }
]
},
{
Modified: trunk/Source/WebCore/ChangeLog (271372 => 271373)
--- trunk/Source/WebCore/ChangeLog 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/WebCore/ChangeLog 2021-01-11 20:13:30 UTC (rev 271373)
@@ -1,3 +1,23 @@
+2021-01-11 Devin Rousso <[email protected]>
+
+ Web Inspector: Debugger: allow breakpoint actions to be evaluated as a user gesture
+ https://bugs.webkit.org/show_bug.cgi?id=200275
+
+ Reviewed by Brian Burg.
+
+ Tests: inspector/debugger/breakpoint-action-emulateUserGesture.html
+ inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting.html
+
+ * inspector/agents/page/PageDebuggerAgent.cpp:
+ * inspector/agents/page/PageDebuggerAgent.h:
+ (WebCore::PageDebuggerAgent::debuggerWillEvaluate): Added.
+ (WebCore::PageDebuggerAgent::debuggerDidEvaluate): Added.
+ Maintain a stack of `UserGestureEmulationScope` whenever evaluating breakpoint actions (but
+ only add/remove items if the current action is set to `emulateUserGesture`).
+
+ * inspector/agents/page/UserGestureEmulationScope.h:
+ Make it fast allocated so it can be used with `UniqueRef`.
+
2021-01-11 Sihui Liu <[email protected]>
Keep newly created IDBIndex objects in deleted map when IDBTransaction is aborted
Modified: trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp (271372 => 271373)
--- trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp 2021-01-11 20:13:30 UTC (rev 271373)
@@ -120,6 +120,18 @@
PageConsoleClient::unmute();
}
+void PageDebuggerAgent::debuggerWillEvaluate(JSC::Debugger&, const JSC::Breakpoint::Action& action)
+{
+ if (action.emulateUserGesture)
+ m_breakpointActionUserGestureEmulationScopeStack.append(makeUniqueRef<UserGestureEmulationScope>(m_inspectedPage, true));
+}
+
+void PageDebuggerAgent::debuggerDidEvaluate(JSC::Debugger&, const JSC::Breakpoint::Action& action)
+{
+ if (action.emulateUserGesture)
+ m_breakpointActionUserGestureEmulationScopeStack.removeLast();
+}
+
void PageDebuggerAgent::breakpointActionLog(JSC::JSGlobalObject* lexicalGlobalObject, const String& message)
{
m_inspectedPage.console().addMessage(MessageSource::JS, MessageLevel::Log, message, createScriptCallStack(lexicalGlobalObject));
Modified: trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.h (271372 => 271373)
--- trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.h 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.h 2021-01-11 20:13:30 UTC (rev 271373)
@@ -39,6 +39,7 @@
class Document;
class Frame;
class Page;
+class UserGestureEmulationScope;
class PageDebuggerAgent final : public WebDebuggerAgent {
WTF_MAKE_NONCOPYABLE(PageDebuggerAgent);
@@ -51,6 +52,10 @@
// DebuggerBackendDispatcherHandler
Inspector::Protocol::ErrorStringOr<std::tuple<Ref<Inspector::Protocol::Runtime::RemoteObject>, Optional<bool> /* wasThrown */, Optional<int> /* savedResultIndex */>> evaluateOnCallFrame(const Inspector::Protocol::Debugger::CallFrameId&, const String& _expression_, const String& objectGroup, Optional<bool>&& includeCommandLineAPI, Optional<bool>&& doNotPauseOnExceptionsAndMuteConsole, Optional<bool>&& returnByValue, Optional<bool>&& generatePreview, Optional<bool>&& saveResult, Optional<bool>&& emulateUserGesture);
+ // JSC::Debugger::Client
+ void debuggerWillEvaluate(JSC::Debugger&, const JSC::Breakpoint::Action&);
+ void debuggerDidEvaluate(JSC::Debugger&, const JSC::Breakpoint::Action&);
+
// JSC::Debugger::Observer
void breakpointActionLog(JSC::JSGlobalObject*, const String& data);
@@ -75,6 +80,7 @@
Inspector::InjectedScript injectedScriptForEval(Inspector::Protocol::ErrorString&, Optional<Inspector::Protocol::Runtime::ExecutionContextId>&&);
Page& m_inspectedPage;
+ Vector<UniqueRef<UserGestureEmulationScope>> m_breakpointActionUserGestureEmulationScopeStack;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h (271372 => 271373)
--- trunk/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h 2021-01-11 20:13:30 UTC (rev 271373)
@@ -41,6 +41,7 @@
class UserGestureEmulationScope {
WTF_MAKE_NONCOPYABLE(UserGestureEmulationScope);
+ WTF_MAKE_FAST_ALLOCATED;
public:
UserGestureEmulationScope(Page& inspectedPage, bool emulateUserGesture);
~UserGestureEmulationScope();
Modified: trunk/Source/WebInspectorUI/ChangeLog (271372 => 271373)
--- trunk/Source/WebInspectorUI/ChangeLog 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/WebInspectorUI/ChangeLog 2021-01-11 20:13:30 UTC (rev 271373)
@@ -1,3 +1,45 @@
+2021-01-11 Devin Rousso <[email protected]>
+
+ Web Inspector: Debugger: allow breakpoint actions to be evaluated as a user gesture
+ https://bugs.webkit.org/show_bug.cgi?id=200275
+
+ Reviewed by Brian Burg.
+
+ * UserInterface/Models/BreakpointAction.js:
+ (WI.BreakpointAction.supportsEmulateUserAction): Added.
+ (WI.BreakpointAction.fromJSON):
+ (WI.BreakpointAction.prototype.toJSON):
+ (WI.BreakpointAction.prototype.set type):
+ (WI.BreakpointAction.prototype.set data):
+ (WI.BreakpointAction.prototype.get emulateUserGesture): Added.
+ (WI.BreakpointAction.prototype.set emulateUserGesture): Added.
+ Add an `_emulateUserGesture` property to match `Debugger.BreakpointAction`.
+
+ * UserInterface/Views/BreakpointActionView.js:
+ (WI.BreakpointActionView):
+ (WI.BreakpointActionView.prototype._updateBody):
+ (WI.BreakpointActionView.prototype._handleEmulateUserGestureCheckboxChange): Added.
+ * UserInterface/Views/BreakpointActionView.css:
+ (.breakpoint-action-block-body .description): Added.
+ (.breakpoint-action-block-body > .flex):
+ (.breakpoint-action-block-body > .description): Deleted.
+ Add a "[ ] Emulate User Gesture" under the log/evaluate/probe input.
+
+ * UserInterface/Models/Breakpoint.js:
+ (WI.Breakpoint):
+ (WI.Breakpoint.prototype.addAction):
+ (WI.Breakpoint.prototype.removeAction):
+ (WI.Breakpoint.prototype._handleBreakpointActionModified): Renamed from `_handleBreakpointActionChanged`.
+ Drive-by: combine `TypeChanged` and `DataChanged` into a single `Modified` event since all
+ the listeners currently have the same callback.
+
+ * UserInterface/Views/LogContentView.js:
+ (WI.LogContentView):
+ (WI.LogContentView.prototype._handleEmulateInUserGestureSettingChanged):
+ Drive-by: only show the "Emulate User Gesture" checkbox when it's supported.
+
+ * Localizations/en.lproj/localizedStrings.js:
+
2021-01-08 Patrick Angle <[email protected]>
Web Inspector: Font Details sidebar - Improve visibility of values by emphasizing them/de-emphasizing range information
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (271372 => 271373)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2021-01-11 20:13:30 UTC (rev 271373)
@@ -549,7 +549,10 @@
localizedStrings["Elements Tab Name"] = "Elements";
/* Category label for experimental settings pertaining to the Elements tab */
localizedStrings["Elements Tab: @ Experimental Settings"] = "Elements Tab:";
-localizedStrings["Emulate User Gesture"] = "Emulate User Gesture";
+/* Checkbox shown in the Console to cause future evaluations as though they are in response to user interaction. */
+localizedStrings["Emulate User Gesture @ Console"] = "Emulate User Gesture";
+/* Checkbox shown when configuring log/evaluate/probe breakpoint actions to cause it to be evaluated as though it was in response to user interaction. */
+localizedStrings["Emulate User Gesture @ breakpoint action configuration"] = "Emulate User Gesture";
localizedStrings["Enable Audit"] = "Enable Audit";
localizedStrings["Enable Breakpoint"] = "Enable Breakpoint";
localizedStrings["Enable Breakpoints"] = "Enable Breakpoints";
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Breakpoint.js (271372 => 271373)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Breakpoint.js 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Breakpoint.js 2021-01-11 20:13:30 UTC (rev 271373)
@@ -45,10 +45,8 @@
this._autoContinue = autoContinue || false;
this._actions = actions || [];
- for (let action of this._actions) {
- action.addEventListener(WI.BreakpointAction.Event.DataChanged, this._handleBreakpointActionChanged, this);
- action.addEventListener(WI.BreakpointAction.Event.TypeChanged, this._handleBreakpointActionChanged, this);
- }
+ for (let action of this._actions)
+ action.addEventListener(WI.BreakpointAction.Event.Modified, this._handleBreakpointActionModified, this);
}
// Import / Export
@@ -225,8 +223,7 @@
console.assert(this.editable, this);
console.assert(action instanceof WI.BreakpointAction, action);
- action.addEventListener(WI.BreakpointAction.Event.DataChanged, this._handleBreakpointActionChanged, this);
- action.addEventListener(WI.BreakpointAction.Event.TypeChanged, this._handleBreakpointActionChanged, this);
+ action.addEventListener(WI.BreakpointAction.Event.Modified, this._handleBreakpointActionModified, this);
if (!precedingAction)
this._actions.push(action);
@@ -254,8 +251,7 @@
this._actions.splice(index, 1);
- action.removeEventListener(WI.BreakpointAction.Event.DataChanged, this._handleBreakpointActionChanged, this);
- action.removeEventListener(WI.BreakpointAction.Event.TypeChanged, this._handleBreakpointActionChanged, this);
+ action.removeEventListener(WI.BreakpointAction.Event.Modified, this._handleBreakpointActionModified, this);
if (!this._actions.length)
this.autoContinue = false;
@@ -339,7 +335,7 @@
// Private
- _handleBreakpointActionChanged(event)
+ _handleBreakpointActionModified(event)
{
console.assert(this.editable, this);
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/BreakpointAction.js (271372 => 271373)
--- trunk/Source/WebInspectorUI/UserInterface/Models/BreakpointAction.js 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/BreakpointAction.js 2021-01-11 20:13:30 UTC (rev 271373)
@@ -25,7 +25,7 @@
WI.BreakpointAction = class BreakpointAction extends WI.Object
{
- constructor(type, {data} = {})
+ constructor(type, {data, emulateUserGesture} = {})
{
console.assert(Object.values(WI.BreakpointAction.Type).includes(type), type);
console.assert(!data || typeof data ="" "string", data);
@@ -35,8 +35,19 @@
this._type = type;
this._data = data || null;
this._id = WI.debuggerManager.nextBreakpointActionIdentifier();
+ this._emulateUserGesture = !!emulateUserGesture;
}
+ // Static
+
+ static supportsEmulateUserAction()
+ {
+ // COMPATIBILITY (iOS 14): the `emulateUserGesture` property of `Debugger.BreakpointAction` did not exist yet.
+ // Since support can't be tested directly, check for the `options` parameter of `Debugger.setPauseOnExceptions`.
+ // FIXME: Use explicit version checking once <https://webkit.org/b/148680> is fixed.
+ return WI.sharedApp.isWebDebuggable() && InspectorBackend.hasCommand("Debugger.setPauseOnExceptions", "options");
+ }
+
// Import / Export
static fromJSON(json)
@@ -43,6 +54,7 @@
{
return new WI.BreakpointAction(json.type, {
data: json.data,
+ emulateUserGesture: json.emulateUserGesture,
});
}
@@ -53,6 +65,8 @@
};
if (this._data)
json.data = ""
+ if (this._emulateUserGesture)
+ json.emulateUserGesture = this._emulateUserGesture;
return json;
}
@@ -74,7 +88,7 @@
this._type = type;
- this.dispatchEventToListeners(WI.BreakpointAction.Event.TypeChanged);
+ this.dispatchEventToListeners(WI.BreakpointAction.Event.Modified);
}
get data()
@@ -91,9 +105,24 @@
this._data = data;
- this.dispatchEventToListeners(WI.BreakpointAction.Event.DataChanged);
+ this.dispatchEventToListeners(WI.BreakpointAction.Event.Modified);
}
+ get emulateUserGesture()
+ {
+ return this._emulateUserGesture;
+ }
+
+ set emulateUserGesture(emulateUserGesture)
+ {
+ if (this._emulateUserGesture === emulateUserGesture)
+ return;
+
+ this._emulateUserGesture = emulateUserGesture;
+
+ this.dispatchEventToListeners(WI.BreakpointAction.Event.Modified);
+ }
+
toProtocol()
{
let json = this.toJSON();
@@ -110,6 +139,5 @@
};
WI.BreakpointAction.Event = {
- DataChanged: "breakpoint-action-data-changed",
- TypeChanged: "breakpoint-action-type-changed",
+ Modified: "breakpoint-action-modified",
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.css (271372 => 271373)
--- trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.css 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.css 2021-01-11 20:13:30 UTC (rev 271373)
@@ -64,9 +64,8 @@
box-shadow: inset 0 0 2px hsl(0, 0%, 78%);
}
-.breakpoint-action-block-body > .description {
- margin-top: 6px;
- margin-inline-end: 2px;
+.breakpoint-action-block-body .description {
+ flex-grow: 1;
text-align: right;
color: var(--text-color-gray-medium);
}
@@ -76,6 +75,12 @@
text-align: left;
}
+.breakpoint-action-block-body > .flex {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+}
+
.breakpoint-action-eval-editor {
margin: 2px 0;
padding: 2px 0 1px 0;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.js (271372 => 271373)
--- trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.js 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.js 2021-01-11 20:13:30 UTC (rev 271373)
@@ -126,6 +126,21 @@
{
this._bodyElement.removeChildren();
+ let createOptionsElements = () => {
+ let optionsElement = document.createElement("div");
+
+ let emulateUserGestureLabel = optionsElement.appendChild(document.createElement("label"));
+
+ this._emulateUserGestureCheckbox = emulateUserGestureLabel.appendChild(document.createElement("input"));
+ this._emulateUserGestureCheckbox.type = "checkbox";
+ this._emulateUserGestureCheckbox.checked = this._action.emulateUserGesture;
+ this._emulateUserGestureCheckbox.addEventListener("change", this._handleEmulateUserGestureCheckboxChange.bind(this));
+
+ emulateUserGestureLabel.appendChild(document.createTextNode(WI.UIString("Emulate User Gesture", "Emulate User Gesture @ breakpoint action configuration", "Checkbox shown when configuring log/evaluate/probe breakpoint actions to cause it to be evaluated as though it was in response to user interaction.")));
+
+ return optionsElement;
+ };
+
switch (this._action.type) {
case WI.BreakpointAction.Type.Log:
this._bodyElement.hidden = false;
@@ -138,7 +153,13 @@
if (!omitFocus)
setTimeout(function() { input.focus(); }, 0);
- var descriptionElement = this._bodyElement.appendChild(document.createElement("div"));
+ var flexWrapper = this._bodyElement.appendChild(document.createElement("div"));
+ flexWrapper.className = "flex";
+
+ if (WI.BreakpointAction.supportsEmulateUserAction())
+ flexWrapper.appendChild(createOptionsElements());
+
+ var descriptionElement = flexWrapper.appendChild(document.createElement("div"));
descriptionElement.classList.add("description");
descriptionElement.setAttribute("dir", "ltr");
descriptionElement.textContent = WI.UIString("${expr} = _expression_");
@@ -167,6 +188,9 @@
var completionController = new WI.CodeMirrorCompletionController(this._delegate.breakpointActionViewCodeMirrorCompletionControllerMode(this, this._codeMirror), this._codeMirror);
completionController.addExtendedCompletionProvider("_javascript_", WI._javascript_RuntimeCompletionProvider);
+ if (WI.BreakpointAction.supportsEmulateUserAction())
+ this._bodyElement.appendChild(createOptionsElements());
+
// CodeMirror needs a refresh after the popover displays to layout otherwise it doesn't appear.
setTimeout(() => {
this._codeMirror.refresh();
@@ -207,4 +231,9 @@
this._codeMirrorViewport.to = to;
this._delegate.breakpointActionViewResized(this);
}
+
+ _handleEmulateUserGestureCheckboxChange(event)
+ {
+ this._action.emulateUserGesture = this._emulateUserGestureCheckbox.checked;
+ }
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/LogContentView.js (271372 => 271373)
--- trunk/Source/WebInspectorUI/UserInterface/Views/LogContentView.js 2021-01-11 20:12:32 UTC (rev 271372)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LogContentView.js 2021-01-11 20:13:30 UTC (rev 271373)
@@ -77,15 +77,22 @@
}, this);
WI.settings.clearLogOnNavigate.addEventListener(WI.Setting.Event.Changed, this._handleClearLogOnNavigateSettingChanged, this);
- this._emulateInUserGestureNavigationItem = new WI.CheckboxNavigationItem("emulate-in-user-gesture", WI.UIString("Emulate User Gesture"), WI.settings.emulateInUserGesture.value);
- this._emulateInUserGestureNavigationItem.tooltip = WI.UIString("Run console commands as if inside a user gesture");
- this._emulateInUserGestureNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, function(event) {
- WI.settings.emulateInUserGesture.value = !WI.settings.emulateInUserGesture.value;
- }, this);
- WI.settings.emulateInUserGesture.addEventListener(WI.Setting.Event.Changed, this._handleEmulateInUserGestureSettingChanged, this);
+ let checkboxesNavigationItems = [this._preserveLogNavigationItem];
- this._checkboxesNavigationItemGroup = new WI.GroupNavigationItem([this._preserveLogNavigationItem, this._emulateInUserGestureNavigationItem, new WI.DividerNavigationItem]);
+ // COMPATIBILITY (iOS 13): `Runtime.evaluate` did not have a `emulateUserGesture` parameter yet.
+ if (WI.sharedApp.isWebDebuggable() && InspectorBackend.hasCommand("Runtime.evaluate", "emulateUserGesture")) {
+ this._emulateUserGestureNavigationItem = new WI.CheckboxNavigationItem("emulate-in-user-gesture", WI.UIString("Emulate User Gesture", "Emulate User Gesture @ Console", "Checkbox shown in the Console to cause future evaluations as though they are in response to user interaction."), WI.settings.emulateInUserGesture.value);
+ this._emulateUserGestureNavigationItem.tooltip = WI.UIString("Run console commands as if inside a user gesture");
+ this._emulateUserGestureNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, function(event) {
+ WI.settings.emulateInUserGesture.value = !WI.settings.emulateInUserGesture.value;
+ }, this);
+ WI.settings.emulateInUserGesture.addEventListener(WI.Setting.Event.Changed, this._handleEmulateInUserGestureSettingChanged, this);
+ checkboxesNavigationItems.push(this._emulateUserGestureNavigationItem);
+ }
+ checkboxesNavigationItems.push(new WI.DividerNavigationItem);
+ this._checkboxesNavigationItemGroup = new WI.GroupNavigationItem(checkboxesNavigationItems);
+
let scopeBarItems = [
new WI.ScopeBarItem(WI.LogContentView.Scopes.All, WI.UIString("All"), {exclusive: true}),
new WI.ScopeBarItem(WI.LogContentView.Scopes.Evaluations, WI.UIString("Evaluations"), {className: "evaluations"}),
@@ -906,7 +913,7 @@
_handleEmulateInUserGestureSettingChanged()
{
- this._emulateInUserGestureNavigationItem.checked = WI.settings.emulateInUserGesture.value;
+ this._emulateUserGestureNavigationItem.checked = WI.settings.emulateInUserGesture.value;
}
_keyDown(event)