Title: [208783] trunk/Source/WebInspectorUI
Revision
208783
Author
[email protected]
Date
2016-11-15 22:03:45 -0800 (Tue, 15 Nov 2016)

Log Message

Web Inspector: SourceCodeTextEditor should display execution lines for background threads
https://bugs.webkit.org/show_bug.cgi?id=164679
<rdar://problem/29233026>

Patch by Joseph Pecoraro <[email protected]> on 2016-11-15
Reviewed by Timothy Hatcher.

There may be multiple threads paused in the same content view. With
this change we should a thread indicator for each primary line a
thread is paused on. It uses the same inline line indicator that
inline errors/warnings (issues) use.

When there is a single thread (just the Page) we don't show thread
indicators. But as soon as there are multiple threads we start
managing and showing them. The line indicator contains the name of
the thread on the side.

Note that SourceCodeTextEditor maintains the thread indicators, but
it still always handles the ActiveCallFrame as it used to, pushing
values down into TextEditor. The ActiveCallFrame styles override
the thread line indicators (albeit with the same styles). The reason
these are still separate is that TextEditor has some special styles
regarding its gutter for the active execution line. Eventually we
may want to find a way to push this up into SourceCodeTextEditor.

* Localizations/en.lproj/localizedStrings.js:
New string "%d Threads" when multiple threads are on the same line.

* UserInterface/Views/ScopeChainDetailsSidebarPanel.js:
(WebInspector.ScopeChainDetailsSidebarPanel):
(WebInspector.ScopeChainDetailsSidebarPanel.prototype._activeCallFrameDidChange):
Update Watch Expressions when the active call frame changes.

* UserInterface/Views/SourceCodeTextEditor.css:
(.source-code.text-editor > .CodeMirror .line-indicator-widget):
(.source-code.text-editor > .CodeMirror .line-indicator-widget.inline):
(.source-code.text-editor > .CodeMirror .line-indicator-widget > .arrow):
(.source-code.text-editor > .CodeMirror .line-indicator-widget.inline > .arrow):
(.source-code.text-editor > .CodeMirror .line-indicator-widget > .icon):
(.source-code.text-editor > .CodeMirror .line-indicator-widget > .text):
(.source-code.text-editor > .CodeMirror .line-indicator-widget.inline > .text):
Share line indicator widget styles between issue widgets and thread widgets.

(.source-code.text-editor > .CodeMirror .thread-indicator):
(.source-code.text-editor > .CodeMirror .thread-widget):
(.source-code.text-editor > .CodeMirror .thread-widget.inline):
(.source-code.text-editor > .CodeMirror .thread-widget.inline > .arrow):
Colors for the thread-widget line-indicators.

* UserInterface/Views/SourceCodeTextEditor.js:
(WebInspector.SourceCodeTextEditor):
(WebInspector.SourceCodeTextEditor.prototype.close):
New event listeners handling for Target added / removed events.

(WebInspector.SourceCodeTextEditor.prototype._targetAdded):
(WebInspector.SourceCodeTextEditor.prototype._targetRemoved):
Update thread indicators as needed.

(WebInspector.SourceCodeTextEditor.prototype._looselyMatchesSourceCodeLocation):
More generic match based just on the URLs. Even if the exact script comes
from a different target, if they share the same URL that is fine.

(WebInspector.SourceCodeTextEditor.prototype._callFramesDidChange):
(WebInspector.SourceCodeTextEditor.prototype._addThreadIndicatorForTarget):
(WebInspector.SourceCodeTextEditor.prototype._removeThreadIndicatorForTarget):
(WebInspector.SourceCodeTextEditor.prototype._threadIndicatorWidgetForLine):
(WebInspector.SourceCodeTextEditor.prototype._updateThreadIndicatorWidget):
(WebInspector.SourceCodeTextEditor.prototype._handleThreadIndicatorWidgetClick):
Manage thread line indicator widgets. There are 3 maps we maintain.

  1. line -> [threads]
      List of threads paused on a line, needed for the UI text.
  2. line -> widget
      Gets the widget on a line so we can modify and eventually remove it.
  3. target -> line
      If a target is removed, we need to know what line it had an indicator on.

