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)); | |
kozy
2017/01/18 23:42:51
We don't really need to rebuild everything on blac
| |
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 throw 'Should not be called ever!'; |
kozy
2017/01/18 23:42:51
Let's replace this with console.assert.
dgozman
2017/01/20 02:04:58
Done.
| |
140 for (var i = 0, n = callFrames.length; i < n; ++i) { | |
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 } | 182 } |
151 | 183 |
152 /** | 184 /** |
153 * @param {!Array.<!Sources.CallStackSidebarPane.CallFrame>} callFrames | 185 * @override |
154 * @param {!Sources.UIList.Item=} asyncCallFrameItem | 186 * @param {!Sources.CallStackSidebarPane.Item} item |
187 * @return {boolean} | |
155 */ | 188 */ |
156 _appendSidebarCallFrames(callFrames, asyncCallFrameItem) { | 189 isItemSelectable(item) { |
157 if (asyncCallFrameItem) | 190 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 } | 191 } |
201 | 192 |
202 /** | 193 /** |
203 * @param {!Sources.CallStackSidebarPane.CallFrame} callFrame | 194 * @override |
195 * @param {?Sources.CallStackSidebarPane.Item} from | |
196 * @param {?Sources.CallStackSidebarPane.Item} to | |
197 * @param {?Element} fromElement | |
198 * @param {?Element} toElement | |
199 */ | |
200 selectedItemChanged(from, to, fromElement, toElement) { | |
201 if (fromElement) | |
202 fromElement.classList.remove('selected'); | |
203 if (toElement) | |
204 toElement.classList.add('selected'); | |
205 | |
206 if (!to) | |
207 return; | |
208 | |
209 var oldCallFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame); | |
210 if (oldCallFrame === to.debuggerCallFrame) { | |
211 var uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation (oldCallFrame.location()); | |
212 Common.Revealer.reveal(uiLocation); | |
213 return; | |
214 } | |
215 | |
216 UI.context.setFlavor(SDK.DebuggerModel.CallFrame, to.debuggerCallFrame); | |
217 this._debuggerModel.setSelectedCallFrame(to.debuggerCallFrame); | |
218 } | |
219 | |
220 /** | |
221 * @param {!Sources.CallStackSidebarPane.Item} item | |
222 * @return {string} | |
223 */ | |
224 _itemTitle(item) { | |
225 if (item.debuggerCallFrame) | |
226 return UI.beautifyFunctionName(item.debuggerCallFrame.functionName); | |
227 if (item.runtimeCallFrame) | |
228 return UI.beautifyFunctionName(item.runtimeCallFrame.functionName); | |
229 return item.asyncStackHeader || ''; | |
230 } | |
231 | |
232 /** | |
233 * @param {!Sources.CallStackSidebarPane.Item} item | |
234 * @return {?SDK.DebuggerModel.Location} | |
235 */ | |
236 _itemLocation(item) { | |
237 if (item.debuggerCallFrame) | |
238 return item.debuggerCallFrame.location(); | |
239 if (item.runtimeCallFrame) { | |
240 return new SDK.DebuggerModel.Location( | |
241 this._debuggerModel, item.runtimeCallFrame.scriptId, item.runtimeCallF rame.lineNumber, | |
242 item.runtimeCallFrame.columnNumber); | |
243 } | |
244 return null; | |
245 } | |
246 | |
247 /** | |
248 * @return {!Element} | |
249 */ | |
250 _createBlackboxedMessageElement() { | |
251 var element = createElementWithClass('div', 'blackboxed-message'); | |
252 element.createChild('span'); | |
253 var showAllLink = element.createChild('span', 'link'); | |
254 showAllLink.textContent = Common.UIString('Show'); | |
255 showAllLink.addEventListener('click', () => { | |
256 this._showBlackboxed = true; | |
257 this._update(); | |
258 }, false); | |
259 return element; | |
260 } | |
261 | |
262 /** | |
204 * @param {!Event} event | 263 * @param {!Event} event |
205 */ | 264 */ |
206 _callFrameContextMenu(callFrame, event) { | 265 _onContextMenu(event) { |
266 var item = this._list.itemForNode(/** @type {?Node} */ (event.target)); | |
267 if (!item) | |
268 return; | |
207 var contextMenu = new UI.ContextMenu(event); | 269 var contextMenu = new UI.ContextMenu(event); |
208 var debuggerCallFrame = callFrame._debuggerCallFrame; | 270 if (item.debuggerCallFrame) |
209 if (debuggerCallFrame) { | 271 contextMenu.appendItem(Common.UIString.capitalize('Restart ^frame'), () => item.debuggerCallFrame.restart()); |
210 contextMenu.appendItem( | 272 contextMenu.appendItem(Common.UIString.capitalize('Copy ^stack ^trace'), thi s._copyStackTrace.bind(this)); |
211 Common.UIString.capitalize('Restart ^frame'), debuggerCallFrame.restar t.bind(debuggerCallFrame)); | 273 var location = this._itemLocation(item); |
274 if (location) { | |
275 var uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation (location); | |
276 this.appendBlackboxURLContextMenuItems(contextMenu, uiLocation.uiSourceCod e); | |
212 } | 277 } |
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(); | 278 contextMenu.show(); |
220 } | 279 } |
221 | 280 |
222 /** | 281 /** |
223 * @param {number} index | |
224 * @param {!Event} event | 282 * @param {!Event} event |
225 */ | 283 */ |
226 _asyncCallFrameContextMenu(index, event) { | 284 _onClick(event) { |
227 for (; index < this.callFrames.length; ++index) { | 285 var item = this._list.itemForNode(/** @type {?Node} */ (event.target)); |
228 var callFrame = this.callFrames[index]; | 286 if (!item || !item.runtimeCallFrame) |
229 if (!callFrame.isHidden()) { | 287 return; |
230 this._callFrameContextMenu(callFrame, event); | 288 var location = this._itemLocation(item); |
231 break; | 289 if (!location) |
232 } | 290 return; |
233 } | 291 Common.Revealer.reveal(Bindings.debuggerWorkspaceBinding.rawLocationToUILoca tion(location)); |
234 } | 292 } |
235 | 293 |
236 /** | 294 /** |
237 * @param {!UI.ContextMenu} contextMenu | 295 * @param {!UI.ContextMenu} contextMenu |
238 * @param {!Workspace.UISourceCode} uiSourceCode | 296 * @param {!Workspace.UISourceCode} uiSourceCode |
239 */ | 297 */ |
240 appendBlackboxURLContextMenuItems(contextMenu, uiSourceCode) { | 298 appendBlackboxURLContextMenuItems(contextMenu, uiSourceCode) { |
241 var binding = Persistence.persistence.binding(uiSourceCode); | 299 var binding = Persistence.persistence.binding(uiSourceCode); |
242 if (binding) | 300 if (binding) |
243 uiSourceCode = binding.network; | 301 uiSourceCode = binding.network; |
(...skipping 20 matching lines...) Expand all Loading... | |
264 Common.UIString.capitalize('Stop blackboxing ^all ^content ^scripts' ), | 322 Common.UIString.capitalize('Stop blackboxing ^all ^content ^scripts' ), |
265 manager.blackboxContentScripts.bind(manager)); | 323 manager.blackboxContentScripts.bind(manager)); |
266 } else { | 324 } else { |
267 contextMenu.appendItem( | 325 contextMenu.appendItem( |
268 Common.UIString.capitalize('Blackbox ^all ^content ^scripts'), | 326 Common.UIString.capitalize('Blackbox ^all ^content ^scripts'), |
269 manager.unblackboxContentScripts.bind(manager)); | 327 manager.unblackboxContentScripts.bind(manager)); |
270 } | 328 } |
271 } | 329 } |
272 } | 330 } |
273 | 331 |
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 /** | 332 /** |
300 * @return {boolean} | 333 * @return {boolean} |
301 */ | 334 */ |
302 _selectNextCallFrameOnStack() { | 335 _selectNextCallFrameOnStack() { |
303 var index = this._selectedCallFrameIndex(); | 336 return this._list.selectNextItem(false /* canWrap */, false /* center */); |
304 if (index === -1) | |
305 return false; | |
306 return this._selectNextVisibleCallFrame(index + 1); | |
307 } | 337 } |
308 | 338 |
309 /** | 339 /** |
310 * @return {boolean} | 340 * @return {boolean} |
311 */ | 341 */ |
312 _selectPreviousCallFrameOnStack() { | 342 _selectPreviousCallFrameOnStack() { |
313 var index = this._selectedCallFrameIndex(); | 343 return this._list.selectPreviousItem(false /* canWrap */, false /* center */ ); |
314 if (index === -1) | 344 } |
315 return false; | 345 |
316 return this._selectNextVisibleCallFrame(index - 1, true); | 346 _copyStackTrace() { |
347 var text = []; | |
348 for (var i = 0; i < this._list.length(); i++) { | |
349 var item = this._list.itemAtIndex(i); | |
350 var itemText = this._itemTitle(item); | |
351 var location = this._itemLocation(item); | |
352 if (location) { | |
353 var uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocati on(location); | |
354 itemText += ' (' + uiLocation.linkText() + ')'; | |
355 } | |
356 text.push(itemText); | |
357 } | |
358 InspectorFrontendHost.copyText(text.join('\n')); | |
317 } | 359 } |
318 | 360 |
319 /** | 361 /** |
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 | 362 * @param {function(!Array.<!UI.KeyboardShortcut.Descriptor>, function(!Event= ):boolean)} registerShortcutDelegate |
402 */ | 363 */ |
403 registerShortcuts(registerShortcutDelegate) { | 364 registerShortcuts(registerShortcutDelegate) { |
404 registerShortcutDelegate( | 365 registerShortcutDelegate( |
405 UI.ShortcutsScreen.SourcesPanelShortcuts.NextCallFrame, this._selectNext CallFrameOnStack.bind(this)); | 366 UI.ShortcutsScreen.SourcesPanelShortcuts.NextCallFrame, this._selectNext CallFrameOnStack.bind(this)); |
406 registerShortcutDelegate( | 367 registerShortcutDelegate( |
407 UI.ShortcutsScreen.SourcesPanelShortcuts.PrevCallFrame, this._selectPrev iousCallFrameOnStack.bind(this)); | 368 UI.ShortcutsScreen.SourcesPanelShortcuts.PrevCallFrame, this._selectPrev iousCallFrameOnStack.bind(this)); |
408 } | 369 } |
409 }; | 370 }; |
410 | 371 |
411 /** | 372 /** |
412 * @unrestricted | 373 * @typedef {{ |
374 * debuggerCallFrame: (SDK.DebuggerModel.CallFrame|undefined), | |
375 * asyncStackHeader: (string|undefined), | |
376 * runtimeCallFrame: (Protocol.Runtime.CallFrame|undefined) | |
377 * }} | |
413 */ | 378 */ |
414 Sources.CallStackSidebarPane.CallFrame = class extends Sources.UIList.Item { | 379 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 |