| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 /** | |
| 5 * @implements {UI.ContextFlavorListener} | |
| 6 * @unrestricted | |
| 7 */ | |
| 8 Sources.JavaScriptBreakpointsSidebarPane = class extends UI.ThrottledWidget { | |
| 9 constructor() { | |
| 10 super(true); | |
| 11 this.registerRequiredCSS('components/breakpointsList.css'); | |
| 12 | |
| 13 this._breakpointManager = Bindings.breakpointManager; | |
| 14 this._breakpointManager.addEventListener(Bindings.BreakpointManager.Events.B
reakpointAdded, this.update, this); | |
| 15 this._breakpointManager.addEventListener(Bindings.BreakpointManager.Events.B
reakpointRemoved, this.update, this); | |
| 16 this._breakpointManager.addEventListener( | |
| 17 Bindings.BreakpointManager.Events.BreakpointsActiveStateChanged, this.up
date, this); | |
| 18 | |
| 19 /** @type {?Element} */ | |
| 20 this._listElement = null; | |
| 21 this.update(); | |
| 22 } | |
| 23 | |
| 24 /** | |
| 25 * @override | |
| 26 * @return {!Promise<?>} | |
| 27 */ | |
| 28 doUpdate() { | |
| 29 var breakpointLocations = this._breakpointManager.allBreakpointLocations(); | |
| 30 if (!breakpointLocations.length) { | |
| 31 this._listElement = null; | |
| 32 this.contentElement.removeChildren(); | |
| 33 var emptyElement = this.contentElement.createChild('div', 'gray-info-messa
ge'); | |
| 34 emptyElement.textContent = Common.UIString('No Breakpoints'); | |
| 35 this.contentElement.appendChild(emptyElement); | |
| 36 this._didUpdateForTest(); | |
| 37 return Promise.resolve(); | |
| 38 } | |
| 39 | |
| 40 if (!this._listElement) { | |
| 41 this.contentElement.removeChildren(); | |
| 42 this._listElement = this.contentElement.createChild('div'); | |
| 43 this.contentElement.appendChild(this._listElement); | |
| 44 } | |
| 45 | |
| 46 breakpointLocations.sort((item1, item2) => item1.uiLocation.compareTo(item2.
uiLocation)); | |
| 47 | |
| 48 /** @type {!Multimap<string, !{breakpoint: !Bindings.BreakpointManager.Break
point, uiLocation: !Workspace.UILocation}>} */ | |
| 49 var locationForEntry = new Multimap(); | |
| 50 for (var breakpointLocation of breakpointLocations) { | |
| 51 var uiLocation = breakpointLocation.uiLocation; | |
| 52 var entryDescriptor = uiLocation.uiSourceCode.url() + ':' + uiLocation.lin
eNumber; | |
| 53 locationForEntry.set(entryDescriptor, breakpointLocation); | |
| 54 } | |
| 55 | |
| 56 var details = UI.context.flavor(SDK.DebuggerPausedDetails); | |
| 57 var selectedUILocation = details && details.callFrames.length ? | |
| 58 Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(details.callFr
ames[0].location()) : | |
| 59 null; | |
| 60 | |
| 61 var shouldShowView = false; | |
| 62 var entry = this._listElement.firstChild; | |
| 63 var promises = []; | |
| 64 for (var descriptor of locationForEntry.keysArray()) { | |
| 65 if (!entry) { | |
| 66 entry = this._listElement.createChild('div', 'breakpoint-entry'); | |
| 67 entry.addEventListener('contextmenu', this._breakpointContextMenu.bind(t
his), true); | |
| 68 entry.addEventListener('click', this._revealLocation.bind(this), false); | |
| 69 var checkboxLabel = UI.CheckboxLabel.create(''); | |
| 70 checkboxLabel.addEventListener('click', this._breakpointCheckboxClicked.
bind(this), false); | |
| 71 entry.appendChild(checkboxLabel); | |
| 72 entry[Sources.JavaScriptBreakpointsSidebarPane._checkboxLabelSymbol] = c
heckboxLabel; | |
| 73 var snippetElement = entry.createChild('div', 'source-text monospace'); | |
| 74 entry[Sources.JavaScriptBreakpointsSidebarPane._snippetElementSymbol] =
snippetElement; | |
| 75 } | |
| 76 | |
| 77 var locations = Array.from(locationForEntry.get(descriptor)); | |
| 78 var uiLocation = locations[0].uiLocation; | |
| 79 var isSelected = | |
| 80 !!selectedUILocation && locations.some(location => location.uiLocation
.id() === selectedUILocation.id()); | |
| 81 var hasEnabled = locations.some(location => location.breakpoint.enabled())
; | |
| 82 var hasDisabled = locations.some(location => !location.breakpoint.enabled(
)); | |
| 83 promises.push(this._resetEntry(/** @type {!Element}*/ (entry), uiLocation,
isSelected, hasEnabled, hasDisabled)); | |
| 84 | |
| 85 if (isSelected) | |
| 86 shouldShowView = true; | |
| 87 entry = entry.nextSibling; | |
| 88 } | |
| 89 while (entry) { | |
| 90 var next = entry.nextSibling; | |
| 91 entry.remove(); | |
| 92 entry = next; | |
| 93 } | |
| 94 if (shouldShowView) | |
| 95 UI.viewManager.showView('sources.jsBreakpoints'); | |
| 96 this._listElement.classList.toggle('breakpoints-list-deactivated', !this._br
eakpointManager.breakpointsActive()); | |
| 97 Promise.all(promises).then(() => this._didUpdateForTest()); | |
| 98 return Promise.resolve(); | |
| 99 } | |
| 100 | |
| 101 /** | |
| 102 * @param {!Element} element | |
| 103 * @param {!Workspace.UILocation} uiLocation | |
| 104 * @param {boolean} isSelected | |
| 105 * @param {boolean} hasEnabled | |
| 106 * @param {boolean} hasDisabled | |
| 107 * @return {!Promise<undefined>} | |
| 108 */ | |
| 109 _resetEntry(element, uiLocation, isSelected, hasEnabled, hasDisabled) { | |
| 110 element[Sources.JavaScriptBreakpointsSidebarPane._locationSymbol] = uiLocati
on; | |
| 111 element.classList.toggle('breakpoint-hit', isSelected); | |
| 112 | |
| 113 var checkboxLabel = element[Sources.JavaScriptBreakpointsSidebarPane._checkb
oxLabelSymbol]; | |
| 114 checkboxLabel.textElement.textContent = uiLocation.linkText(); | |
| 115 checkboxLabel.checkboxElement.checked = hasEnabled; | |
| 116 checkboxLabel.checkboxElement.indeterminate = hasEnabled && hasDisabled; | |
| 117 | |
| 118 var snippetElement = element[Sources.JavaScriptBreakpointsSidebarPane._snipp
etElementSymbol]; | |
| 119 return uiLocation.uiSourceCode.requestContent().then(fillSnippetElement.bind
(null, snippetElement)); | |
| 120 | |
| 121 /** | |
| 122 * @param {!Element} snippetElement | |
| 123 * @param {?string} content | |
| 124 */ | |
| 125 function fillSnippetElement(snippetElement, content) { | |
| 126 var lineNumber = uiLocation.lineNumber; | |
| 127 var text = new TextUtils.Text(content || ''); | |
| 128 if (lineNumber < text.lineCount()) { | |
| 129 var lineText = text.lineAt(lineNumber); | |
| 130 var maxSnippetLength = 200; | |
| 131 snippetElement.textContent = lineText.trimEnd(maxSnippetLength); | |
| 132 } | |
| 133 } | |
| 134 } | |
| 135 | |
| 136 /** | |
| 137 * @param {!Event} event | |
| 138 * @return {?Workspace.UILocation} | |
| 139 */ | |
| 140 _uiLocationFromEvent(event) { | |
| 141 var node = event.target.enclosingNodeOrSelfWithClass('breakpoint-entry'); | |
| 142 if (!node) | |
| 143 return null; | |
| 144 return node[Sources.JavaScriptBreakpointsSidebarPane._locationSymbol] || nul
l; | |
| 145 } | |
| 146 | |
| 147 /** | |
| 148 * @param {!Event} event | |
| 149 */ | |
| 150 _breakpointCheckboxClicked(event) { | |
| 151 var uiLocation = this._uiLocationFromEvent(event); | |
| 152 if (!uiLocation) | |
| 153 return; | |
| 154 | |
| 155 var breakpoints = this._breakpointManager.findBreakpoints(uiLocation.uiSourc
eCode, uiLocation.lineNumber); | |
| 156 var newState = event.target.checkboxElement.checked; | |
| 157 for (var breakpoint of breakpoints) | |
| 158 breakpoint.setEnabled(newState); | |
| 159 event.consume(); | |
| 160 } | |
| 161 | |
| 162 /** | |
| 163 * @param {!Event} event | |
| 164 */ | |
| 165 _revealLocation(event) { | |
| 166 var uiLocation = this._uiLocationFromEvent(event); | |
| 167 if (uiLocation) | |
| 168 Common.Revealer.reveal(uiLocation); | |
| 169 } | |
| 170 | |
| 171 /** | |
| 172 * @param {!Event} event | |
| 173 */ | |
| 174 _breakpointContextMenu(event) { | |
| 175 var uiLocation = this._uiLocationFromEvent(event); | |
| 176 if (!uiLocation) | |
| 177 return; | |
| 178 | |
| 179 var breakpoints = this._breakpointManager.findBreakpoints(uiLocation.uiSourc
eCode, uiLocation.lineNumber); | |
| 180 | |
| 181 var contextMenu = new UI.ContextMenu(event); | |
| 182 var removeEntryTitle = breakpoints.length > 1 ? Common.UIString('Remove all
breakpoints in line') : | |
| 183 Common.UIString('Remove brea
kpoint'); | |
| 184 contextMenu.appendItem(removeEntryTitle, () => breakpoints.map(breakpoint =>
breakpoint.remove())); | |
| 185 | |
| 186 contextMenu.appendSeparator(); | |
| 187 var breakpointActive = this._breakpointManager.breakpointsActive(); | |
| 188 var breakpointActiveTitle = | |
| 189 breakpointActive ? Common.UIString('Deactivate breakpoints') : Common.UI
String('Activate breakpoints'); | |
| 190 contextMenu.appendItem( | |
| 191 breakpointActiveTitle, | |
| 192 this._breakpointManager.setBreakpointsActive.bind(this._breakpointManage
r, !breakpointActive)); | |
| 193 | |
| 194 contextMenu.appendSeparator(); | |
| 195 if (breakpoints.some(breakpoint => !breakpoint.enabled())) { | |
| 196 var enableTitle = Common.UIString('Enable all breakpoints'); | |
| 197 contextMenu.appendItem( | |
| 198 enableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._b
reakpointManager, true)); | |
| 199 } | |
| 200 if (breakpoints.some(breakpoint => breakpoint.enabled())) { | |
| 201 var disableTitle = Common.UIString('Disable all breakpoints'); | |
| 202 contextMenu.appendItem( | |
| 203 disableTitle, this._breakpointManager.toggleAllBreakpoints.bind(this._
breakpointManager, false)); | |
| 204 } | |
| 205 var removeAllTitle = Common.UIString('Remove all breakpoints'); | |
| 206 contextMenu.appendItem(removeAllTitle, this._breakpointManager.removeAllBrea
kpoints.bind(this._breakpointManager)); | |
| 207 var removeOtherTitle = Common.UIString('Remove other breakpoints'); | |
| 208 contextMenu.appendItem( | |
| 209 removeOtherTitle, | |
| 210 this._breakpointManager.removeOtherBreakpoints.bind(this._breakpointMana
ger, new Set(breakpoints))); | |
| 211 contextMenu.show(); | |
| 212 } | |
| 213 | |
| 214 /** | |
| 215 * @override | |
| 216 * @param {?Object} object | |
| 217 */ | |
| 218 flavorChanged(object) { | |
| 219 this.update(); | |
| 220 } | |
| 221 | |
| 222 _didUpdateForTest() { | |
| 223 } | |
| 224 }; | |
| 225 | |
| 226 Sources.JavaScriptBreakpointsSidebarPane._locationSymbol = Symbol('location'); | |
| 227 Sources.JavaScriptBreakpointsSidebarPane._checkboxLabelSymbol = Symbol('checkbox
-label'); | |
| 228 Sources.JavaScriptBreakpointsSidebarPane._snippetElementSymbol = Symbol('snippet
-element'); | |
| OLD | NEW |