Title: [156923] trunk/Source/WebInspectorUI
Revision
156923
Author
[email protected]
Date
2013-10-04 16:01:50 -0700 (Fri, 04 Oct 2013)

Log Message

Web Inspector: pressing the Cmd key over a CSS property should underline it immediately (jump to definition mode)
https://bugs.webkit.org/show_bug.cgi?id=119012

Reviewed by Joseph Pecoraro.

We add an "enabled" state to the tokenTrackingController to indicate that we're interested
in tracking hovered tokens. The tokenTrackingController is now only enabled in the
CSSStyleDeclarationTextEditor when the Cmd key is pressed and in the SourceCodeTextEditor
when either the Cmd key is pressed (NonSymbolTokens mode) or when the debugger is paused
(_javascript_Expression mode).

The tokenTrackingController is now smarter about how it tracks mouse events when it's enabled,
tracking "mouseenter" and "mouseleave" events to enable tracking allowing immediate detection of
tokens being hovered or no longer being hovered even with quick mouse movements. Additioanlly,
using the new top-level mouse coordinates tracking, we can detect a hovered token as soon as
it's being enabled to provide instant feedback to the user.

This new top-level mouse coordinates tracking couple with tracking of modifier keys also fixes
http://webkit.org/b/119011.

* UserInterface/CSSStyleDeclarationTextEditor.js:
(WebInspector.CSSStyleDeclarationTextEditor.prototype._updateJumpToSymbolTrackingMode):
Highlight the last known hovered candidate's range as soon as the Cmd key is pressed and enable
the tokenTrackingController if we're dealing with a non-read-only editor. When the Cmd key is
released, disable the tokenTrackingController.

* UserInterface/CodeMirrorTokenTrackingController.js:
(WebInspector.CodeMirrorTokenTrackingController):
(WebInspector.CodeMirrorTokenTrackingController.prototype.get enabled):
(WebInspector.CodeMirrorTokenTrackingController.prototype.set enabled):
New enabled state for the tokenTrackingController which indicates whether it should be tracking
mouse events to track hovered tokens in the editor. Upon being enabled, the tokenTrackingController
looks up the mouse coordinates continuously tracked at the window level to check for a token
at the last known mouse coordinates in case we're already over a token that may be highlighted.

(WebInspector.CodeMirrorTokenTrackingController.prototype.highlightLastHoveredRange):
New public method allowing to highlight the last know candidate range, if any. This is used from
editor code when the Cmd key is pressed and we want to force the last know candidate to be
highlighted.

(WebInspector.CodeMirrorTokenTrackingController.prototype._startTracking):
(WebInspector.CodeMirrorTokenTrackingController.prototype._stopTracking):
Make these two methods private now that they're automatically called by the "mouseenter" and
"mouseleave" event handling when we're in the "enabled" state. Additionally, the public
"tracking" property has been removed since it is no longer useful to the developer.

(WebInspector.CodeMirrorTokenTrackingController.prototype.handleEvent):
(WebInspector.CodeMirrorTokenTrackingController.prototype._mouseEntered):
(WebInspector.CodeMirrorTokenTrackingController.prototype._mouseLeft):
New handlers for the "mouseenter" and "mouseleave" events enabling tracking of hovered tokens.

(WebInspector.CodeMirrorTokenTrackingController.prototype._mouseMovedOverEditor):
(WebInspector.CodeMirrorTokenTrackingController.prototype._updateHoveredTokenInfo):
Refactor _mouseMovedOverEditor() into two methods with the new _updateHoveredTokenInfo()
allowing to customize the mouse coordinates to be used since we may call
_updateHoveredTokenInfo() outside of the context of a mouse event (ie. a keypress event).

(WebInspector.CodeMirrorTokenTrackingController.prototype._windowLostFocus):
(WebInspector.CodeMirrorTokenTrackingController.prototype._resetTrackingStates):
New private method combining all the various states that need to be reset when tracking
is turned off, including the removal of the highlighted range if any. This is now called
when the window loses focus.