(WebInspector.SourceCodeTextEditor.prototype._isWidgetToggleable):
Generalize for all of our different line indicator widgets.

(WebInspector.SourceCodeTextEditor.prototype._contentDidPopulate):
(WebInspector.SourceCodeTextEditor.prototype.textEditorUpdatedFormatting):
(WebInspector.SourceCodeTextEditor.prototype._reinsertAllThreadIndicators):
When first populated, or reformatted, clear and reinsert all widgets.

(WebInspector.SourceCodeTextEditor.prototype._reinsertAllIssues):
(WebInspector.SourceCodeTextEditor.prototype._logCleared):
(WebInspector.SourceCodeTextEditor.prototype._clearIssueWidgets): Renamed.
Rename _clearWidgets to _clearIssueWidgets.

Modified Paths

Diff

Modified: trunk/Source/WebInspectorUI/ChangeLog (208782 => 208783)


--- trunk/Source/WebInspectorUI/ChangeLog	2016-11-16 05:05:38 UTC (rev 208782)
+++ trunk/Source/WebInspectorUI/ChangeLog	2016-11-16 06:03:45 UTC (rev 208783)
@@ -1,5 +1,96 @@
 2016-11-15  Joseph Pecoraro  <[email protected]>
 
+        Web Inspector: SourceCodeTextEditor should display execution lines for background threads
+        https://bugs.webkit.org/show_bug.cgi?id=164679
+        <rdar://problem/29233026>
+
+        Reviewed by Timothy Hatcher.
+
+        There may be multiple threads paused in the same content view. With
+        this change we should a thread indicator for each primary line a
+        thread is paused on. It uses the same inline line indicator that
+        inline errors/warnings (issues) use.
+
+        When there is a single thread (just the Page) we don't show thread
+        indicators. But as soon as there are multiple threads we start
+        managing and showing them. The line indicator contains the name of
+        the thread on the side.
+
+        Note that SourceCodeTextEditor maintains the thread indicators, but
+        it still always handles the ActiveCallFrame as it used to, pushing
+        values down into TextEditor. The ActiveCallFrame styles override
+        the thread line indicators (albeit with the same styles). The reason
+        these are still separate is that TextEditor has some special styles
+        regarding its gutter for the active execution line. Eventually we
+        may want to find a way to push this up into SourceCodeTextEditor.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        New string "%d Threads" when multiple threads are on the same line.
+
+        * UserInterface/Views/ScopeChainDetailsSidebarPanel.js:
+        (WebInspector.ScopeChainDetailsSidebarPanel):
+        (WebInspector.ScopeChainDetailsSidebarPanel.prototype._activeCallFrameDidChange):
+        Update Watch Expressions when the active call frame changes.
+
+        * UserInterface/Views/SourceCodeTextEditor.css:
+        (.source-code.text-editor > .CodeMirror .line-indicator-widget):
+        (.source-code.text-editor > .CodeMirror .line-indicator-widget.inline):
+        (.source-code.text-editor > .CodeMirror .line-indicator-widget > .arrow):
+        (.source-code.text-editor > .CodeMirror .line-indicator-widget.inline > .arrow):
+        (.source-code.text-editor > .CodeMirror .line-indicator-widget > .icon):
+        (.source-code.text-editor > .CodeMirror .line-indicator-widget > .text):
+        (.source-code.text-editor > .CodeMirror .line-indicator-widget.inline > .text):
+        Share line indicator widget styles between issue widgets and thread widgets.
+
+        (.source-code.text-editor > .CodeMirror .thread-indicator):
+        (.source-code.text-editor > .CodeMirror .thread-widget):
+        (.source-code.text-editor > .CodeMirror .thread-widget.inline):
+        (.source-code.text-editor > .CodeMirror .thread-widget.inline > .arrow):
+        Colors for the thread-widget line-indicators.
+
+        * UserInterface/Views/SourceCodeTextEditor.js:
+        (WebInspector.SourceCodeTextEditor):
+        (WebInspector.SourceCodeTextEditor.prototype.close):
+        New event listeners handling for Target added / removed events.
+
+        (WebInspector.SourceCodeTextEditor.prototype._targetAdded):
+        (WebInspector.SourceCodeTextEditor.prototype._targetRemoved):
+        Update thread indicators as needed.
+
+        (WebInspector.SourceCodeTextEditor.prototype._looselyMatchesSourceCodeLocation):
+        More generic match based just on the URLs. Even if the exact script comes
+        from a different target, if they share the same URL that is fine.
+
+        (WebInspector.SourceCodeTextEditor.prototype._callFramesDidChange):
+        (WebInspector.SourceCodeTextEditor.prototype._addThreadIndicatorForTarget):
+        (WebInspector.SourceCodeTextEditor.prototype._removeThreadIndicatorForTarget):
+        (WebInspector.SourceCodeTextEditor.prototype._threadIndicatorWidgetForLine):
+        (WebInspector.SourceCodeTextEditor.prototype._updateThreadIndicatorWidget):
+        (WebInspector.SourceCodeTextEditor.prototype._handleThreadIndicatorWidgetClick):
+        Manage thread line indicator widgets. There are 3 maps we maintain.
+
+          1. line -> [threads]
+              List of threads paused on a line, needed for the UI text.
+          2. line -> widget
+              Gets the widget on a line so we can modify and eventually remove it.
+          3. target -> line
+              If a target is removed, we need to know what line it had an indicator on.
+
+        (WebInspector.SourceCodeTextEditor.prototype._isWidgetToggleable):
+        Generalize for all of our different line indicator widgets.
+
+        (WebInspector.SourceCodeTextEditor.prototype._contentDidPopulate):
+        (WebInspector.SourceCodeTextEditor.prototype.textEditorUpdatedFormatting):        
+        (WebInspector.SourceCodeTextEditor.prototype._reinsertAllThreadIndicators):
+        When first populated, or reformatted, clear and reinsert all widgets.
+
+        (WebInspector.SourceCodeTextEditor.prototype._reinsertAllIssues):
+        (WebInspector.SourceCodeTextEditor.prototype._logCleared):
+        (WebInspector.SourceCodeTextEditor.prototype._clearIssueWidgets): Renamed.
+        Rename _clearWidgets to _clearIssueWidgets.
+
+2016-11-15  Joseph Pecoraro  <[email protected]>
+
         Web Inspector: Remove unused and untested Page.setTouchEmulationEnabled command
         https://bugs.webkit.org/show_bug.cgi?id=164793
 

Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (208782 => 208783)


