Changeset 271373 in webkit


Ignore:
Timestamp:
Jan 11, 2021 12:13:30 PM (18 months ago)
Author:
Devin Rousso
Message:

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.

Source/JavaScriptCore:

  • 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.

Source/WebCore:

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.

Source/WebInspectorUI:

  • 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:

LayoutTests:

  • 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.
Location:
trunk
Files:
4 added
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r271368 r271373  
     12021-01-11  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Debugger: allow breakpoint actions to be evaluated as a user gesture
     4        https://bugs.webkit.org/show_bug.cgi?id=200275
     5
     6        Reviewed by Brian Burg.
     7
     8        * inspector/debugger/breakpoint-action-emulateUserGesture.html: Added.
     9        * inspector/debugger/breakpoint-action-emulateUserGesture-expected.txt: Added.
     10        * inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting.html: Added.
     11        * inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting-expected.txt: Added.
     12
     13        * TestExpectations:
     14        * platform/wk2/TestExpectations:
     15
    1162021-01-11  Sihui Liu  <sihui_liu@appe.com>
    217
  • trunk/LayoutTests/TestExpectations

    r271362 r271373  
    11151115
    11161116# User interaction is a WK2 concept.
     1117inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting.html [ Skip ]
    11171118inspector/debugger/evaluateOnCallFrame-emulateUserGesture-userIsInteracting.html [ Skip ]
    11181119inspector/runtime/evaluate-emulateUserGesture-userIsInteracting.html [ Skip ]
  • trunk/LayoutTests/platform/wk2/TestExpectations

    r270158 r271373  
    750750
    751751# User interaction is a WebKit2 concept.
     752inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting.html [ Pass ]
    752753inspector/debugger/evaluateOnCallFrame-emulateUserGesture-userIsInteracting.html [ Pass ]
    753754inspector/runtime/evaluate-emulateUserGesture-userIsInteracting.html [ Pass ]
  • trunk/Source/JavaScriptCore/ChangeLog

    r271352 r271373  
     12021-01-11  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Debugger: allow breakpoint actions to be evaluated as a user gesture
     4        https://bugs.webkit.org/show_bug.cgi?id=200275
     5
     6        Reviewed by Brian Burg.
     7
     8        * inspector/protocol/Debugger.json:
     9        * debugger/Breakpoint.h:
     10        Add an optional `emulateUserGesture` property to `Debugger.BreakpointAction`.
     11
     12        * debugger/Debugger.h:
     13        (JSC::Debugger::Client::debuggerScopeExtensionObject): Renamed from `scopeExtensionObject`.
     14        (JSC::Debugger::Client::debuggerWillEvaluate): Added.
     15        (JSC::Debugger::Client::debuggerDidEvaluate): Added.
     16        * debugger/Debugger.cpp:
     17        (JSC::Debugger::evaluateBreakpointCondition):
     18        (JSC::Debugger::evaluateBreakpointActions):
     19        Consult the `Debugger::Client` before and after evaluating each `Breakpoint::Action`.
     20        Currently this is used by `WebCore::PageDebuggerAgent` to push onto or pop from a stack of
     21        `WebCore::UserGestureEmulationScope`, each corresponding to a `Breakpoint::Action` that
     22        has been set with `emulateUserGesture`.
     23
     24        * inspector/agents/InspectorDebuggerAgent.h:
     25        * inspector/agents/InspectorDebuggerAgent.cpp:
     26        (Inspector::parseBreakpointOptions):
     27        (Inspector::InspectorDebuggerAgent::debuggerScopeExtensionObject): Renamed from `scopeExtensionObject`.
     28
    1292021-01-10  Yusuke Suzuki  <ysuzuki@apple.com>
    230
  • trunk/Source/JavaScriptCore/debugger/Breakpoint.h

    r266534 r271373  
    5656        String data;
    5757        BreakpointActionID id { noBreakpointActionID };
     58        bool emulateUserGesture { false };
    5859    };
    5960
  • trunk/Source/JavaScriptCore/debugger/Debugger.cpp

    r269023 r271373  
    616616    NakedPtr<Exception> exception;
    617617    DebuggerCallFrame& debuggerCallFrame = currentDebuggerCallFrame();
    618     JSObject* scopeExtensionObject = m_client ? m_client->scopeExtensionObject(*this, globalObject, debuggerCallFrame) : nullptr;
     618    JSObject* scopeExtensionObject = m_client ? m_client->debuggerScopeExtensionObject(*this, globalObject, debuggerCallFrame) : nullptr;
    619619    JSValue result = debuggerCallFrame.evaluateWithScopeExtension(condition, scopeExtensionObject, exception);
    620620
     
    638638    m_currentProbeBatchId++;
    639639
    640     for (auto& action : breakpoint.actions()) {
     640    for (const auto& action : breakpoint.actions()) {
     641        if (m_client)
     642            m_client->debuggerWillEvaluate(*this, action);
     643
    641644        auto& debuggerCallFrame = currentDebuggerCallFrame();
    642645
     
    650653        case Breakpoint::Action::Type::Evaluate: {
    651654            NakedPtr<Exception> exception;
    652             JSObject* scopeExtensionObject = m_client ? m_client->scopeExtensionObject(*this, globalObject, debuggerCallFrame) : nullptr;
     655            JSObject* scopeExtensionObject = m_client ? m_client->debuggerScopeExtensionObject(*this, globalObject, debuggerCallFrame) : nullptr;
    653656            debuggerCallFrame.evaluateWithScopeExtension(action.data, scopeExtensionObject, exception);
    654657            if (exception)
     
    665668        case Breakpoint::Action::Type::Probe: {
    666669            NakedPtr<Exception> exception;
    667             JSObject* scopeExtensionObject = m_client ? m_client->scopeExtensionObject(*this, globalObject, debuggerCallFrame) : nullptr;
     670            JSObject* scopeExtensionObject = m_client ? m_client->debuggerScopeExtensionObject(*this, globalObject, debuggerCallFrame) : nullptr;
    668671            JSValue result = debuggerCallFrame.evaluateWithScopeExtension(action.data, scopeExtensionObject, exception);
    669672            JSC::JSGlobalObject* debuggerGlobalObject = debuggerCallFrame.globalObject();
     
    677680        }
    678681        }
     682
     683        if (m_client)
     684            m_client->debuggerDidEvaluate(*this, action);
    679685
    680686        if (!isAttached(globalObject))
  • trunk/Source/JavaScriptCore/debugger/Debugger.h

    r269023 r271373  
    145145        virtual ~Client() = default;
    146146
    147         virtual JSObject* scopeExtensionObject(Debugger&, JSGlobalObject*, DebuggerCallFrame&) { return nullptr; }
     147        virtual JSObject* debuggerScopeExtensionObject(Debugger&, JSGlobalObject*, DebuggerCallFrame&) { return nullptr; }
     148        virtual void debuggerWillEvaluate(Debugger&, const Breakpoint::Action&) { }
     149        virtual void debuggerDidEvaluate(Debugger&, const Breakpoint::Action&) { }
    148150    };
    149151
  • trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp

    r269023 r271373  
    131131                action.id = actionObject->getInteger(Protocol::Debugger::BreakpointAction::idKey).valueOr(JSC::noBreakpointActionID);
    132132
     133                action.emulateUserGesture = actionObject->getBoolean(Protocol::Debugger::BreakpointAction::emulateUserGestureKey).valueOr(false);
     134
    133135                actions.append(WTFMove(action));
    134136            }
     
    11041106}
    11051107
    1106 JSC::JSObject* InspectorDebuggerAgent::scopeExtensionObject(JSC::Debugger& debugger, JSC::JSGlobalObject* globalObject, JSC::DebuggerCallFrame& debuggerCallFrame)
     1108JSC::JSObject* InspectorDebuggerAgent::debuggerScopeExtensionObject(JSC::Debugger& debugger, JSC::JSGlobalObject* globalObject, JSC::DebuggerCallFrame& debuggerCallFrame)
    11071109{
    11081110    auto injectedScript = m_injectedScriptManager.injectedScriptFor(globalObject);
    11091111    ASSERT(!injectedScript.hasNoValue());
    11101112    if (injectedScript.hasNoValue())
    1111         return JSC::Debugger::Client::scopeExtensionObject(debugger, globalObject, debuggerCallFrame);
     1113        return JSC::Debugger::Client::debuggerScopeExtensionObject(debugger, globalObject, debuggerCallFrame);
    11121114
    11131115    auto* debuggerGlobalObject = debuggerCallFrame.scope()->globalObject();
  • trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.h

    r269023 r271373  
    9797
    9898    // JSC::Debugger::Client
    99     JSC::JSObject* scopeExtensionObject(JSC::Debugger&, JSC::JSGlobalObject*, JSC::DebuggerCallFrame&) final;
     99    JSC::JSObject* debuggerScopeExtensionObject(JSC::Debugger&, JSC::JSGlobalObject*, JSC::DebuggerCallFrame&) final;
    100100
    101101    // JSC::Debugger::Observer
  • trunk/Source/JavaScriptCore/inspector/protocol/Debugger.json

    r266534 r271373  
    4242                { "name": "type", "type": "string", "enum": ["log", "evaluate", "sound", "probe"], "description": "Different kinds of breakpoint actions." },
    4343                { "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)." },
    44                 { "name": "id", "$ref": "BreakpointActionIdentifier", "optional": true, "description": "A frontend-assigned identifier for this breakpoint action." }
     44                { "name": "id", "$ref": "BreakpointActionIdentifier", "optional": true, "description": "A frontend-assigned identifier for this breakpoint action." },
     45                { "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>." }
    4546            ]
    4647        },
  • trunk/Source/WebCore/ChangeLog

    r271368 r271373  
     12021-01-11  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Debugger: allow breakpoint actions to be evaluated as a user gesture
     4        https://bugs.webkit.org/show_bug.cgi?id=200275
     5
     6        Reviewed by Brian Burg.
     7
     8        Tests: inspector/debugger/breakpoint-action-emulateUserGesture.html
     9               inspector/debugger/breakpoint-action-emulateUserGesture-userIsInteracting.html
     10
     11        * inspector/agents/page/PageDebuggerAgent.cpp:
     12        * inspector/agents/page/PageDebuggerAgent.h:
     13        (WebCore::PageDebuggerAgent::debuggerWillEvaluate): Added.
     14        (WebCore::PageDebuggerAgent::debuggerDidEvaluate): Added.
     15        Maintain a stack of `UserGestureEmulationScope` whenever evaluating breakpoint actions (but
     16        only add/remove items if the current action is set to `emulateUserGesture`).
     17
     18        * inspector/agents/page/UserGestureEmulationScope.h:
     19        Make it fast allocated so it can be used with `UniqueRef`.
     20
    1212021-01-11  Sihui Liu  <sihui_liu@appe.com>
    222
  • trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.cpp

    r268700 r271373  
    121121}
    122122
     123void PageDebuggerAgent::debuggerWillEvaluate(JSC::Debugger&, const JSC::Breakpoint::Action& action)
     124{
     125    if (action.emulateUserGesture)
     126        m_breakpointActionUserGestureEmulationScopeStack.append(makeUniqueRef<UserGestureEmulationScope>(m_inspectedPage, true));
     127}
     128
     129void PageDebuggerAgent::debuggerDidEvaluate(JSC::Debugger&, const JSC::Breakpoint::Action& action)
     130{
     131    if (action.emulateUserGesture)
     132        m_breakpointActionUserGestureEmulationScopeStack.removeLast();
     133}
     134
    123135void PageDebuggerAgent::breakpointActionLog(JSC::JSGlobalObject* lexicalGlobalObject, const String& message)
    124136{
  • trunk/Source/WebCore/inspector/agents/page/PageDebuggerAgent.h

    r266885 r271373  
    4040class Frame;
    4141class Page;
     42class UserGestureEmulationScope;
    4243
    4344class PageDebuggerAgent final : public WebDebuggerAgent {
     
    5152    // DebuggerBackendDispatcherHandler
    5253    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);
     54
     55    // JSC::Debugger::Client
     56    void debuggerWillEvaluate(JSC::Debugger&, const JSC::Breakpoint::Action&);
     57    void debuggerDidEvaluate(JSC::Debugger&, const JSC::Breakpoint::Action&);
    5358
    5459    // JSC::Debugger::Observer
     
    7681
    7782    Page& m_inspectedPage;
     83    Vector<UniqueRef<UserGestureEmulationScope>> m_breakpointActionUserGestureEmulationScopeStack;
    7884};
    7985
  • trunk/Source/WebCore/inspector/agents/page/UserGestureEmulationScope.h

    r251620 r271373  
    4242class UserGestureEmulationScope {
    4343    WTF_MAKE_NONCOPYABLE(UserGestureEmulationScope);
     44    WTF_MAKE_FAST_ALLOCATED;
    4445public:
    4546    UserGestureEmulationScope(Page& inspectedPage, bool emulateUserGesture);
  • trunk/Source/WebInspectorUI/ChangeLog

    r271329 r271373  
     12021-01-11  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Debugger: allow breakpoint actions to be evaluated as a user gesture
     4        https://bugs.webkit.org/show_bug.cgi?id=200275
     5
     6        Reviewed by Brian Burg.
     7
     8        * UserInterface/Models/BreakpointAction.js:
     9        (WI.BreakpointAction.supportsEmulateUserAction): Added.
     10        (WI.BreakpointAction.fromJSON):
     11        (WI.BreakpointAction.prototype.toJSON):
     12        (WI.BreakpointAction.prototype.set type):
     13        (WI.BreakpointAction.prototype.set data):
     14        (WI.BreakpointAction.prototype.get emulateUserGesture): Added.
     15        (WI.BreakpointAction.prototype.set emulateUserGesture): Added.
     16        Add an `_emulateUserGesture` property to match `Debugger.BreakpointAction`.
     17
     18        * UserInterface/Views/BreakpointActionView.js:
     19        (WI.BreakpointActionView):
     20        (WI.BreakpointActionView.prototype._updateBody):
     21        (WI.BreakpointActionView.prototype._handleEmulateUserGestureCheckboxChange): Added.
     22        * UserInterface/Views/BreakpointActionView.css:
     23        (.breakpoint-action-block-body .description): Added.
     24        (.breakpoint-action-block-body > .flex):
     25        (.breakpoint-action-block-body > .description): Deleted.
     26        Add a "[ ] Emulate User Gesture" under the log/evaluate/probe input.
     27
     28        * UserInterface/Models/Breakpoint.js:
     29        (WI.Breakpoint):
     30        (WI.Breakpoint.prototype.addAction):
     31        (WI.Breakpoint.prototype.removeAction):
     32        (WI.Breakpoint.prototype._handleBreakpointActionModified): Renamed from `_handleBreakpointActionChanged`.
     33        Drive-by: combine `TypeChanged` and `DataChanged` into a single `Modified` event since all
     34        the listeners currently have the same callback.
     35
     36        * UserInterface/Views/LogContentView.js:
     37        (WI.LogContentView):
     38        (WI.LogContentView.prototype._handleEmulateInUserGestureSettingChanged):
     39        Drive-by: only show the "Emulate User Gesture" checkbox when it's supported.
     40
     41        * Localizations/en.lproj/localizedStrings.js:
     42
    1432021-01-08  Patrick Angle  <pangle@apple.com>
    244
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r271329 r271373  
    550550/* Category label for experimental settings pertaining to the Elements tab */
    551551localizedStrings["Elements Tab: @ Experimental Settings"] = "Elements Tab:";
    552 localizedStrings["Emulate User Gesture"] = "Emulate User Gesture";
     552/* Checkbox shown in the Console to cause future evaluations as though they are in response to user interaction. */
     553localizedStrings["Emulate User Gesture @ Console"] = "Emulate User Gesture";
     554/* Checkbox shown when configuring log/evaluate/probe breakpoint actions to cause it to be evaluated as though it was in response to user interaction. */
     555localizedStrings["Emulate User Gesture @ breakpoint action configuration"] = "Emulate User Gesture";
    553556localizedStrings["Enable Audit"] = "Enable Audit";
    554557localizedStrings["Enable Breakpoint"] = "Enable Breakpoint";
  • trunk/Source/WebInspectorUI/UserInterface/Models/Breakpoint.js

    r268885 r271373  
    4646        this._actions = actions || [];
    4747
    48         for (let action of this._actions) {
    49             action.addEventListener(WI.BreakpointAction.Event.DataChanged, this._handleBreakpointActionChanged, this);
    50             action.addEventListener(WI.BreakpointAction.Event.TypeChanged, this._handleBreakpointActionChanged, this);
    51         }
     48        for (let action of this._actions)
     49            action.addEventListener(WI.BreakpointAction.Event.Modified, this._handleBreakpointActionModified, this);
    5250    }
    5351
     
    226224        console.assert(action instanceof WI.BreakpointAction, action);
    227225
    228         action.addEventListener(WI.BreakpointAction.Event.DataChanged, this._handleBreakpointActionChanged, this);
    229         action.addEventListener(WI.BreakpointAction.Event.TypeChanged, this._handleBreakpointActionChanged, this);
     226        action.addEventListener(WI.BreakpointAction.Event.Modified, this._handleBreakpointActionModified, this);
    230227
    231228        if (!precedingAction)
     
    255252        this._actions.splice(index, 1);
    256253
    257         action.removeEventListener(WI.BreakpointAction.Event.DataChanged, this._handleBreakpointActionChanged, this);
    258         action.removeEventListener(WI.BreakpointAction.Event.TypeChanged, this._handleBreakpointActionChanged, this);
     254        action.removeEventListener(WI.BreakpointAction.Event.Modified, this._handleBreakpointActionModified, this);
    259255
    260256        if (!this._actions.length)
     
    340336    // Private
    341337
    342     _handleBreakpointActionChanged(event)
     338    _handleBreakpointActionModified(event)
    343339    {
    344340        console.assert(this.editable, this);
  • trunk/Source/WebInspectorUI/UserInterface/Models/BreakpointAction.js

    r266480 r271373  
    2626WI.BreakpointAction = class BreakpointAction extends WI.Object
    2727{
    28     constructor(type, {data} = {})
     28    constructor(type, {data, emulateUserGesture} = {})
    2929    {
    3030        console.assert(Object.values(WI.BreakpointAction.Type).includes(type), type);
     
    3636        this._data = data || null;
    3737        this._id = WI.debuggerManager.nextBreakpointActionIdentifier();
     38        this._emulateUserGesture = !!emulateUserGesture;
     39    }
     40
     41    // Static
     42
     43    static supportsEmulateUserAction()
     44    {
     45        // COMPATIBILITY (iOS 14): the `emulateUserGesture` property of `Debugger.BreakpointAction` did not exist yet.
     46        // Since support can't be tested directly, check for the `options` parameter of `Debugger.setPauseOnExceptions`.
     47        // FIXME: Use explicit version checking once <https://webkit.org/b/148680> is fixed.
     48        return WI.sharedApp.isWebDebuggable() && InspectorBackend.hasCommand("Debugger.setPauseOnExceptions", "options");
    3849    }
    3950
     
    4455        return new WI.BreakpointAction(json.type, {
    4556            data: json.data,
     57            emulateUserGesture: json.emulateUserGesture,
    4658        });
    4759    }
     
    5466        if (this._data)
    5567            json.data = this._data;
     68        if (this._emulateUserGesture)
     69            json.emulateUserGesture = this._emulateUserGesture;
    5670        return json;
    5771    }
     
    7589        this._type = type;
    7690
    77         this.dispatchEventToListeners(WI.BreakpointAction.Event.TypeChanged);
     91        this.dispatchEventToListeners(WI.BreakpointAction.Event.Modified);
    7892    }
    7993
     
    92106        this._data = data;
    93107
    94         this.dispatchEventToListeners(WI.BreakpointAction.Event.DataChanged);
     108        this.dispatchEventToListeners(WI.BreakpointAction.Event.Modified);
     109    }
     110
     111    get emulateUserGesture()
     112    {
     113        return this._emulateUserGesture;
     114    }
     115
     116    set emulateUserGesture(emulateUserGesture)
     117    {
     118        if (this._emulateUserGesture === emulateUserGesture)
     119            return;
     120
     121        this._emulateUserGesture = emulateUserGesture;
     122
     123        this.dispatchEventToListeners(WI.BreakpointAction.Event.Modified);
    95124    }
    96125
     
    111140
    112141WI.BreakpointAction.Event = {
    113     DataChanged: "breakpoint-action-data-changed",
    114     TypeChanged: "breakpoint-action-type-changed",
     142    Modified: "breakpoint-action-modified",
    115143};
  • trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.css

    r269166 r271373  
    6565}
    6666
    67 .breakpoint-action-block-body > .description {
    68     margin-top: 6px;
    69     margin-inline-end: 2px;
     67.breakpoint-action-block-body .description {
     68    flex-grow: 1;
    7069    text-align: right;
    7170    color: var(--text-color-gray-medium);
     
    7574    width: 100%;
    7675    text-align: left;
     76}
     77
     78.breakpoint-action-block-body > .flex {
     79    display: flex;
     80    align-items: center;
     81    flex-wrap: wrap;
    7782}
    7883
  • trunk/Source/WebInspectorUI/UserInterface/Views/BreakpointActionView.js

    r269023 r271373  
    127127        this._bodyElement.removeChildren();
    128128
     129        let createOptionsElements = () => {
     130            let optionsElement = document.createElement("div");
     131
     132            let emulateUserGestureLabel = optionsElement.appendChild(document.createElement("label"));
     133
     134            this._emulateUserGestureCheckbox = emulateUserGestureLabel.appendChild(document.createElement("input"));
     135            this._emulateUserGestureCheckbox.type = "checkbox";
     136            this._emulateUserGestureCheckbox.checked = this._action.emulateUserGesture;
     137            this._emulateUserGestureCheckbox.addEventListener("change", this._handleEmulateUserGestureCheckboxChange.bind(this));
     138
     139            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.")));
     140
     141            return optionsElement;
     142        };
     143
    129144        switch (this._action.type) {
    130145        case WI.BreakpointAction.Type.Log:
     
    139154                setTimeout(function() { input.focus(); }, 0);
    140155
    141             var descriptionElement = this._bodyElement.appendChild(document.createElement("div"));
     156            var flexWrapper = this._bodyElement.appendChild(document.createElement("div"));
     157            flexWrapper.className = "flex";
     158
     159            if (WI.BreakpointAction.supportsEmulateUserAction())
     160                flexWrapper.appendChild(createOptionsElements());
     161
     162            var descriptionElement = flexWrapper.appendChild(document.createElement("div"));
    142163            descriptionElement.classList.add("description");
    143164            descriptionElement.setAttribute("dir", "ltr");
     
    168189            completionController.addExtendedCompletionProvider("javascript", WI.javaScriptRuntimeCompletionProvider);
    169190
     191            if (WI.BreakpointAction.supportsEmulateUserAction())
     192                this._bodyElement.appendChild(createOptionsElements());
     193
    170194            // CodeMirror needs a refresh after the popover displays to layout otherwise it doesn't appear.
    171195            setTimeout(() => {
     
    208232        this._delegate.breakpointActionViewResized(this);
    209233    }
     234
     235    _handleEmulateUserGestureCheckboxChange(event)
     236    {
     237        this._action.emulateUserGesture = this._emulateUserGestureCheckbox.checked;
     238    }
    210239};
  • trunk/Source/WebInspectorUI/UserInterface/Views/LogContentView.js

    r270134 r271373  
    7878        WI.settings.clearLogOnNavigate.addEventListener(WI.Setting.Event.Changed, this._handleClearLogOnNavigateSettingChanged, this);
    7979
    80         this._emulateInUserGestureNavigationItem = new WI.CheckboxNavigationItem("emulate-in-user-gesture", WI.UIString("Emulate User Gesture"), WI.settings.emulateInUserGesture.value);
    81         this._emulateInUserGestureNavigationItem.tooltip = WI.UIString("Run console commands as if inside a user gesture");
    82         this._emulateInUserGestureNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, function(event) {
    83             WI.settings.emulateInUserGesture.value = !WI.settings.emulateInUserGesture.value;
    84         }, this);
    85         WI.settings.emulateInUserGesture.addEventListener(WI.Setting.Event.Changed, this._handleEmulateInUserGestureSettingChanged, this);
    86 
    87         this._checkboxesNavigationItemGroup = new WI.GroupNavigationItem([this._preserveLogNavigationItem, this._emulateInUserGestureNavigationItem, new WI.DividerNavigationItem]);
     80        let checkboxesNavigationItems = [this._preserveLogNavigationItem];
     81
     82        // COMPATIBILITY (iOS 13): `Runtime.evaluate` did not have a `emulateUserGesture` parameter yet.
     83        if (WI.sharedApp.isWebDebuggable() && InspectorBackend.hasCommand("Runtime.evaluate", "emulateUserGesture")) {
     84            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);
     85            this._emulateUserGestureNavigationItem.tooltip = WI.UIString("Run console commands as if inside a user gesture");
     86            this._emulateUserGestureNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, function(event) {
     87                WI.settings.emulateInUserGesture.value = !WI.settings.emulateInUserGesture.value;
     88            }, this);
     89            WI.settings.emulateInUserGesture.addEventListener(WI.Setting.Event.Changed, this._handleEmulateInUserGestureSettingChanged, this);
     90            checkboxesNavigationItems.push(this._emulateUserGestureNavigationItem);
     91        }
     92
     93        checkboxesNavigationItems.push(new WI.DividerNavigationItem);
     94        this._checkboxesNavigationItemGroup = new WI.GroupNavigationItem(checkboxesNavigationItems);
    8895
    8996        let scopeBarItems = [
     
    907914    _handleEmulateInUserGestureSettingChanged()
    908915    {
    909         this._emulateInUserGestureNavigationItem.checked = WI.settings.emulateInUserGesture.value;
     916        this._emulateUserGestureNavigationItem.checked = WI.settings.emulateInUserGesture.value;
    910917    }
    911918
Note: See TracChangeset for help on using the changeset viewer.