* UserInterface/Main.js:
(WebInspector.loaded):
(WebInspector._mouseMoved):
Add a new window-level "mousemove" event handler to always track mouse coordinates and key modifier
states. This ensures that we may have the most accurate information possible for key modifiers and
allow code to query the last recorded mouse position in situations where it wouldn't be possible
to have dealt with a mouse event, as is the case when the tokenTrackingController just started tracking.

* UserInterface/SourceCodeTextEditor.js:
(WebInspector.SourceCodeTextEditor.prototype._updateTokenTrackingControllerEnabled):
(WebInspector.SourceCodeTextEditor.prototype._debuggerDidPause):
(WebInspector.SourceCodeTextEditor.prototype._debuggerDidResume):
(WebInspector.SourceCodeTextEditor.prototype._enableJumpToSymbolTrackingModeSettings):
(WebInspector.SourceCodeTextEditor.prototype._disableJumpToSymbolTrackingModeSettings):
Update the "enabled" state on the tokenTrackingController when it may have changed based
on those two conditions: we should have either an active debugger call frame or the
Cmd key should have been pressed. This ensures we only track hovered tokens as needed.

(WebInspector.SourceCodeTextEditor.prototype._updateJumpToSymbolTrackingMode):
Highlight the last known hovered candidate's range as soon as the Cmd key is pressed.

Modified Paths

Diff

Modified: trunk/Source/WebInspectorUI/ChangeLog (156922 => 156923)


