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/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