--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2016-11-16 05:05:38 UTC (rev 208782)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2016-11-16 06:03:45 UTC (rev 208783)
@@ -22,6 +22,7 @@
 localizedStrings["%d Errors"] = "%d Errors";
 localizedStrings["%d Errors, %d Warnings"] = "%d Errors, %d Warnings";
 localizedStrings["%d More\u2026"] = "%d More\u2026";
+localizedStrings["%d Threads"] = "%d Threads";
 localizedStrings["%d Warnings"] = "%d Warnings";
 localizedStrings["%d \xd7 %d pixels"] = "%d \xd7 %d pixels";
 localizedStrings["%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)"] = "%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)";

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js (208782 => 208783)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js	2016-11-16 05:05:38 UTC (rev 208782)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js	2016-11-16 06:03:45 UTC (rev 208783)
@@ -68,6 +68,9 @@
 
         // Update watch expressions on navigations.
         WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
+
+        // Update watch expressions on active call frame changes.
+        WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange, this._activeCallFrameDidChange, this);
     }
 
     // Public
@@ -424,6 +427,11 @@
         this.needsLayout();
     }
 
+    _activeCallFrameDidChange()
+    {
+        this.needsLayout();
+    }
+
     _mainResourceDidChange(event)
     {
         if (!event.target.isMainFrame())

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.css (208782 => 208783)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.css	2016-11-16 05:05:38 UTC (rev 208782)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.css	2016-11-16 06:03:45 UTC (rev 208783)
@@ -36,7 +36,11 @@
     background-color: hsl(15, 100%, 90%);
 }
 