--- trunk/Source/WebInspectorUI/ChangeLog	2013-10-04 22:49:40 UTC (rev 156922)
+++ trunk/Source/WebInspectorUI/ChangeLog	2013-10-04 23:01:50 UTC (rev 156923)
@@ -1,3 +1,89 @@
+2013-10-04  Antoine Quint  <[email protected]>
+
+        Web Inspector: pressing the Cmd key over a CSS property should underline it immediately (jump to definition mode)
+        https://bugs.webkit.org/show_bug.cgi?id=119012
+
+        Reviewed by Joseph Pecoraro.
+
+        We add an "enabled" state to the tokenTrackingController to indicate that we're interested
+        in tracking hovered tokens. The tokenTrackingController is now only enabled in the
+        CSSStyleDeclarationTextEditor when the Cmd key is pressed and in the SourceCodeTextEditor
+        when either the Cmd key is pressed (NonSymbolTokens mode) or when the debugger is paused
+        (_javascript_Expression mode).
+        
+        The tokenTrackingController is now smarter about how it tracks mouse events when it's enabled,
+        tracking "mouseenter" and "mouseleave" events to enable tracking allowing immediate detection of
+        tokens being hovered or no longer being hovered even with quick mouse movements. Additioanlly,
+        using the new top-level mouse coordinates tracking, we can detect a hovered token as soon as
+        it's being enabled to provide instant feedback to the user.
+
+        This new top-level mouse coordinates tracking couple with tracking of modifier keys also fixes
+        http://webkit.org/b/119011.
+
+        * UserInterface/CSSStyleDeclarationTextEditor.js:
+        (WebInspector.CSSStyleDeclarationTextEditor.prototype._updateJumpToSymbolTrackingMode):
+        Highlight the last known hovered candidate's range as soon as the Cmd key is pressed and enable
+        the tokenTrackingController if we're dealing with a non-read-only editor. When the Cmd key is
+        released, disable the tokenTrackingController.
+
+        * UserInterface/CodeMirrorTokenTrackingController.js:
+        (WebInspector.CodeMirrorTokenTrackingController):
+        (WebInspector.CodeMirrorTokenTrackingController.prototype.get enabled):
+        (WebInspector.CodeMirrorTokenTrackingController.prototype.set enabled):
+        New enabled state for the tokenTrackingController which indicates whether it should be tracking
+        mouse events to track hovered tokens in the editor. Upon being enabled, the tokenTrackingController
+        looks up the mouse coordinates continuously tracked at the window level to check for a token
+        at the last known mouse coordinates in case we're already over a token that may be highlighted.
+
+        (WebInspector.CodeMirrorTokenTrackingController.prototype.highlightLastHoveredRange):
+        New public method allowing to highlight the last know candidate range, if any. This is used from
+        editor code when the Cmd key is pressed and we want to force the last know candidate to be
+        highlighted.
+
+        (WebInspector.CodeMirrorTokenTrackingController.prototype._startTracking):
+        (WebInspector.CodeMirrorTokenTrackingController.prototype._stopTracking):
+        Make these two methods private now that they're automatically called by the "mouseenter" and
+        "mouseleave" event handling when we're in the "enabled" state. Additionally, the public
+        "tracking" property has been removed since it is no longer useful to the developer.
+
+        (WebInspector.CodeMirrorTokenTrackingController.prototype.handleEvent):
+        (WebInspector.CodeMirrorTokenTrackingController.prototype._mouseEntered):
+        (WebInspector.CodeMirrorTokenTrackingController.prototype._mouseLeft):
+        New handlers for the "mouseenter" and "mouseleave" events enabling tracking of hovered tokens.
+
+        (WebInspector.CodeMirrorTokenTrackingController.prototype._mouseMovedOverEditor):
+        (WebInspector.CodeMirrorTokenTrackingController.prototype._updateHoveredTokenInfo):
+        Refactor _mouseMovedOverEditor() into two methods with the new _updateHoveredTokenInfo()
+        allowing to customize the mouse coordinates to be used since we may call
+        _updateHoveredTokenInfo() outside of the context of a mouse event (ie. a keypress event).
+
+        (WebInspector.CodeMirrorTokenTrackingController.prototype._windowLostFocus):
+        (WebInspector.CodeMirrorTokenTrackingController.prototype._resetTrackingStates):
+        New private method combining all the various states that need to be reset when tracking
+        is turned off, including the removal of the highlighted range if any. This is now called
+        when the window loses focus.
+
+        * UserInterface/Main.js:
+        (WebInspector.loaded):
+        (WebInspector._mouseMoved):
+        Add a new window-level "mousemove" event handler to always track mouse coordinates and key modifier
+        states. This ensures that we may have the most accurate information possible for key modifiers and
+        allow code to query the last recorded mouse position in situations where it wouldn't be possible
+        to have dealt with a mouse event, as is the case when the tokenTrackingController just started tracking.
+
+        * UserInterface/SourceCodeTextEditor.js:
+        (WebInspector.SourceCodeTextEditor.prototype._updateTokenTrackingControllerEnabled):
+        (WebInspector.SourceCodeTextEditor.prototype._debuggerDidPause):
+        (WebInspector.SourceCodeTextEditor.prototype._debuggerDidResume):
+        (WebInspector.SourceCodeTextEditor.prototype._enableJumpToSymbolTrackingModeSettings):
+        (WebInspector.SourceCodeTextEditor.prototype._disableJumpToSymbolTrackingModeSettings):
+        Update the "enabled" state on the tokenTrackingController when it may have changed based
+        on those two conditions: we should have either an active debugger call frame or the
+        Cmd key should have been pressed. This ensures we only track hovered tokens as needed.
+
+        (WebInspector.SourceCodeTextEditor.prototype._updateJumpToSymbolTrackingMode):
+        Highlight the last known hovered candidate's range as soon as the Cmd key is pressed.
+
 2013-10-02  Brian J. Burg  <[email protected]>
 
         Web Inspector: save and restore source positions in back/forward history

Modified: trunk/Source/WebInspectorUI/UserInterface/CSSStyleDeclarationTextEditor.js (156922 => 156923)


--- trunk/Source/WebInspectorUI/UserInterface/CSSStyleDeclarationTextEditor.js	2013-10-04 22:49:40 UTC (rev 156922)
+++ trunk/Source/WebInspectorUI/UserInterface/CSSStyleDeclarationTextEditor.js	2013-10-04 23:01:50 UTC (rev 156923)
@@ -1002,11 +1002,12 @@
             this._jumpToSymbolTrackingModeEnabled = WebInspector.modifierKeys.metaKey && !WebInspector.modifierKeys.altKey && !WebInspector.modifierKeys.shiftKey;
 
         if (oldJumpToSymbolTrackingModeEnabled !== this._jumpToSymbolTrackingModeEnabled) {
-            if (this._jumpToSymbolTrackingModeEnabled)
-                this._tokenTrackingController.startTracking();
-            else {
-                this._tokenTrackingController.stopTracking();
+            if (this._jumpToSymbolTrackingModeEnabled) {
+                this._tokenTrackingController.highlightLastHoveredRange();
+                this._tokenTrackingController.enabled = !this._codeMirror.getOption("readOnly");
+            } else {
                 this._tokenTrackingController.removeHighlightedRange();
+                this._tokenTrackingController.enabled = false;
             }
         }
     },

