Changeset 208783 in webkit
- Timestamp:
- Nov 15, 2016 10:03:45 PM (7 years ago)
- Location:
- trunk/Source/WebInspectorUI
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebInspectorUI/ChangeLog
r208779 r208783 1 2016-11-15 Joseph Pecoraro <pecoraro@apple.com> 2 3 Web Inspector: SourceCodeTextEditor should display execution lines for background threads 4 https://bugs.webkit.org/show_bug.cgi?id=164679 5 <rdar://problem/29233026> 6 7 Reviewed by Timothy Hatcher. 8 9 There may be multiple threads paused in the same content view. With 10 this change we should a thread indicator for each primary line a 11 thread is paused on. It uses the same inline line indicator that 12 inline errors/warnings (issues) use. 13 14 When there is a single thread (just the Page) we don't show thread 15 indicators. But as soon as there are multiple threads we start 16 managing and showing them. The line indicator contains the name of 17 the thread on the side. 18 19 Note that SourceCodeTextEditor maintains the thread indicators, but 20 it still always handles the ActiveCallFrame as it used to, pushing 21 values down into TextEditor. The ActiveCallFrame styles override 22 the thread line indicators (albeit with the same styles). The reason 23 these are still separate is that TextEditor has some special styles 24 regarding its gutter for the active execution line. Eventually we 25 may want to find a way to push this up into SourceCodeTextEditor. 26 27 * Localizations/en.lproj/localizedStrings.js: 28 New string "%d Threads" when multiple threads are on the same line. 29 30 * UserInterface/Views/ScopeChainDetailsSidebarPanel.js: 31 (WebInspector.ScopeChainDetailsSidebarPanel): 32 (WebInspector.ScopeChainDetailsSidebarPanel.prototype._activeCallFrameDidChange): 33 Update Watch Expressions when the active call frame changes. 34 35 * UserInterface/Views/SourceCodeTextEditor.css: 36 (.source-code.text-editor > .CodeMirror .line-indicator-widget): 37 (.source-code.text-editor > .CodeMirror .line-indicator-widget.inline): 38 (.source-code.text-editor > .CodeMirror .line-indicator-widget > .arrow): 39 (.source-code.text-editor > .CodeMirror .line-indicator-widget.inline > .arrow): 40 (.source-code.text-editor > .CodeMirror .line-indicator-widget > .icon): 41 (.source-code.text-editor > .CodeMirror .line-indicator-widget > .text): 42 (.source-code.text-editor > .CodeMirror .line-indicator-widget.inline > .text): 43 Share line indicator widget styles between issue widgets and thread widgets. 44 45 (.source-code.text-editor > .CodeMirror .thread-indicator): 46 (.source-code.text-editor > .CodeMirror .thread-widget): 47 (.source-code.text-editor > .CodeMirror .thread-widget.inline): 48 (.source-code.text-editor > .CodeMirror .thread-widget.inline > .arrow): 49 Colors for the thread-widget line-indicators. 50 51 * UserInterface/Views/SourceCodeTextEditor.js: 52 (WebInspector.SourceCodeTextEditor): 53 (WebInspector.SourceCodeTextEditor.prototype.close): 54 New event listeners handling for Target added / removed events. 55 56 (WebInspector.SourceCodeTextEditor.prototype._targetAdded): 57 (WebInspector.SourceCodeTextEditor.prototype._targetRemoved): 58 Update thread indicators as needed. 59 60 (WebInspector.SourceCodeTextEditor.prototype._looselyMatchesSourceCodeLocation): 61 More generic match based just on the URLs. Even if the exact script comes 62 from a different target, if they share the same URL that is fine. 63 64 (WebInspector.SourceCodeTextEditor.prototype._callFramesDidChange): 65 (WebInspector.SourceCodeTextEditor.prototype._addThreadIndicatorForTarget): 66 (WebInspector.SourceCodeTextEditor.prototype._removeThreadIndicatorForTarget): 67 (WebInspector.SourceCodeTextEditor.prototype._threadIndicatorWidgetForLine): 68 (WebInspector.SourceCodeTextEditor.prototype._updateThreadIndicatorWidget): 69 (WebInspector.SourceCodeTextEditor.prototype._handleThreadIndicatorWidgetClick): 70 Manage thread line indicator widgets. There are 3 maps we maintain. 71 72 1. line -> [threads] 73 List of threads paused on a line, needed for the UI text. 74 2. line -> widget 75 Gets the widget on a line so we can modify and eventually remove it. 76 3. target -> line 77 If a target is removed, we need to know what line it had an indicator on. 78 79 (WebInspector.SourceCodeTextEditor.prototype._isWidgetToggleable): 80 Generalize for all of our different line indicator widgets. 81 82 (WebInspector.SourceCodeTextEditor.prototype._contentDidPopulate): 83 (WebInspector.SourceCodeTextEditor.prototype.textEditorUpdatedFormatting): 84 (WebInspector.SourceCodeTextEditor.prototype._reinsertAllThreadIndicators): 85 When first populated, or reformatted, clear and reinsert all widgets. 86 87 (WebInspector.SourceCodeTextEditor.prototype._reinsertAllIssues): 88 (WebInspector.SourceCodeTextEditor.prototype._logCleared): 89 (WebInspector.SourceCodeTextEditor.prototype._clearIssueWidgets): Renamed. 90 Rename _clearWidgets to _clearIssueWidgets. 91 1 92 2016-11-15 Joseph Pecoraro <pecoraro@apple.com> 2 93 -
trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
r208779 r208783 23 23 localizedStrings["%d Errors, %d Warnings"] = "%d Errors, %d Warnings"; 24 24 localizedStrings["%d More\u2026"] = "%d More\u2026"; 25 localizedStrings["%d Threads"] = "%d Threads"; 25 26 localizedStrings["%d Warnings"] = "%d Warnings"; 26 27 localizedStrings["%d \xd7 %d pixels"] = "%d \xd7 %d pixels"; -
trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js
r208664 r208783 69 69 // Update watch expressions on navigations. 70 70 WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this); 71 72 // Update watch expressions on active call frame changes. 73 WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange, this._activeCallFrameDidChange, this); 71 74 } 72 75 … … 425 428 } 426 429 430 _activeCallFrameDidChange() 431 { 432 this.needsLayout(); 433 } 434 427 435 _mainResourceDidChange(event) 428 436 { -
trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.css
r205832 r208783 37 37 } 38 38 39 .source-code.text-editor > .CodeMirror .issue-widget { 39 .source-code.text-editor > .CodeMirror .thread-indicator { 40 background-color: hsla(99, 38%, 86%, 0.5); 41 } 42 43 .source-code.text-editor > .CodeMirror .line-indicator-widget { 40 44 float: right; 41 45 padding: 0 5px 1px 5px; … … 44 48 } 45 49 46 .source-code.text-editor > .CodeMirror . issue-widget.inline {50 .source-code.text-editor > .CodeMirror .line-indicator-widget.inline { 47 51 position: relative; 48 52 top: -13px; … … 52 56 } 53 57 54 .source-code.text-editor > .CodeMirror . issue-widget > .arrow {58 .source-code.text-editor > .CodeMirror .line-indicator-widget > .arrow { 55 59 display: none; 56 60 } 57 61 58 .source-code.text-editor > .CodeMirror . issue-widget.inline > .arrow {62 .source-code.text-editor > .CodeMirror .line-indicator-widget.inline > .arrow { 59 63 position: absolute; 60 64 left: -5px; … … 71 75 72 76 @media (-webkit-min-device-pixel-ratio: 2) { 73 .source-code.text-editor > .CodeMirror . issue-widget.inline > .arrow {77 .source-code.text-editor > .CodeMirror .line-indicator-widget.inline > .arrow { 74 78 left: -5.5px; 75 79 } 76 80 } 77 81 78 .source-code.text-editor > .CodeMirror . issue-widget > .icon {82 .source-code.text-editor > .CodeMirror .line-indicator-widget > .icon { 79 83 height: 9px; 80 84 width: 9px; … … 86 90 } 87 91 88 .source-code.text-editor > .CodeMirror .issue-widget > .icon.icon-warning { 89 background-image: url(../Images/Warning.svg); 90 } 91 92 .source-code.text-editor > .CodeMirror .issue-widget > .icon.icon-error { 93 background-image: url(../Images/Error.svg); 94 } 95 96 .source-code.text-editor > .CodeMirror .issue-widget.warning { 97 background-color: hsl(51, 87%, 93%); 98 } 99 100 .source-code.text-editor > .CodeMirror .issue-widget.inline.warning { 101 background-color: hsl(43, 97%, 84%); 102 } 103 104 .source-code.text-editor > .CodeMirror .issue-widget.inline.warning > .arrow { 105 border-right-color: hsl(43, 97%, 84%); 106 } 107 108 .source-code.text-editor > .CodeMirror .issue-widget.error { 109 background-color: hsl(15, 100%, 90%); 110 } 111 112 .source-code.text-editor > .CodeMirror .issue-widget.inline.error { 113 background-color: hsl(11, 100%, 80%); 114 } 115 116 .source-code.text-editor > .CodeMirror .issue-widget.inline.error > .arrow { 117 border-right-color: hsl(11, 100%, 80%); 118 } 119 120 .source-code.text-editor > .CodeMirror .issue-widget > .text { 92 .source-code.text-editor > .CodeMirror .line-indicator-widget > .text { 121 93 font-family: -apple-system, sans-serif; 122 94 } 123 95 124 .source-code.text-editor > .CodeMirror . issue-widget.inline > .text {96 .source-code.text-editor > .CodeMirror .line-indicator-widget.inline > .text { 125 97 display: inline-block; 126 98 max-width: 300px; … … 128 100 text-overflow: ellipsis; 129 101 white-space: nowrap; 102 } 103 104 .source-code.text-editor > .CodeMirror .issue-widget > .icon.icon-warning { 105 background-image: url(../Images/Warning.svg); 106 } 107 108 .source-code.text-editor > .CodeMirror .issue-widget > .icon.icon-error { 109 background-image: url(../Images/Error.svg); 110 } 111 112 .source-code.text-editor > .CodeMirror .issue-widget.warning { 113 background-color: hsl(51, 87%, 93%); 114 } 115 116 .source-code.text-editor > .CodeMirror .issue-widget.inline.warning { 117 background-color: hsl(43, 97%, 84%); 118 } 119 120 .source-code.text-editor > .CodeMirror .issue-widget.inline.warning > .arrow { 121 border-right-color: hsl(43, 97%, 84%); 122 } 123 124 .source-code.text-editor > .CodeMirror .issue-widget.error { 125 background-color: hsl(15, 100%, 90%); 126 } 127 128 .source-code.text-editor > .CodeMirror .issue-widget.inline.error { 129 background-color: hsl(11, 100%, 80%); 130 } 131 132 .source-code.text-editor > .CodeMirror .issue-widget.inline.error > .arrow { 133 border-right-color: hsl(11, 100%, 80%); 134 } 135 136 .source-code.text-editor > .CodeMirror .thread-widget { 137 background-color: hsl(90, 30%, 82%); 138 } 139 140 .source-code.text-editor > .CodeMirror .thread-widget.inline { 141 background-color: hsl(90, 30%, 82%); 142 } 143 144 .source-code.text-editor > .CodeMirror .thread-widget.inline > .arrow { 145 border-right-color: hsl(90, 30%, 82%); 130 146 } 131 147 -
trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js
r208664 r208783 43 43 this._activeCallFrameSourceCodeLocation = null; 44 44 45 this._threadLineNumberMap = new Map; // line -> [targets] 46 this._threadWidgetMap = new Map; // line -> widget 47 this._threadTargetMap = new Map; // target -> line 48 45 49 this._typeTokenScrollHandler = null; 46 50 this._typeTokenAnnotator = null; … … 68 72 WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.LocationDidChange, this._updateBreakpointLocation, this); 69 73 74 WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Event.TargetAdded, this._targetAdded, this); 75 WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Event.TargetRemoved, this._targetRemoved, this); 76 70 77 WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.BreakpointsEnabledDidChange, this._breakpointsEnabledDidChange, this); 71 78 WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.BreakpointAdded, this._breakpointAdded, this); 72 79 WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.BreakpointRemoved, this._breakpointRemoved, this); 80 WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.CallFramesDidChange, this._callFramesDidChange, this); 73 81 WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange, this._activeCallFrameDidChange, this); 74 82 … … 163 171 WebInspector.Breakpoint.removeEventListener(null, null, this); 164 172 WebInspector.debuggerManager.removeEventListener(null, null, this); 173 WebInspector.targetManager.removeEventListener(null, null, this); 165 174 166 175 if (this._activeCallFrameSourceCodeLocation) { … … 480 489 481 490 this._reinsertAllIssues(); 491 this._reinsertAllThreadIndicators(); 482 492 483 493 this._updateEditableMarkers(); … … 651 661 } 652 662 663 _targetAdded(event) 664 { 665 if (WebInspector.targets.size === 2) 666 this._reinsertAllThreadIndicators(); 667 } 668 669 _targetRemoved(event) 670 { 671 if (WebInspector.targets.size === 1) { 672 // Back to one thread, remove thread indicators. 673 this._reinsertAllThreadIndicators(); 674 return; 675 } 676 677 let target = event.data.target; 678 this._removeThreadIndicatorForTarget(target); 679 } 680 681 _callFramesDidChange(event) 682 { 683 if (WebInspector.targets.size === 1) 684 return; 685 686 let target = event.data.target; 687 this._removeThreadIndicatorForTarget(target); 688 this._addThreadIndicatorForTarget(target); 689 } 690 691 _addThreadIndicatorForTarget(target) 692 { 693 let targetData = WebInspector.debuggerManager.dataForTarget(target); 694 let topCallFrame = targetData.callFrames[0]; 695 if (!topCallFrame) 696 return; 697 698 let sourceCodeLocation = topCallFrame.sourceCodeLocation; 699 console.assert(sourceCodeLocation, "Expected source code location to place thread indicator."); 700 if (!sourceCodeLocation) 701 return; 702 703 if (!this._looselyMatchesSourceCodeLocation(sourceCodeLocation)) 704 return; 705 706 let lineNumberWithIndicator = sourceCodeLocation.formattedLineNumber; 707 this._threadTargetMap.set(target, lineNumberWithIndicator); 708 709 let threads = this._threadLineNumberMap.get(lineNumberWithIndicator); 710 if (!threads) { 711 threads = []; 712 this._threadLineNumberMap.set(lineNumberWithIndicator, threads); 713 } 714 threads.push(target); 715 716 let widget = this._threadIndicatorWidgetForLine(target, lineNumberWithIndicator); 717 this._updateThreadIndicatorWidget(widget, threads); 718 719 this.addStyleClassToLine(lineNumberWithIndicator, "thread-indicator"); 720 } 721 722 _removeThreadIndicatorForTarget(target) 723 { 724 let lineNumberWithIndicator = this._threadTargetMap.take(target); 725 if (lineNumberWithIndicator === undefined) 726 return; 727 728 let threads = this._threadLineNumberMap.get(lineNumberWithIndicator); 729 threads.remove(target); 730 if (threads.length) { 731 let widget = this._threadWidgetMap.get(lineNumberWithIndicator); 732 this._updateThreadIndicatorWidget(widget, threads); 733 return; 734 } 735 736 this._threadLineNumberMap.delete(lineNumberWithIndicator); 737 738 let widget = this._threadWidgetMap.take(lineNumberWithIndicator); 739 if (widget) 740 widget.clear(); 741 742 this.removeStyleClassFromLine(lineNumberWithIndicator, "thread-indicator"); 743 } 744 745 _threadIndicatorWidgetForLine(target, lineNumber) 746 { 747 let widget = this._threadWidgetMap.get(lineNumber); 748 if (widget) 749 return widget; 750 751 widget = this.createWidgetForLine(lineNumber); 752 if (!widget) 753 return null; 754 755 let widgetElement = widget.widgetElement; 756 widgetElement.classList.add("line-indicator-widget", "thread-widget", "inline"); 757 widgetElement.addEventListener("click", this._handleThreadIndicatorWidgetClick.bind(this, widget, lineNumber)); 758 759 this._threadWidgetMap.set(lineNumber, widget); 760 761 return widget; 762 } 763 764 _updateThreadIndicatorWidget(widget, threads) 765 { 766 if (!widget) 767 return; 768 769 console.assert(WebInspector.targets.size > 1); 770 771 let widgetElement = widget.widgetElement; 772 widgetElement.removeChildren(); 773 774 widget[WebInspector.SourceCodeTextEditor.WidgetContainsMultipleThreadsSymbol] = threads.length > 1; 775 776 if (widgetElement.classList.contains("inline") || threads.length === 1) { 777 let arrowElement = widgetElement.appendChild(document.createElement("span")); 778 arrowElement.className = "arrow"; 779 780 let textElement = widgetElement.appendChild(document.createElement("span")); 781 textElement.className = "text"; 782 textElement.textContent = threads.length === 1 ? threads[0].displayName : WebInspector.UIString("%d Threads").format(threads.length); 783 } else { 784 for (let target of threads) { 785 let textElement = widgetElement.appendChild(document.createElement("span")); 786 textElement.className = "text"; 787 textElement.textContent = target.displayName; 788 789 widgetElement.appendChild(document.createElement("br")); 790 } 791 } 792 793 widget.update(); 794 } 795 796 _handleThreadIndicatorWidgetClick(widget, lineNumber, event) 797 { 798 if (!this._isWidgetToggleable(widget)) 799 return; 800 801 widget.widgetElement.classList.toggle("inline"); 802 803 let threads = this._threadLineNumberMap.get(lineNumber); 804 this._updateThreadIndicatorWidget(widget, threads); 805 } 806 653 807 _activeCallFrameDidChange() 654 808 { … … 660 814 } 661 815 662 varactiveCallFrame = WebInspector.debuggerManager.activeCallFrame;816 let activeCallFrame = WebInspector.debuggerManager.activeCallFrame; 663 817 if (!activeCallFrame || !this._matchesSourceCodeLocation(activeCallFrame.sourceCodeLocation)) { 664 818 this.setExecutionLineAndColumn(NaN, NaN); … … 674 828 // could have changed (e.g. continuing in a loop with a breakpoint inside). 675 829 676 varlineInfo = this._editorLineInfoForSourceCodeLocation(activeCallFrame.sourceCodeLocation);830 let lineInfo = this._editorLineInfoForSourceCodeLocation(activeCallFrame.sourceCodeLocation); 677 831 this.setExecutionLineAndColumn(lineInfo.lineNumber, lineInfo.columnNumber); 678 832 … … 812 966 } 813 967 968 _looselyMatchesSourceCodeLocation(sourceCodeLocation) 969 { 970 if (this._sourceCode instanceof WebInspector.SourceMapResource) 971 return sourceCodeLocation.displaySourceCode === this._sourceCode; 972 if (this._sourceCode instanceof WebInspector.Resource || this._sourceCode instanceof WebInspector.Script) 973 return sourceCodeLocation.sourceCode.url === this._sourceCode.url; 974 return false; 975 } 976 814 977 _matchesSourceCodeLocation(sourceCodeLocation) 815 978 { … … 896 1059 897 1060 var widgetElement = widget.widgetElement; 898 widgetElement.classList.add(" issue-widget", "inline");1061 widgetElement.classList.add("line-indicator-widget", "issue-widget", "inline"); 899 1062 widgetElement.addEventListener("click", this._handleWidgetClick.bind(this, widget, lineNumber)); 900 1063 … … 976 1139 return true; 977 1140 1141 if (widget[WebInspector.SourceCodeTextEditor.WidgetContainsMultipleThreadsSymbol]) 1142 return true; 1143 978 1144 if (!widget.widgetElement.classList.contains("inline")) 979 1145 return true; … … 1228 1394 1229 1395 this._reinsertAllIssues(); 1396 this._reinsertAllThreadIndicators(); 1230 1397 } 1231 1398 … … 1353 1520 } 1354 1521 1355 _clear Widgets()1522 _clearIssueWidgets() 1356 1523 { 1357 1524 for (var widget of this._widgetMap.values()) … … 1364 1531 { 1365 1532 this._issuesLineNumberMap.clear(); 1366 this._clear Widgets();1367 1368 varissues = WebInspector.issueManager.issuesForSourceCode(this._sourceCode);1369 for ( varissue of issues)1533 this._clearIssueWidgets(); 1534 1535 let issues = WebInspector.issueManager.issuesForSourceCode(this._sourceCode); 1536 for (let issue of issues) 1370 1537 this._addIssue(issue); 1538 } 1539 1540 _reinsertAllThreadIndicators() 1541 { 1542 // Clear line styles. 1543 for (let lineNumber of this._threadLineNumberMap.keys()) 1544 this.removeStyleClassFromLine(lineNumber, "thread-indicator"); 1545 this._threadLineNumberMap.clear(); 1546 1547 // Clear widgets. 1548 for (let widget of this._threadWidgetMap.values()) 1549 widget.clear(); 1550 this._threadWidgetMap.clear(); 1551 1552 // Clear other maps. 1553 this._threadTargetMap.clear(); 1554 1555 if (WebInspector.targets.size > 1) { 1556 for (let target of WebInspector.targets) 1557 this._addThreadIndicatorForTarget(target); 1558 } 1371 1559 } 1372 1560 … … 2050 2238 2051 2239 this._issuesLineNumberMap.clear(); 2052 this._clear Widgets();2240 this._clearIssueWidgets(); 2053 2241 } 2054 2242 }; … … 2062 2250 WebInspector.SourceCodeTextEditor.DurationToUpdateTypeTokensAfterScrolling = 100; 2063 2251 WebInspector.SourceCodeTextEditor.WidgetContainsMultipleIssuesSymbol = Symbol("source-code-widget-contains-multiple-issues"); 2252 WebInspector.SourceCodeTextEditor.WidgetContainsMultipleThreadsSymbol = Symbol("source-code-widget-contains-multiple-threads"); 2064 2253 2065 2254 WebInspector.SourceCodeTextEditor.Event = {
Note: See TracChangeset
for help on using the changeset viewer.