-.source-code.text-editor > .CodeMirror .issue-widget {
+.source-code.text-editor > .CodeMirror .thread-indicator {
+    background-color: hsla(99, 38%, 86%, 0.5);
+}
+
+.source-code.text-editor > .CodeMirror .line-indicator-widget {
     float: right;
     padding: 0 5px 1px 5px;
     border-bottom-left-radius: 5px;
@@ -43,7 +47,7 @@
     cursor: default;
 }
 
-.source-code.text-editor > .CodeMirror .issue-widget.inline {
+.source-code.text-editor > .CodeMirror .line-indicator-widget.inline {
     position: relative;
     top: -13px;
     height: 13px;
@@ -51,11 +55,11 @@
     border-bottom-left-radius: 0;
 }
 
-.source-code.text-editor > .CodeMirror .issue-widget > .arrow {
+.source-code.text-editor > .CodeMirror .line-indicator-widget > .arrow {
     display: none;
 }
 
-.source-code.text-editor > .CodeMirror .issue-widget.inline > .arrow {
+.source-code.text-editor > .CodeMirror .line-indicator-widget.inline > .arrow {
     position: absolute;
     left: -5px;
     display: block;
@@ -70,12 +74,12 @@
 }
 
 @media (-webkit-min-device-pixel-ratio: 2) {
-    .source-code.text-editor > .CodeMirror .issue-widget.inline > .arrow {
+    .source-code.text-editor > .CodeMirror .line-indicator-widget.inline > .arrow {
         left: -5.5px;
     }
 }
 
-.source-code.text-editor > .CodeMirror .issue-widget > .icon {
+.source-code.text-editor > .CodeMirror .line-indicator-widget > .icon {
     height: 9px;
     width: 9px;
     padding-right: 12px;
@@ -85,6 +89,18 @@
     background-position-y: 1px;
 }
 
+.source-code.text-editor > .CodeMirror .line-indicator-widget > .text {
+    font-family: -apple-system, sans-serif;
+}
+
+.source-code.text-editor > .CodeMirror .line-indicator-widget.inline > .text {
+    display: inline-block;
+    max-width: 300px;
+    vertical-align: baseline;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
+
 .source-code.text-editor > .CodeMirror .issue-widget > .icon.icon-warning {
     background-image: url(../Images/Warning.svg);
 }
@@ -117,18 +133,18 @@
     border-right-color: hsl(11, 100%, 80%);
 }
 
-.source-code.text-editor > .CodeMirror .issue-widget > .text {
-    font-family: -apple-system, sans-serif;
+.source-code.text-editor > .CodeMirror .thread-widget {
+    background-color: hsl(90, 30%, 82%);
 }
 
-.source-code.text-editor > .CodeMirror .issue-widget.inline > .text {
-    display: inline-block;
-    max-width: 300px;
-    vertical-align: baseline;
-    text-overflow: ellipsis;
-    white-space: nowrap;
+.source-code.text-editor > .CodeMirror .thread-widget.inline {
+    background-color: hsl(90, 30%, 82%);
 }
 
+.source-code.text-editor > .CodeMirror .thread-widget.inline > .arrow {
+    border-right-color: hsl(90, 30%, 82%);
+}
+
 .popover .debugger-popover-content {
     font-family: Menlo, monospace;
     font-size: 11px;

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js (208782 => 208783)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js	2016-11-16 05:05:38 UTC (rev 208782)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js	2016-11-16 06:03:45 UTC (rev 208783)
@@ -42,6 +42,10 @@
         this._requestingScriptContent = false;
         this._activeCallFrameSourceCodeLocation = null;
 
+        this._threadLineNumberMap = new Map; // line -> [targets]
+        this._threadWidgetMap = new Map; // line -> widget
+        this._threadTargetMap = new Map; // target -> line
+
         this._typeTokenScrollHandler = null;
         this._typeTokenAnnotator = null;
         this._basicBlockAnnotator = null;
@@ -67,9 +71,13 @@
             WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.ResolvedStateDidChange, this._breakpointStatusDidChange, this);
             WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.LocationDidChange, this._updateBreakpointLocation, this);
 
+            WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Event.TargetAdded, this._targetAdded, this);
+            WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Event.TargetRemoved, this._targetRemoved, this);
+
             WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.BreakpointsEnabledDidChange, this._breakpointsEnabledDidChange, this);
             WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.BreakpointAdded, this._breakpointAdded, this);
             WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.BreakpointRemoved, this._breakpointRemoved, this);
+            WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.CallFramesDidChange, this._callFramesDidChange, this);
             WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange, this._activeCallFrameDidChange, this);
 
             WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.Paused, this._debuggerDidPause, this);