Modified: trunk/Source/WebInspectorUI/UserInterface/CodeMirrorTokenTrackingController.js (156922 => 156923)


--- trunk/Source/WebInspectorUI/UserInterface/CodeMirrorTokenTrackingController.js	2013-10-04 22:49:40 UTC (rev 156922)
+++ trunk/Source/WebInspectorUI/UserInterface/CodeMirrorTokenTrackingController.js	2013-10-04 23:01:50 UTC (rev 156923)
@@ -37,6 +37,7 @@
     this._mouseOutReleaseDelayDuration = 0;
     this._classNameForHighlightedRange = null;
 
+    this._enabled = false;
     this._tracking = false;
     this._hoveredTokenInfo = null;
 };
@@ -63,6 +64,31 @@
         this._delegate = x;
     },
 
+    get enabled()
+    {
+        return this._enabled;
+    },
+
+    set enabled(enabled)
+    {
+        if (this._enabled === enabled)
+            return;
+
+        this._enabled = enabled;
+
+        var wrapper = this._codeMirror.getWrapperElement();
+        if (enabled) {
+            wrapper.addEventListener("mouseenter", this);
+            wrapper.addEventListener("mouseleave", this);
+            this._updateHoveredTokenInfo({left: WebInspector.mouseCoords.x, top: WebInspector.mouseCoords.y});
+            this._startTracking();
+        } else {
+            wrapper.removeEventListener("mouseenter", this);
+            wrapper.removeEventListener("mouseleave", this);
+            this._stopTracking();
+        }
+    },
+
     get mode()
     {
         return this._mode;
@@ -110,53 +136,17 @@
         this._classNameForHighlightedRange = x || null;
     },
 
-    get tracking()
-    {
-        return this._tracking;
-    },
-
     get candidate()
     {
         return this._candidate;
     },
 
-    startTracking: function()
+    highlightLastHoveredRange: function()
     {
-        console.assert(!this._tracking);
-        if (this._tracking)
-            return;
-
-        this._tracking = true;
-
-        var wrapper = this._codeMirror.getWrapperElement();
-        wrapper.addEventListener("mousemove", this, true);
-        wrapper.addEventListener("mouseout", this, false);
-        wrapper.addEventListener("mousedown", this, false);
-        wrapper.addEventListener("mouseup", this, false);
-        window.addEventListener("blur", this, true);
+        if (this._candidate)
+            this.highlightRange(this._candidate.hoveredTokenRange);
     },
 
