OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
12 * | 12 * |
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR | 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 */ | 24 */ |
| 25 |
25 /** | 26 /** |
26 * @implements {UI.ContextFlavorListener} | 27 * @implements {UI.ContextFlavorListener} |
| 28 * @implements {UI.ListDelegate<!Sources.CallStackSidebarPane.Item>} |
27 * @unrestricted | 29 * @unrestricted |
28 */ | 30 */ |
29 Sources.CallStackSidebarPane = class extends UI.SimpleView { | 31 Sources.CallStackSidebarPane = class extends UI.SimpleView { |
30 constructor() { | 32 constructor() { |
31 super(Common.UIString('Call Stack')); | 33 super(Common.UIString('Call Stack'), true); |
32 this.callFrameList = new Sources.UIList(); | 34 this.registerRequiredCSS('sources/callStackSidebarPane.css'); |
33 this.callFrameList.show(this.element); | 35 |
34 this._linkifier = new Components.Linkifier(); | 36 this._blackboxedMessageElement = this._createBlackboxedMessageElement(); |
35 Common.moduleSetting('enableAsyncStackTraces').addChangeListener(this._async
StackTracesStateChanged, this); | 37 this.contentElement.appendChild(this._blackboxedMessageElement); |
36 Common.moduleSetting('skipStackFramesPattern').addChangeListener(this._updat
e, this); | 38 |
37 /** @type {!Array<!Sources.CallStackSidebarPane.CallFrame>} */ | 39 this._notPausedMessageElement = this.contentElement.createChild('div', 'gray
-info-message'); |
38 this.callFrames = []; | 40 this._notPausedMessageElement.textContent = Common.UIString('Not Paused'); |
| 41 |
| 42 /** @type {!UI.ListControl<!Sources.CallStackSidebarPane.Item>} */ |
| 43 this._list = new UI.ListControl(this, UI.ListMode.NonViewport); |
| 44 this.contentElement.appendChild(this._list.element); |
| 45 this._list.element.addEventListener('contextmenu', this._onContextMenu.bind(
this), false); |
| 46 this._list.element.addEventListener('click', this._onClick.bind(this), false
); |
| 47 |
| 48 this._showBlackboxed = false; |
| 49 Bindings.blackboxManager.addChangeListener(this._update.bind(this)); |
39 this._locationPool = new Bindings.LiveLocationPool(); | 50 this._locationPool = new Bindings.LiveLocationPool(); |
| 51 |
40 this._update(); | 52 this._update(); |
41 } | 53 } |
42 | 54 |
43 /** | 55 /** |
44 * @override | 56 * @override |
45 * @param {?Object} object | 57 * @param {?Object} object |
46 */ | 58 */ |
47 flavorChanged(object) { | 59 flavorChanged(object) { |
| 60 this._showBlackboxed = false; |
48 this._update(); | 61 this._update(); |
49 } | 62 } |
50 | 63 |
51 _update() { | 64 _update() { |
52 var details = UI.context.flavor(SDK.DebuggerPausedDetails); | |
53 | |
54 this.callFrameList.detach(); | |
55 this.callFrameList.clear(); | |
56 this._linkifier.reset(); | |
57 this.element.removeChildren(); | |
58 this._locationPool.disposeAll(); | 65 this._locationPool.disposeAll(); |
59 | 66 |
60 this.callFrameList.show(this.element); | 67 var details = UI.context.flavor(SDK.DebuggerPausedDetails); |
61 delete this._hiddenCallFramesMessageElement; | |
62 this.callFrames = []; | |
63 this._hiddenCallFrames = 0; | |
64 | |
65 if (!details) { | 68 if (!details) { |
66 var infoElement = this.element.createChild('div', 'gray-info-message'); | 69 this._notPausedMessageElement.classList.remove('hidden'); |
67 infoElement.textContent = Common.UIString('Not Paused'); | 70 this._blackboxedMessageElement.classList.add('hidden'); |
| 71 this._list.replaceAllItems([]); |
| 72 this._debuggerModel = null; |
68 UI.context.setFlavor(SDK.DebuggerModel.CallFrame, null); | 73 UI.context.setFlavor(SDK.DebuggerModel.CallFrame, null); |
69 return; | 74 return; |
70 } | 75 } |
| 76 |
71 this._debuggerModel = details.debuggerModel; | 77 this._debuggerModel = details.debuggerModel; |
| 78 this._notPausedMessageElement.classList.add('hidden'); |
| 79 |
| 80 var showBlackboxed = this._showBlackboxed || |
| 81 details.callFrames.every(frame => Bindings.blackboxManager.isBlackboxedR
awLocation(frame.location())); |
| 82 |
| 83 var hiddenCallFramesCount = 0; |
| 84 var items = details.callFrames.map(frame => ({debuggerCallFrame: frame})); |
| 85 if (!showBlackboxed) { |
| 86 items = items.filter( |
| 87 item => !Bindings.blackboxManager.isBlackboxedRawLocation( |
| 88 /** @type {!SDK.DebuggerModel.Location} */ (this._itemLocation(ite
m)))); |
| 89 hiddenCallFramesCount += details.callFrames.length - items.length; |
| 90 } |
| 91 |
72 var asyncStackTrace = details.asyncStackTrace; | 92 var asyncStackTrace = details.asyncStackTrace; |
73 | |
74 this._appendSidebarCallFrames(this._callFramesFromDebugger(details.callFrame
s)); | |
75 var topStackHidden = (this._hiddenCallFrames === this.callFrames.length); | |
76 | |
77 var peviousStackTrace = details.callFrames; | 93 var peviousStackTrace = details.callFrames; |
78 while (asyncStackTrace) { | 94 while (asyncStackTrace) { |
79 var title = ''; | 95 var title = ''; |
80 if (asyncStackTrace.description === 'async function') { | 96 if (asyncStackTrace.description === 'async function') { |
81 var lastPreviousFrame = peviousStackTrace[peviousStackTrace.length - 1]; | 97 var lastPreviousFrame = peviousStackTrace[peviousStackTrace.length - 1]; |
82 var topFrame = asyncStackTrace.callFrames[0]; | 98 var topFrame = asyncStackTrace.callFrames[0]; |
83 var lastPreviousFrameName = UI.beautifyFunctionName(lastPreviousFrame.fu
nctionName); | 99 var lastPreviousFrameName = UI.beautifyFunctionName(lastPreviousFrame.fu
nctionName); |
84 var topFrameName = UI.beautifyFunctionName(topFrame.functionName); | 100 var topFrameName = UI.beautifyFunctionName(topFrame.functionName); |
85 title = topFrameName + ' awaits ' + lastPreviousFrameName; | 101 title = topFrameName + ' awaits ' + lastPreviousFrameName; |
86 } else { | 102 } else { |
87 title = UI.asyncStackTraceLabel(asyncStackTrace.description); | 103 title = UI.asyncStackTraceLabel(asyncStackTrace.description); |
88 } | 104 } |
89 var asyncCallFrame = new Sources.UIList.Item(title, '', true); | 105 |
90 asyncCallFrame.setHoverable(false); | 106 var asyncItems = asyncStackTrace.callFrames.map(frame => ({runtimeCallFram
e: frame})); |
91 asyncCallFrame.element.addEventListener( | 107 if (!showBlackboxed) { |
92 'contextmenu', this._asyncCallFrameContextMenu.bind(this, this.callFra
mes.length), true); | 108 asyncItems = asyncItems.filter( |
93 this._appendSidebarCallFrames( | 109 item => !Bindings.blackboxManager.isBlackboxedRawLocation( |
94 this._callFramesFromRuntime(asyncStackTrace.callFrames, asyncCallFrame
), asyncCallFrame); | 110 /** @type {!SDK.DebuggerModel.Location} */ (this._itemLocation(i
tem)))); |
| 111 hiddenCallFramesCount += asyncStackTrace.callFrames.length - asyncItems.
length; |
| 112 } |
| 113 if (asyncItems.length) { |
| 114 items.push({asyncStackHeader: title}); |
| 115 items = items.concat(asyncItems); |
| 116 } |
| 117 |
95 peviousStackTrace = asyncStackTrace.callFrames; | 118 peviousStackTrace = asyncStackTrace.callFrames; |
96 asyncStackTrace = asyncStackTrace.parent; | 119 asyncStackTrace = asyncStackTrace.parent; |
97 } | 120 } |
98 | 121 |
99 if (topStackHidden) | 122 if (!hiddenCallFramesCount) { |
100 this._revealHiddenCallFrames(); | 123 this._blackboxedMessageElement.classList.add('hidden'); |
101 if (this._hiddenCallFrames) { | 124 } else { |
102 var element = createElementWithClass('div', 'hidden-callframes-message'); | 125 if (hiddenCallFramesCount === 1) { |
103 if (this._hiddenCallFrames === 1) | 126 this._blackboxedMessageElement.firstChild.textContent = |
104 element.textContent = Common.UIString('1 stack frame is hidden (black-bo
xed).'); | 127 Common.UIString('1 stack frame is hidden (black-boxed).'); |
105 else | 128 } else { |
106 element.textContent = Common.UIString('%d stack frames are hidden (black
-boxed).', this._hiddenCallFrames); | 129 this._blackboxedMessageElement.firstChild.textContent = |
107 element.createTextChild(' '); | 130 Common.UIString('%d stack frames are hidden (black-boxed).', hiddenC
allFramesCount); |
108 var showAllLink = element.createChild('span', 'link'); | 131 } |
109 showAllLink.textContent = Common.UIString('Show'); | 132 this._blackboxedMessageElement.classList.remove('hidden'); |
110 showAllLink.addEventListener('click', this._revealHiddenCallFrames.bind(th
is), false); | |
111 this.element.insertBefore(element, this.element.firstChild); | |
112 this._hiddenCallFramesMessageElement = element; | |
113 } | 133 } |
114 this._selectNextVisibleCallFrame(0); | 134 |
| 135 this._list.replaceAllItems(items); |
| 136 this._list.selectNextItem(true /* canWrap */, false /* center */); |
115 } | 137 } |
116 | 138 |
117 /** | 139 /** |
118 * @param {!Array.<!SDK.DebuggerModel.CallFrame>} callFrames | 140 * @override |
119 * @return {!Array<!Sources.CallStackSidebarPane.CallFrame>} | 141 * @param {!Sources.CallStackSidebarPane.Item} item |
| 142 * @return {!Element} |
120 */ | 143 */ |
121 _callFramesFromDebugger(callFrames) { | 144 createElementForItem(item) { |
122 var callFrameItems = []; | 145 var element = createElementWithClass('div', 'call-frame-item'); |
123 for (var i = 0, n = callFrames.length; i < n; ++i) { | 146 element.createChild('div', 'call-frame-item-title').textContent = this._item
Title(item); |
124 var callFrame = callFrames[i]; | 147 if (item.asyncStackHeader) |
125 var callFrameItem = new Sources.CallStackSidebarPane.CallFrame( | 148 element.classList.add('async-header'); |
126 callFrame.functionName, callFrame.location(), this._linkifier, callFra
me, this._locationPool); | 149 |
127 callFrameItem.element.addEventListener('click', this._callFrameSelected.bi
nd(this, callFrameItem), false); | 150 var location = this._itemLocation(item); |
128 callFrameItems.push(callFrameItem); | 151 if (location) { |
| 152 if (Bindings.blackboxManager.isBlackboxedRawLocation(location)) |
| 153 element.classList.add('blackboxed-call-frame'); |
| 154 |
| 155 /** |
| 156 * @param {!Bindings.LiveLocation} liveLocation |
| 157 */ |
| 158 function updateLocation(liveLocation) { |
| 159 var uiLocation = liveLocation.uiLocation(); |
| 160 if (!uiLocation) |
| 161 return; |
| 162 var text = uiLocation.linkText(); |
| 163 linkElement.textContent = text.trimMiddle(30); |
| 164 linkElement.title = text; |
| 165 } |
| 166 |
| 167 var linkElement = element.createChild('div', 'call-frame-location'); |
| 168 Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(location, up
dateLocation, this._locationPool); |
129 } | 169 } |
130 return callFrameItems; | 170 |
| 171 element.appendChild(UI.Icon.create('smallicon-thick-right-arrow', 'selected-
call-frame-icon')); |
| 172 return element; |
131 } | 173 } |
132 | 174 |
133 /** | 175 /** |
134 * @param {!Array<!Protocol.Runtime.CallFrame>} callFrames | 176 * @override |
135 * @param {!Sources.UIList.Item} asyncCallFrameItem | 177 * @param {!Sources.CallStackSidebarPane.Item} item |
136 * @return {!Array<!Sources.CallStackSidebarPane.CallFrame>} | 178 * @return {number} |
137 */ | 179 */ |
138 _callFramesFromRuntime(callFrames, asyncCallFrameItem) { | 180 heightForItem(item) { |
139 var callFrameItems = []; | 181 console.assert(false); // Should not be called. |
140 for (var i = 0, n = callFrames.length; i < n; ++i) { | 182 return 0; |
141 var callFrame = callFrames[i]; | |
142 var location = new SDK.DebuggerModel.Location( | |
143 this._debuggerModel, callFrame.scriptId, callFrame.lineNumber, callFra
me.columnNumber); | |
144 var callFrameItem = new Sources.CallStackSidebarPane.CallFrame( | |
145 callFrame.functionName, location, this._linkifier, null, this._locatio
nPool, asyncCallFrameItem); | |
146 callFrameItem.element.addEventListener('click', this._asyncCallFrameClicke
d.bind(this, callFrameItem), false); | |
147 callFrameItems.push(callFrameItem); | |
148 } | |
149 return callFrameItems; | |
150 } | 183 } |
151 | 184 |
152 /** | 185 /** |
153 * @param {!Array.<!Sources.CallStackSidebarPane.CallFrame>} callFrames | 186 * @override |
154 * @param {!Sources.UIList.Item=} asyncCallFrameItem | 187 * @param {!Sources.CallStackSidebarPane.Item} item |
| 188 * @return {boolean} |
155 */ | 189 */ |
156 _appendSidebarCallFrames(callFrames, asyncCallFrameItem) { | 190 isItemSelectable(item) { |
157 if (asyncCallFrameItem) | 191 return !!item.debuggerCallFrame; |
158 this.callFrameList.addItem(asyncCallFrameItem); | |
159 | |
160 var allCallFramesHidden = true; | |
161 for (var i = 0, n = callFrames.length; i < n; ++i) { | |
162 var callFrameItem = callFrames[i]; | |
163 callFrameItem.element.addEventListener('contextmenu', this._callFrameConte
xtMenu.bind(this, callFrameItem), true); | |
164 this.callFrames.push(callFrameItem); | |
165 | |
166 if (Bindings.blackboxManager.isBlackboxedRawLocation(callFrameItem._locati
on)) { | |
167 callFrameItem.setHidden(true); | |
168 callFrameItem.setDimmed(true); | |
169 ++this._hiddenCallFrames; | |
170 } else { | |
171 this.callFrameList.addItem(callFrameItem); | |
172 allCallFramesHidden = false; | |
173 } | |
174 } | |
175 if (allCallFramesHidden && asyncCallFrameItem) { | |
176 asyncCallFrameItem.setHidden(true); | |
177 asyncCallFrameItem.element.remove(); | |
178 } | |
179 } | |
180 | |
181 _revealHiddenCallFrames() { | |
182 if (!this._hiddenCallFrames) | |
183 return; | |
184 this._hiddenCallFrames = 0; | |
185 this.callFrameList.clear(); | |
186 for (var i = 0; i < this.callFrames.length; ++i) { | |
187 var callFrame = this.callFrames[i]; | |
188 if (callFrame._asyncCallFrame) { | |
189 callFrame._asyncCallFrame.setHidden(false); | |
190 if (i && callFrame._asyncCallFrame !== this.callFrames[i - 1]._asyncCall
Frame) | |
191 this.callFrameList.addItem(callFrame._asyncCallFrame); | |
192 } | |
193 callFrame.setHidden(false); | |
194 this.callFrameList.addItem(callFrame); | |
195 } | |
196 if (this._hiddenCallFramesMessageElement) { | |
197 this._hiddenCallFramesMessageElement.remove(); | |
198 delete this._hiddenCallFramesMessageElement; | |
199 } | |
200 } | 192 } |
201 | 193 |
202 /** | 194 /** |
203 * @param {!Sources.CallStackSidebarPane.CallFrame} callFrame | 195 * @override |
| 196 * @param {?Sources.CallStackSidebarPane.Item} from |
| 197 * @param {?Sources.CallStackSidebarPane.Item} to |
| 198 * @param {?Element} fromElement |
| 199 * @param {?Element} toElement |
| 200 */ |
| 201 selectedItemChanged(from, to, fromElement, toElement) { |
| 202 if (fromElement) |
| 203 fromElement.classList.remove('selected'); |
| 204 if (toElement) |
| 205 toElement.classList.add('selected'); |
| 206 |
| 207 if (!to) |
| 208 return; |
| 209 |
| 210 var oldCallFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame); |
| 211 if (oldCallFrame === to.debuggerCallFrame) { |
| 212 var uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation
(oldCallFrame.location()); |
| 213 Common.Revealer.reveal(uiLocation); |
| 214 return; |
| 215 } |
| 216 |
| 217 UI.context.setFlavor(SDK.DebuggerModel.CallFrame, to.debuggerCallFrame); |
| 218 this._debuggerModel.setSelectedCallFrame(to.debuggerCallFrame); |
| 219 } |
| 220 |
| 221 /** |
| 222 * @param {!Sources.CallStackSidebarPane.Item} item |
| 223 * @return {string} |
| 224 */ |
| 225 _itemTitle(item) { |
| 226 if (item.debuggerCallFrame) |
| 227 return UI.beautifyFunctionName(item.debuggerCallFrame.functionName); |
| 228 if (item.runtimeCallFrame) |
| 229 return UI.beautifyFunctionName(item.runtimeCallFrame.functionName); |
| 230 return item.asyncStackHeader || ''; |
| 231 } |
| 232 |
| 233 /** |
| 234 * @param {!Sources.CallStackSidebarPane.Item} item |
| 235 * @return {?SDK.DebuggerModel.Location} |
| 236 */ |
| 237 _itemLocation(item) { |
| 238 if (item.debuggerCallFrame) |
| 239 return item.debuggerCallFrame.location(); |
| 240 if (item.runtimeCallFrame) { |
| 241 return new SDK.DebuggerModel.Location( |
| 242 this._debuggerModel, item.runtimeCallFrame.scriptId, item.runtimeCallF
rame.lineNumber, |
| 243 item.runtimeCallFrame.columnNumber); |
| 244 } |
| 245 return null; |
| 246 } |
| 247 |
| 248 /** |
| 249 * @return {!Element} |
| 250 */ |
| 251 _createBlackboxedMessageElement() { |
| 252 var element = createElementWithClass('div', 'blackboxed-message'); |
| 253 element.createChild('span'); |
| 254 var showAllLink = element.createChild('span', 'link'); |
| 255 showAllLink.textContent = Common.UIString('Show'); |
| 256 showAllLink.addEventListener('click', () => { |
| 257 this._showBlackboxed = true; |
| 258 this._update(); |
| 259 }, false); |
| 260 return element; |
| 261 } |
| 262 |
| 263 /** |
204 * @param {!Event} event | 264 * @param {!Event} event |
205 */ | 265 */ |
206 _callFrameContextMenu(callFrame, event) { | 266 _onContextMenu(event) { |
| 267 var item = this._list.itemForNode(/** @type {?Node} */ (event.target)); |
| 268 if (!item) |
| 269 return; |
207 var contextMenu = new UI.ContextMenu(event); | 270 var contextMenu = new UI.ContextMenu(event); |
208 var debuggerCallFrame = callFrame._debuggerCallFrame; | 271 if (item.debuggerCallFrame) |
209 if (debuggerCallFrame) { | 272 contextMenu.appendItem(Common.UIString.capitalize('Restart ^frame'), () =>
item.debuggerCallFrame.restart()); |
210 contextMenu.appendItem( | 273 contextMenu.appendItem(Common.UIString.capitalize('Copy ^stack ^trace'), thi
s._copyStackTrace.bind(this)); |
211 Common.UIString.capitalize('Restart ^frame'), debuggerCallFrame.restar
t.bind(debuggerCallFrame)); | 274 var location = this._itemLocation(item); |
| 275 if (location) { |
| 276 var uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation
(location); |
| 277 this.appendBlackboxURLContextMenuItems(contextMenu, uiLocation.uiSourceCod
e); |
212 } | 278 } |
213 | |
214 contextMenu.appendItem(Common.UIString.capitalize('Copy ^stack ^trace'), thi
s._copyStackTrace.bind(this)); | |
215 | |
216 var uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(c
allFrame._location); | |
217 this.appendBlackboxURLContextMenuItems(contextMenu, uiLocation.uiSourceCode)
; | |
218 | |
219 contextMenu.show(); | 279 contextMenu.show(); |
220 } | 280 } |
221 | 281 |
222 /** | 282 /** |
223 * @param {number} index | |
224 * @param {!Event} event | 283 * @param {!Event} event |
225 */ | 284 */ |
226 _asyncCallFrameContextMenu(index, event) { | 285 _onClick(event) { |
227 for (; index < this.callFrames.length; ++index) { | 286 var item = this._list.itemForNode(/** @type {?Node} */ (event.target)); |
228 var callFrame = this.callFrames[index]; | 287 if (!item || !item.runtimeCallFrame) |
229 if (!callFrame.isHidden()) { | 288 return; |
230 this._callFrameContextMenu(callFrame, event); | 289 var location = this._itemLocation(item); |
231 break; | 290 if (!location) |
232 } | 291 return; |
233 } | 292 Common.Revealer.reveal(Bindings.debuggerWorkspaceBinding.rawLocationToUILoca
tion(location)); |
234 } | 293 } |
235 | 294 |
236 /** | 295 /** |
237 * @param {!UI.ContextMenu} contextMenu | 296 * @param {!UI.ContextMenu} contextMenu |
238 * @param {!Workspace.UISourceCode} uiSourceCode | 297 * @param {!Workspace.UISourceCode} uiSourceCode |
239 */ | 298 */ |
240 appendBlackboxURLContextMenuItems(contextMenu, uiSourceCode) { | 299 appendBlackboxURLContextMenuItems(contextMenu, uiSourceCode) { |
241 var binding = Persistence.persistence.binding(uiSourceCode); | 300 var binding = Persistence.persistence.binding(uiSourceCode); |
242 if (binding) | 301 if (binding) |
243 uiSourceCode = binding.network; | 302 uiSourceCode = binding.network; |
(...skipping 20 matching lines...) Expand all Loading... |
264 Common.UIString.capitalize('Stop blackboxing ^all ^content ^scripts'
), | 323 Common.UIString.capitalize('Stop blackboxing ^all ^content ^scripts'
), |
265 manager.blackboxContentScripts.bind(manager)); | 324 manager.blackboxContentScripts.bind(manager)); |
266 } else { | 325 } else { |
267 contextMenu.appendItem( | 326 contextMenu.appendItem( |
268 Common.UIString.capitalize('Blackbox ^all ^content ^scripts'), | 327 Common.UIString.capitalize('Blackbox ^all ^content ^scripts'), |
269 manager.unblackboxContentScripts.bind(manager)); | 328 manager.unblackboxContentScripts.bind(manager)); |
270 } | 329 } |
271 } | 330 } |
272 } | 331 } |
273 | 332 |
274 _asyncStackTracesStateChanged() { | |
275 var enabled = Common.moduleSetting('enableAsyncStackTraces').get(); | |
276 if (!enabled && this.callFrames) | |
277 this._removeAsyncCallFrames(); | |
278 } | |
279 | |
280 _removeAsyncCallFrames() { | |
281 var shouldSelectTopFrame = false; | |
282 var lastSyncCallFrameIndex = -1; | |
283 for (var i = 0; i < this.callFrames.length; ++i) { | |
284 var callFrame = this.callFrames[i]; | |
285 if (callFrame._asyncCallFrame) { | |
286 if (callFrame.isSelected()) | |
287 shouldSelectTopFrame = true; | |
288 callFrame._asyncCallFrame.element.remove(); | |
289 callFrame.element.remove(); | |
290 } else { | |
291 lastSyncCallFrameIndex = i; | |
292 } | |
293 } | |
294 this.callFrames.length = lastSyncCallFrameIndex + 1; | |
295 if (shouldSelectTopFrame) | |
296 this._selectNextVisibleCallFrame(0); | |
297 } | |
298 | |
299 /** | 333 /** |
300 * @return {boolean} | 334 * @return {boolean} |
301 */ | 335 */ |
302 _selectNextCallFrameOnStack() { | 336 _selectNextCallFrameOnStack() { |
303 var index = this._selectedCallFrameIndex(); | 337 return this._list.selectNextItem(false /* canWrap */, false /* center */); |
304 if (index === -1) | |
305 return false; | |
306 return this._selectNextVisibleCallFrame(index + 1); | |
307 } | 338 } |
308 | 339 |
309 /** | 340 /** |
310 * @return {boolean} | 341 * @return {boolean} |
311 */ | 342 */ |
312 _selectPreviousCallFrameOnStack() { | 343 _selectPreviousCallFrameOnStack() { |
313 var index = this._selectedCallFrameIndex(); | 344 return this._list.selectPreviousItem(false /* canWrap */, false /* center */
); |
314 if (index === -1) | 345 } |
315 return false; | 346 |
316 return this._selectNextVisibleCallFrame(index - 1, true); | 347 _copyStackTrace() { |
| 348 var text = []; |
| 349 for (var i = 0; i < this._list.length(); i++) { |
| 350 var item = this._list.itemAtIndex(i); |
| 351 var itemText = this._itemTitle(item); |
| 352 var location = this._itemLocation(item); |
| 353 if (location) { |
| 354 var uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocati
on(location); |
| 355 itemText += ' (' + uiLocation.linkText() + ')'; |
| 356 } |
| 357 text.push(itemText); |
| 358 } |
| 359 InspectorFrontendHost.copyText(text.join('\n')); |
317 } | 360 } |
318 | 361 |
319 /** | 362 /** |
320 * @param {number} index | |
321 * @param {boolean=} backward | |
322 * @return {boolean} | |
323 */ | |
324 _selectNextVisibleCallFrame(index, backward) { | |
325 while (0 <= index && index < this.callFrames.length) { | |
326 var callFrame = this.callFrames[index]; | |
327 if (!callFrame.isHidden() && !callFrame.isLabel() && !callFrame._asyncCall
Frame) { | |
328 this._callFrameSelected(callFrame); | |
329 return true; | |
330 } | |
331 index += backward ? -1 : 1; | |
332 } | |
333 return false; | |
334 } | |
335 | |
336 /** | |
337 * @return {number} | |
338 */ | |
339 _selectedCallFrameIndex() { | |
340 if (!this._debuggerModel) | |
341 return -1; | |
342 var selectedCallFrame = this._debuggerModel.selectedCallFrame(); | |
343 if (!selectedCallFrame) | |
344 return -1; | |
345 for (var i = 0; i < this.callFrames.length; ++i) { | |
346 if (this.callFrames[i]._debuggerCallFrame === selectedCallFrame) | |
347 return i; | |
348 } | |
349 return -1; | |
350 } | |
351 | |
352 /** | |
353 * @param {!Sources.CallStackSidebarPane.CallFrame} callFrameItem | |
354 */ | |
355 _asyncCallFrameClicked(callFrameItem) { | |
356 var uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(c
allFrameItem._location); | |
357 Common.Revealer.reveal(uiLocation); | |
358 } | |
359 | |
360 /** | |
361 * @param {!Sources.CallStackSidebarPane.CallFrame} selectedCallFrame | |
362 */ | |
363 _callFrameSelected(selectedCallFrame) { | |
364 selectedCallFrame.element.scrollIntoViewIfNeeded(); | |
365 var callFrame = selectedCallFrame._debuggerCallFrame; | |
366 | |
367 for (var i = 0; i < this.callFrames.length; ++i) { | |
368 var callFrameItem = this.callFrames[i]; | |
369 callFrameItem.setSelected(callFrameItem === selectedCallFrame); | |
370 if (callFrameItem.isSelected() && callFrameItem.isHidden()) | |
371 this._revealHiddenCallFrames(); | |
372 } | |
373 | |
374 var oldCallFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame); | |
375 if (oldCallFrame === callFrame) { | |
376 var uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation
(callFrame.location()); | |
377 Common.Revealer.reveal(uiLocation); | |
378 return; | |
379 } | |
380 | |
381 UI.context.setFlavor(SDK.DebuggerModel.CallFrame, callFrame); | |
382 callFrame.debuggerModel.setSelectedCallFrame(callFrame); | |
383 } | |
384 | |
385 _copyStackTrace() { | |
386 var text = ''; | |
387 var lastCallFrame = null; | |
388 for (var i = 0; i < this.callFrames.length; ++i) { | |
389 var callFrame = this.callFrames[i]; | |
390 if (callFrame.isHidden()) | |
391 continue; | |
392 if (lastCallFrame && callFrame._asyncCallFrame !== lastCallFrame._asyncCal
lFrame) | |
393 text += callFrame._asyncCallFrame.title() + '\n'; | |
394 text += callFrame.title() + ' (' + callFrame.subtitle() + ')\n'; | |
395 lastCallFrame = callFrame; | |
396 } | |
397 InspectorFrontendHost.copyText(text); | |
398 } | |
399 | |
400 /** | |
401 * @param {function(!Array.<!UI.KeyboardShortcut.Descriptor>, function(!Event=
):boolean)} registerShortcutDelegate | 363 * @param {function(!Array.<!UI.KeyboardShortcut.Descriptor>, function(!Event=
):boolean)} registerShortcutDelegate |
402 */ | 364 */ |
403 registerShortcuts(registerShortcutDelegate) { | 365 registerShortcuts(registerShortcutDelegate) { |
404 registerShortcutDelegate( | 366 registerShortcutDelegate( |
405 UI.ShortcutsScreen.SourcesPanelShortcuts.NextCallFrame, this._selectNext
CallFrameOnStack.bind(this)); | 367 UI.ShortcutsScreen.SourcesPanelShortcuts.NextCallFrame, this._selectNext
CallFrameOnStack.bind(this)); |
406 registerShortcutDelegate( | 368 registerShortcutDelegate( |
407 UI.ShortcutsScreen.SourcesPanelShortcuts.PrevCallFrame, this._selectPrev
iousCallFrameOnStack.bind(this)); | 369 UI.ShortcutsScreen.SourcesPanelShortcuts.PrevCallFrame, this._selectPrev
iousCallFrameOnStack.bind(this)); |
408 } | 370 } |
409 }; | 371 }; |
410 | 372 |
411 /** | 373 /** |
412 * @unrestricted | 374 * @typedef {{ |
| 375 * debuggerCallFrame: (SDK.DebuggerModel.CallFrame|undefined), |
| 376 * asyncStackHeader: (string|undefined), |
| 377 * runtimeCallFrame: (Protocol.Runtime.CallFrame|undefined) |
| 378 * }} |
413 */ | 379 */ |
414 Sources.CallStackSidebarPane.CallFrame = class extends Sources.UIList.Item { | 380 Sources.CallStackSidebarPane.Item; |
415 /** | |
416 * @param {string} functionName | |
417 * @param {!SDK.DebuggerModel.Location} location | |
418 * @param {!Components.Linkifier} linkifier | |
419 * @param {?SDK.DebuggerModel.CallFrame} debuggerCallFrame | |
420 * @param {!Bindings.LiveLocationPool} locationPool | |
421 * @param {!Sources.UIList.Item=} asyncCallFrame | |
422 */ | |
423 constructor(functionName, location, linkifier, debuggerCallFrame, locationPool
, asyncCallFrame) { | |
424 super(UI.beautifyFunctionName(functionName), ''); | |
425 this._location = location; | |
426 this._debuggerCallFrame = debuggerCallFrame; | |
427 this._asyncCallFrame = asyncCallFrame; | |
428 Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(location, this
._update.bind(this), locationPool); | |
429 } | |
430 | |
431 /** | |
432 * @param {!Bindings.LiveLocation} liveLocation | |
433 */ | |
434 _update(liveLocation) { | |
435 var uiLocation = liveLocation.uiLocation(); | |
436 if (!uiLocation) | |
437 return; | |
438 var text = uiLocation.linkText(); | |
439 this.setSubtitle(text.trimMiddle(30)); | |
440 this.subtitleElement.title = text; | |
441 } | |
442 }; | |
OLD | NEW |