@@ -162,6 +170,7 @@
         if (this._supportsDebugging) {
             WebInspector.Breakpoint.removeEventListener(null, null, this);
             WebInspector.debuggerManager.removeEventListener(null, null, this);
+            WebInspector.targetManager.removeEventListener(null, null, this);
 
             if (this._activeCallFrameSourceCodeLocation) {
                 this._activeCallFrameSourceCodeLocation.removeEventListener(WebInspector.SourceCodeLocation.Event.LocationChanged, this._activeCallFrameSourceCodeLocationChanged, this);
@@ -479,6 +488,7 @@
         // partial script content this can be called multiple times.)
 
         this._reinsertAllIssues();
+        this._reinsertAllThreadIndicators();
 
         this._updateEditableMarkers();
     }
@@ -650,6 +660,150 @@
         this.setBreakpointInfoForLineAndColumn(lineInfo.lineNumber, lineInfo.columnNumber, null);
     }
 
+    _targetAdded(event)
+    {
+        if (WebInspector.targets.size === 2)
+            this._reinsertAllThreadIndicators();
+    }
+
+    _targetRemoved(event)
+    {
+        if (WebInspector.targets.size === 1) {
+            // Back to one thread, remove thread indicators.
+            this._reinsertAllThreadIndicators();
+            return;
+        }
+
+        let target = event.data.target;
+        this._removeThreadIndicatorForTarget(target);
+    }
+
+    _callFramesDidChange(event)
+    {
+        if (WebInspector.targets.size === 1)
+            return;
+
+        let target = event.data.target;
+        this._removeThreadIndicatorForTarget(target);
+        this._addThreadIndicatorForTarget(target);
+    }
+
+    _addThreadIndicatorForTarget(target)
+    {
+        let targetData = WebInspector.debuggerManager.dataForTarget(target);
+        let topCallFrame = targetData.callFrames[0];
+        if (!topCallFrame)
+            return;
+
+        let sourceCodeLocation = topCallFrame.sourceCodeLocation;
+        console.assert(sourceCodeLocation, "Expected source code location to place thread indicator.");
+        if (!sourceCodeLocation)
+            return;
+
+        if (!this._looselyMatchesSourceCodeLocation(sourceCodeLocation))
+            return;
+
+        let lineNumberWithIndicator = sourceCodeLocation.formattedLineNumber;
+        this._threadTargetMap.set(target, lineNumberWithIndicator);
+
+        let threads = this._threadLineNumberMap.get(lineNumberWithIndicator);
+        if (!threads) {
+            threads = [];
+            this._threadLineNumberMap.set(lineNumberWithIndicator, threads);
+        }
+        threads.push(target);
+
+        let widget = this._threadIndicatorWidgetForLine(target, lineNumberWithIndicator);
+        this._updateThreadIndicatorWidget(widget, threads);
+
+        this.addStyleClassToLine(lineNumberWithIndicator, "thread-indicator");
+    }
+
+    _removeThreadIndicatorForTarget(target)
+    {
+        let lineNumberWithIndicator = this._threadTargetMap.take(target);
+        if (lineNumberWithIndicator === undefined)
+            return;
+
+        let threads = this._threadLineNumberMap.get(lineNumberWithIndicator);
+        threads.remove(target);
+        if (threads.length) {
+            let widget = this._threadWidgetMap.get(lineNumberWithIndicator);
+            this._updateThreadIndicatorWidget(widget, threads);
+            return;
+        }
+
+        this._threadLineNumberMap.delete(lineNumberWithIndicator);
+
+        let widget = this._threadWidgetMap.take(lineNumberWithIndicator);
+        if (widget)
+            widget.clear();
+
+        this.removeStyleClassFromLine(lineNumberWithIndicator, "thread-indicator");
+    }
+
+    _threadIndicatorWidgetForLine(target, lineNumber)
+    {
+        let widget = this._threadWidgetMap.get(lineNumber);
+        if (widget)
+            return widget;
+
+        widget = this.createWidgetForLine(lineNumber);
+        if (!widget)
+            return null;
+
+        let widgetElement = widget.widgetElement;
+        widgetElement.classList.add("line-indicator-widget", "thread-widget", "inline");
+        widgetElement.addEventListener("click", this._handleThreadIndicatorWidgetClick.bind(this, widget, lineNumber));
+
+        this._threadWidgetMap.set(lineNumber, widget);
+
+        return widget;
+    }
+
+    _updateThreadIndicatorWidget(widget, threads)
+    {
+        if (!widget)
+            return;
+
+        console.assert(WebInspector.targets.size > 1);
+
+        let widgetElement = widget.widgetElement;
+        widgetElement.removeChildren();
+
+        widget[WebInspector.SourceCodeTextEditor.WidgetContainsMultipleThreadsSymbol] = threads.length > 1;
+
+        if (widgetElement.classList.contains("inline") || threads.length === 1) {
+            let arrowElement = widgetElement.appendChild(document.createElement("span"));
+            arrowElement.className = "arrow";
+
+            let textElement = widgetElement.appendChild(document.createElement("span"));
+            textElement.className = "text";
+            textElement.textContent = threads.length === 1 ? threads[0].displayName : WebInspector.UIString("%d Threads").format(threads.length);
+        } else {
+            for (let target of threads) {
+                let textElement = widgetElement.appendChild(document.createElement("span"));
+                textElement.className = "text";
+                textElement.textContent = target.displayName;
+
+                widgetElement.appendChild(document.createElement("br"));
+            }
+        }
+
+        widget.update();
+    }
+
+    _handleThreadIndicatorWidgetClick(widget, lineNumber, event)
+    {
+        if (!this._isWidgetToggleable(widget))
+            return;
+
+        widget.widgetElement.classList.toggle("inline");
+
+        let threads = this._threadLineNumberMap.get(lineNumber);
+        this._updateThreadIndicatorWidget(widget, threads);
+    }
+
     _activeCallFrameDidChange()
     {
         console.assert(this._supportsDebugging);
@@ -659,7 +813,7 @@
             this._activeCallFrameSourceCodeLocation = null;
         }
 
