Changeset 286412 in webkit


Ignore:
Timestamp:
Dec 1, 2021 9:03:13 PM (8 months ago)
Author:
Patrick Angle
Message:

Web Inspector: Console execution context can become an unexpected selection on refresh/navigation
https://bugs.webkit.org/show_bug.cgi?id=233349

Reviewed by Devin Rousso.

There are really three bugs here in WI.QuickConsole.prototype._handleFrameExecutionContextsCleared, each of
which contribute to unexpected execution context selections.

  1. If the frame of the active execution context commits a provisional load, our code attempts to re-select the

new context for that frame, which results in clearing the Auto bit for selected context, which means the
context no longer will follow the selected DOM node. This is resolved by no longer following a frame's execution
context on navigation if the current selection is Auto (tracked by the _useExecutionContextOfInspectedNode
variable).

  1. Because of the very short timeframe for the above to take place before bailing (previously 10ms) there are

many situations where other large payloads over the protocol, like a complex DOM tree, will cause the timeout to
fire before we receive an event telling us there is a new execution context for the frame, which means we end up
not following the frame anyways. This is improved by increasing the timeout to a still-brisk, but more
reasonable 100ms.

  1. The timeout in (2) can lead to us having a selected execution context that may no longer be valid because the

fail-safe in QuickConsole.prototype._handleFrameExecutionContextsCleared doesn't really fail safely, since it
doesn't provide a new execution context to be active and instead seems to rely on the hope that the context will
still work for future invocations, which I believe is how many users are getting into the state of a blank
execution context picker (with a working drop down menu with actual contexts that are selectable) and are unable
to evaluate anything in the console until re-selecting an execution context.

Additional drive-by change to move the checks for whether or not we can use the execution context of a selected
node into its own method.

  • UserInterface/Views/QuickConsole.js:

(WI.QuickConsole.prototype._populateActiveExecutionContextNavigationItemContextMenu):
(WI.QuickConsole.prototype._handleEngineeringShowInternalExecutionContextsSettingChanged):
(WI.QuickConsole.prototype._handleFrameExecutionContextsCleared):
(WI.QuickConsole.prototype._handleTargetRemoved):
(WI.QuickConsole.prototype._canUseExecutionContextOfInspectedNode):