-    stopTracking: function()
-    {
-        console.assert(this._tracking);
-        if (!this._tracking)
-            return;
-
-        this._tracking = false;
-
-        var wrapper = this._codeMirror.getWrapperElement();
-        wrapper.removeEventListener("mousemove", this, true);
-        wrapper.removeEventListener("mouseout", this, false);
-        wrapper.removeEventListener("mousedown", this, false);
-        wrapper.removeEventListener("mouseup", this, false);
-        window.removeEventListener("blur", this, true);
-        window.removeEventListener("mousemove", this, true);
-
-        clearTimeout(this._tokenHoverTimer);
-        delete this._selectionMayBeInProgress;
-        delete this._hoveredTokenInfo;
-    },
-
     highlightRange: function(range)
     {
         // Nothing to do if we're trying to highlight the same range.
@@ -195,9 +185,51 @@
 
     // Private
 
+    _startTracking: function()
+    {
+        console.assert(!this._tracking);
+        if (this._tracking)
+            return;
+
+        this._tracking = true;
+
+        var wrapper = this._codeMirror.getWrapperElement();
+        wrapper.addEventListener("mousemove", this, true);
+        wrapper.addEventListener("mouseout", this, false);
+        wrapper.addEventListener("mousedown", this, false);
+        wrapper.addEventListener("mouseup", this, false);
+        window.addEventListener("blur", this, true);
+    },
+
+    _stopTracking: function()
+    {
+        console.assert(this._tracking);
+        if (!this._tracking)
+            return;
+
+        this._tracking = false;
+        this._candidate = null;
+
+        var wrapper = this._codeMirror.getWrapperElement();
+        wrapper.removeEventListener("mousemove", this, true);
+        wrapper.removeEventListener("mouseout", this, false);
+        wrapper.removeEventListener("mousedown", this, false);
+        wrapper.removeEventListener("mouseup", this, false);
+        window.removeEventListener("blur", this, true);
+        window.removeEventListener("mousemove", this, true);
+
+        this._resetTrackingStates();
+    },
+
     handleEvent: function(event)
     {
         switch (event.type) {
+        case "mouseenter":
+            this._mouseEntered(event);
+            break;
+        case "mouseleave":
+            this._mouseLeft(event);
+            break;
         case "mousemove":
             if (event.currentTarget === window)
                 this._mouseMovedWithMarkedText(event);
@@ -221,6 +253,16 @@
         }
     },
 
+    _mouseEntered: function(event)
+    {
+        this._startTracking();
+    },
+
+    _mouseLeft: function(event)
+    {
+        this._stopTracking();
+    },
+
     _mouseMovedWithMarkedText: function(event)
     {
         var shouldRelease = !event.target.classList.contains(this._classNameForHighlightedRange);
@@ -246,13 +288,17 @@
 
     _mouseMovedOverEditor: function(event)
     {
+        this._updateHoveredTokenInfo({left: event.pageX, top: event.pageY});
+    },
+
+    _updateHoveredTokenInfo: function(mouseCoords)
+    {
         // Get the position in the text and the token at that position.
-        var position = this._codeMirror.coordsChar({left: event.pageX, top: event.pageY});
+        var position = this._codeMirror.coordsChar(mouseCoords);
         var token = this._codeMirror.getTokenAt(position);
 
         if (!token || !token.type || !token.string) {
-            clearTimeout(this._tokenHoverTimer);
-            delete this._hoveredTokenInfo;
+            this._resetTrackingStates();
             return;
         }
 
@@ -315,7 +361,7 @@
 
     _windowLostFocus: function(event)
     {
-        delete this._selectionMayBeInProgress;
+        this._resetTrackingStates();
     },
 
     _processNewHoveredToken: function()
@@ -430,6 +476,14 @@
             _expression_: _expression_,
             expressionRange: {start: expressionStartPosition, end: endPosition},
         };
+    },
+
+    _resetTrackingStates: function()
+    {
+        clearTimeout(this._tokenHoverTimer);
+        delete this._selectionMayBeInProgress;
+        delete this._hoveredTokenInfo;
+        this.removeHighlightedRange();
     }
 };
 

Modified: trunk/Source/WebInspectorUI/UserInterface/Main.js (156922 => 156923)


--- trunk/Source/WebInspectorUI/UserInterface/Main.js	2013-10-04 22:49:40 UTC (rev 156922)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.js	2013-10-04 23:01:50 UTC (rev 156923)
@@ -107,6 +107,7 @@
     window.addEventListener("resize", this._windowResized.bind(this));
     window.addEventListener("keydown", this._windowKeyDown.bind(this));
     window.addEventListener("keyup", this._windowKeyUp.bind(this));
+    window.addEventListener("mousemove", this._mouseMoved.bind(this), true);
 
     // Create settings.
     this._lastSelectedNavigationSidebarPanelSetting = new WebInspector.Setting("last-selected-navigation-sidebar-panel", "resource");
@@ -135,6 +136,11 @@
     this._dockButtonToggledSetting = new WebInspector.Setting("dock-button-toggled", false);
 
     this.showShadowDOMSetting = new WebInspector.Setting("show-shadow-dom", false);
