| 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 |