Location:
trunk/Source/WebInspectorUI
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r286329 r286412  
     12021-12-01  Patrick Angle  <pangle@apple.com>
     2
     3        Web Inspector: Console execution context can become an unexpected selection on refresh/navigation
     4        https://bugs.webkit.org/show_bug.cgi?id=233349
     5
     6        Reviewed by Devin Rousso.
     7
     8        There are really three bugs here in `WI.QuickConsole.prototype._handleFrameExecutionContextsCleared`, each of
     9        which contribute to unexpected execution context selections.
     10
     11        1. If the frame of the active execution context commits a provisional load, our code attempts to re-select the
     12        new context for that frame, which results in clearing the `Auto` bit for selected context, which means the
     13        context no longer will follow the selected DOM node. This is resolved by no longer following a frame's execution
     14        context on navigation if the current selection is `Auto` (tracked by the `_useExecutionContextOfInspectedNode`
     15        variable).
     16
     17        2. Because of the very short timeframe for the above to take place before bailing (previously 10ms) there are
     18        many situations where other large payloads over the protocol, like a complex DOM tree, will cause the timeout to
     19        fire before we receive an event telling us there is a new execution context for the frame, which means we end up
     20        not following the frame anyways. This is improved by increasing the timeout to a still-brisk, but more
     21        reasonable 100ms.
     22
     23        3. The timeout in (2) can lead to us having a selected execution context that may no longer be valid because the
     24        fail-safe in `QuickConsole.prototype._handleFrameExecutionContextsCleared` doesn't really fail safely, since it
     25        doesn't provide a new execution context to be active and instead seems to rely on the hope that the context will
     26        still work for future invocations, which I believe is how many users are getting into the state of a blank
     27        execution context picker (with a working drop down menu with actual contexts that are selectable) and are unable
     28        to evaluate anything in the console until re-selecting an execution context.
     29
     30        Additional drive-by change to move the checks for whether or not we can use the execution context of a selected
     31        node into its own method.
     32
     33        * UserInterface/Views/QuickConsole.js:
     34        (WI.QuickConsole.prototype._populateActiveExecutionContextNavigationItemContextMenu):
     35        (WI.QuickConsole.prototype._handleEngineeringShowInternalExecutionContextsSettingChanged):
     36        (WI.QuickConsole.prototype._handleFrameExecutionContextsCleared):
     37        (WI.QuickConsole.prototype._handleTargetRemoved):
     38        (WI.QuickConsole.prototype._canUseExecutionContextOfInspectedNode):
     39
    1402021-11-30  BJ Burg  <bburg@apple.com>
    241
  • trunk/Source/WebInspectorUI/UserInterface/Views/QuickConsole.js

    r280989 r286412  
    3434        this._keyboardShortcutDisabled = false;
    3535
    36         this._useExecutionContextOfInspectedNode = InspectorBackend.hasDomain("DOM");
     36        this._useExecutionContextOfInspectedNode = this._canUseExecutionContextOfInspectedNode();
    3737        this._restoreSelectedExecutionContextForFrame = null;
    3838
     
    244244        let activeExecutionContext = WI.runtimeManager.activeExecutionContext;
    245245
    246         if (InspectorBackend.hasDomain("DOM")) {
     246        if (this._canUseExecutionContextOfInspectedNode()) {
    247247            let executionContextForInspectedNode = this._resolveDesiredActiveExecutionContext(true);
    248248            contextMenu.appendCheckboxItem(WI.UIString("Auto \u2014 %s").format(this._displayNameForExecutionContext(executionContextForInspectedNode, maxLength)), () => {
     
    357357            return;
    358358
    359         this._useExecutionContextOfInspectedNode = InspectorBackend.hasDomain("DOM");
     359        this._useExecutionContextOfInspectedNode = this._canUseExecutionContextOfInspectedNode();
    360360        this._setActiveExecutionContext(this._resolveDesiredActiveExecutionContext());
    361361    }
     
    389389        }
    390390
    391         // If this frame is navigating and it is selected in the UI we want to reselect its new item after navigation.
    392         if (committingProvisionalLoad && !this._restoreSelectedExecutionContextForFrame) {
     391        // If this frame is navigating and it is selected in the UI we want to reselect its new item after navigation,
     392        // however when `_useExecutionContextOfInspectedNode` is true, we should keep the execution context set to `Auto`.
     393        if (committingProvisionalLoad && !this._restoreSelectedExecutionContextForFrame && !this._useExecutionContextOfInspectedNode) {
    393394            this._restoreSelectedExecutionContextForFrame = event.target;
    394395
    395396            // As a fail safe, if the frame never gets an execution context, clear the restore value.
    396397            setTimeout(() => {
    397                 if (this._restoreSelectedExecutionContextForFrame)
    398                     this._updateActiveExecutionContextDisplay();
     398                if (!this._restoreSelectedExecutionContextForFrame)
     399                    return;
    399400                this._restoreSelectedExecutionContextForFrame = null;
    400             }, 10);
    401             return;
    402         }
    403 
    404         this._useExecutionContextOfInspectedNode = InspectorBackend.hasDomain("DOM");
     401
     402                this._useExecutionContextOfInspectedNode = this._canUseExecutionContextOfInspectedNode();
     403                this._setActiveExecutionContext(this._resolveDesiredActiveExecutionContext());
     404            }, 100);
     405            return;
     406        }
     407
     408        this._useExecutionContextOfInspectedNode = this._canUseExecutionContextOfInspectedNode();
    405409        this._setActiveExecutionContext(this._resolveDesiredActiveExecutionContext());
    406410    }
     
    429433        }
    430434
    431         this._useExecutionContextOfInspectedNode = InspectorBackend.hasDomain("DOM");
     435        this._useExecutionContextOfInspectedNode = this._canUseExecutionContextOfInspectedNode();
    432436        this._setActiveExecutionContext(this._resolveDesiredActiveExecutionContext());
    433437    }
     
    439443
    440444        this._setActiveExecutionContext(this._resolveDesiredActiveExecutionContext());
     445    }
     446
     447    _canUseExecutionContextOfInspectedNode()
     448    {
     449        return InspectorBackend.hasDomain("DOM");
    441450    }
    442451
Note: See TracChangeset for help on using the changeset viewer.