-        var activeCallFrame = WebInspector.debuggerManager.activeCallFrame;
+        let activeCallFrame = WebInspector.debuggerManager.activeCallFrame;
         if (!activeCallFrame || !this._matchesSourceCodeLocation(activeCallFrame.sourceCodeLocation)) {
             this.setExecutionLineAndColumn(NaN, NaN);
             return;
@@ -673,7 +827,7 @@
         // Don't return early if the line number didn't change. The execution state still
         // could have changed (e.g. continuing in a loop with a breakpoint inside).
 
-        var lineInfo = this._editorLineInfoForSourceCodeLocation(activeCallFrame.sourceCodeLocation);
+        let lineInfo = this._editorLineInfoForSourceCodeLocation(activeCallFrame.sourceCodeLocation);
         this.setExecutionLineAndColumn(lineInfo.lineNumber, lineInfo.columnNumber);
 
         // If we have full content or this source code isn't a Resource we can return early.
@@ -811,6 +965,15 @@
         scripts[0].requestContent().then(scriptContentAvailable.bind(this));
     }
 
+    _looselyMatchesSourceCodeLocation(sourceCodeLocation)
+    {
+        if (this._sourceCode instanceof WebInspector.SourceMapResource)
+            return sourceCodeLocation.displaySourceCode === this._sourceCode;
+        if (this._sourceCode instanceof WebInspector.Resource || this._sourceCode instanceof WebInspector.Script)
+            return sourceCodeLocation.sourceCode.url ="" this._sourceCode.url;
+        return false;
+    }
+
     _matchesSourceCodeLocation(sourceCodeLocation)
     {
         if (this._sourceCode instanceof WebInspector.SourceMapResource)
@@ -895,7 +1058,7 @@
             return null;
 
         var widgetElement = widget.widgetElement;
-        widgetElement.classList.add("issue-widget", "inline");
+        widgetElement.classList.add("line-indicator-widget", "issue-widget", "inline");
         widgetElement.addEventListener("click", this._handleWidgetClick.bind(this, widget, lineNumber));
 
         this._widgetMap.set(lineNumber, widget);
@@ -975,6 +1138,9 @@
         if (widget[WebInspector.SourceCodeTextEditor.WidgetContainsMultipleIssuesSymbol])
             return true;
 
+        if (widget[WebInspector.SourceCodeTextEditor.WidgetContainsMultipleThreadsSymbol])
+            return true;
+
         if (!widget.widgetElement.classList.contains("inline"))
             return true;
 
@@ -1227,6 +1393,7 @@
         }
 
         this._reinsertAllIssues();