+
+    this.mouseCoords = {
+        x: 0,
+        y: 0
+    };
 }
 
 WebInspector.contentLoaded = function()
@@ -805,6 +811,15 @@
     this.undockButtonNavigationItem.toggled = (event.altKey && !event.metaKey && !event.shiftKey) ? opposite : !opposite;
 }
 
+WebInspector._mouseMoved = function(event)
+{
+    this._updateModifierKeys(event);
+    this.mouseCoords = {
+        x: event.pageX,
+        y: event.pageY
+    };
+}
+
 WebInspector._undock = function(event)
 {
     this._dockButtonToggledSetting.value = this.undockButtonNavigationItem.toggled;

Modified: trunk/Source/WebInspectorUI/UserInterface/SourceCodeTextEditor.js (156922 => 156923)


--- trunk/Source/WebInspectorUI/UserInterface/SourceCodeTextEditor.js	2013-10-04 22:49:40 UTC (rev 156922)
+++ trunk/Source/WebInspectorUI/UserInterface/SourceCodeTextEditor.js	2013-10-04 23:01:50 UTC (rev 156923)
@@ -900,32 +900,19 @@
         }
     },
 
-    _shouldTrackTokenHovering: function()
+    _updateTokenTrackingControllerEnabled: function()
     {
-        return this._jumpToSymbolTrackingModeEnabled || WebInspector.debuggerManager.activeCallFrame;
+        this.tokenTrackingController.enabled = this._jumpToSymbolTrackingModeEnabled || WebInspector.debuggerManager.activeCallFrame;
     },
 
-    _startTrackingTokenHoveringIfNeeded: function()
-    {
-        if (this._shouldTrackTokenHovering() && !this.tokenTrackingController.tracking)
-            this.tokenTrackingController.startTracking();
-    },
-
-    _stopTrackingTokenHoveringIfNeeded: function()
-    {
-        if (!this._shouldTrackTokenHovering() && this.tokenTrackingController.tracking)
-            this.tokenTrackingController.stopTracking();
-    },
-
     _debuggerDidPause: function(event)
     {
-        this._startTrackingTokenHoveringIfNeeded();
+        this._updateTokenTrackingControllerEnabled();
     },
 
     _debuggerDidResume: function(event)
     {
-        this._stopTrackingTokenHoveringIfNeeded();
-
+        this._updateTokenTrackingControllerEnabled();
         this._dismissPopover();
     },
 
@@ -949,12 +936,10 @@
         if (oldJumpToSymbolTrackingModeEnabled !== this._jumpToSymbolTrackingModeEnabled) {
             if (this._jumpToSymbolTrackingModeEnabled) {
                 this._enableJumpToSymbolTrackingModeSettings();
-                this._startTrackingTokenHoveringIfNeeded();
+                this.tokenTrackingController.highlightLastHoveredRange();
             } else {
-                this._stopTrackingTokenHoveringIfNeeded();
                 this._disableJumpToSymbolTrackingModeSettings();
-                if (!this.tokenTrackingController.tracking)
-                    this.tokenTrackingController.removeHighlightedRange();
+                this.tokenTrackingController.removeHighlightedRange();
             }
         }
     },
@@ -966,6 +951,9 @@
         this.tokenTrackingController.mouseOutReleaseDelayDuration = 0;
 
         this.tokenTrackingController.mode = WebInspector.CodeMirrorTokenTrackingController.Mode.NonSymbolTokens;
+        this._updateTokenTrackingControllerEnabled();
+
+        this._dismissPopover();
     },
 
     _disableJumpToSymbolTrackingModeSettings: function()
@@ -975,6 +963,7 @@
         this.tokenTrackingController.mouseOutReleaseDelayDuration = WebInspector.SourceCodeTextEditor.DurationToMouseOutOfHoveredTokenToRelease;
 
         this.tokenTrackingController.mode = WebInspector.CodeMirrorTokenTrackingController.Mode._javascript_Expression;
+        this._updateTokenTrackingControllerEnabled();
     },
 
     // CodeMirrorTokenTrackingController Delegate
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to