+        this._reinsertAllThreadIndicators();
     }
 
     textEditorExecutionHighlightRange(offset, position, characterAtOffset, callback)
@@ -1352,7 +1519,7 @@
         });
     }
 
-    _clearWidgets()
+    _clearIssueWidgets()
     {
         for (var widget of this._widgetMap.values())
             widget.clear();
@@ -1363,13 +1530,34 @@
     _reinsertAllIssues()
     {
         this._issuesLineNumberMap.clear();
-        this._clearWidgets();
+        this._clearIssueWidgets();
 
-        var issues = WebInspector.issueManager.issuesForSourceCode(this._sourceCode);
-        for (var issue of issues)
+        let issues = WebInspector.issueManager.issuesForSourceCode(this._sourceCode);
+        for (let issue of issues)
             this._addIssue(issue);
     }
 
+    _reinsertAllThreadIndicators()
+    {
+        // Clear line styles.
+        for (let lineNumber of this._threadLineNumberMap.keys())
+            this.removeStyleClassFromLine(lineNumber, "thread-indicator");
+        this._threadLineNumberMap.clear();
+
+        // Clear widgets.
+        for (let widget of this._threadWidgetMap.values())
+            widget.clear();
+        this._threadWidgetMap.clear();
+
+        // Clear other maps.
+        this._threadTargetMap.clear();
+
+        if (WebInspector.targets.size > 1) {
+            for (let target of WebInspector.targets)
+                this._addThreadIndicatorForTarget(target);
+        }
+    }
+
     _debuggerDidPause(event)
     {
         this._updateTokenTrackingControllerState();
@@ -2049,7 +2237,7 @@
         }
 
         this._issuesLineNumberMap.clear();
-        this._clearWidgets();
+        this._clearIssueWidgets();
     }
 };
 
@@ -2061,6 +2249,7 @@
 WebInspector.SourceCodeTextEditor.DurationToMouseOutOfHoveredTokenToRelease = 1000;
 WebInspector.SourceCodeTextEditor.DurationToUpdateTypeTokensAfterScrolling = 100;
 WebInspector.SourceCodeTextEditor.WidgetContainsMultipleIssuesSymbol = Symbol("source-code-widget-contains-multiple-issues");
+WebInspector.SourceCodeTextEditor.WidgetContainsMultipleThreadsSymbol = Symbol("source-code-widget-contains-multiple-threads");
 
 WebInspector.SourceCodeTextEditor.Event = {
     ContentWillPopulate: "source-code-text-editor-content-will-populate",
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to