Commit bceaccd3 authored by Alexey Kozyatinskiy's avatar Alexey Kozyatinskiy Committed by Commit Bot

[DevTools] migrate CallStackSidebarPane to live locations

New CallStackSidebarPane tries to finally split model and view by using
live locations more.
With new implementation each item maintains own state based on live
location updates and schedule updates of correspond list item.

drive-by: removed BlackboxManager.isRawLocationBlackboxed method.

R=lushnikov@chromium.org

Bug: none
Change-Id: I19adde997652754e5f90869ee41ab41899bf8ec4
Reviewed-on: https://chromium-review.googlesource.com/1168384
Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Reviewed-by: default avatarAndrey Lushnikov <lushnikov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582044}
parent 606b90f2
...@@ -46,6 +46,9 @@ Bindings.BlackboxManager = class { ...@@ -46,6 +46,9 @@ Bindings.BlackboxManager = class {
*/ */
modelAdded(debuggerModel) { modelAdded(debuggerModel) {
this._setBlackboxPatterns(debuggerModel); this._setBlackboxPatterns(debuggerModel);
const sourceMapManager = debuggerModel.sourceMapManager();
sourceMapManager.addEventListener(SDK.SourceMapManager.Events.SourceMapAttached, this._sourceMapAttached, this);
sourceMapManager.addEventListener(SDK.SourceMapManager.Events.SourceMapDetached, this._sourceMapDetached, this);
} }
/** /**
...@@ -54,6 +57,9 @@ Bindings.BlackboxManager = class { ...@@ -54,6 +57,9 @@ Bindings.BlackboxManager = class {
*/ */
modelRemoved(debuggerModel) { modelRemoved(debuggerModel) {
this._clearCacheIfNeeded(); this._clearCacheIfNeeded();
const sourceMapManager = debuggerModel.sourceMapManager();
sourceMapManager.removeEventListener(SDK.SourceMapManager.Events.SourceMapAttached, this._sourceMapAttached, this);
sourceMapManager.removeEventListener(SDK.SourceMapManager.Events.SourceMapDetached, this._sourceMapDetached, this);
} }
_clearCacheIfNeeded() { _clearCacheIfNeeded() {
...@@ -75,32 +81,6 @@ Bindings.BlackboxManager = class { ...@@ -75,32 +81,6 @@ Bindings.BlackboxManager = class {
return debuggerModel.setBlackboxPatterns(patterns); return debuggerModel.setBlackboxPatterns(patterns);
} }
/**
* @param {!SDK.DebuggerModel.Location} location
* @return {boolean}
*/
isBlackboxedRawLocation(location) {
const script = location.script();
if (!script)
return false;
const ranges = script[Bindings.BlackboxManager._blackboxedRanges];
if (!ranges)
return this.isBlackboxedURL(script.sourceURL, script.isContentScript());
const index = ranges.lowerBound(location, comparator);
return !!(index % 2);
/**
* @param {!SDK.DebuggerModel.Location} a
* @param {!Protocol.Debugger.ScriptPosition} b
* @return {number}
*/
function comparator(a, b) {
if (a.lineNumber !== b.lineNumber)
return a.lineNumber - b.lineNumber;
return a.columnNumber - b.columnNumber;
}
}
/** /**
* @param {!Workspace.UISourceCode} uiSourceCode * @param {!Workspace.UISourceCode} uiSourceCode
* @return {boolean} * @return {boolean}
...@@ -130,13 +110,32 @@ Bindings.BlackboxManager = class { ...@@ -130,13 +110,32 @@ Bindings.BlackboxManager = class {
return isBlackboxed; return isBlackboxed;
} }
/**
* @param {!Common.Event} event
*/
_sourceMapAttached(event) {
const script = /** @type {!SDK.Script} */ (event.data.client);
const sourceMap = /** @type {!SDK.SourceMap} */ (event.data.sourceMap);
this._updateScriptRanges(script, sourceMap);
}
/**
* @param {!Common.Event} event
*/
_sourceMapDetached(event) {
const script = /** @type {!SDK.Script} */ (event.data.client);
this._updateScriptRanges(script, null);
}
/** /**
* @param {!SDK.Script} script * @param {!SDK.Script} script
* @param {?SDK.SourceMap} sourceMap * @param {?SDK.SourceMap} sourceMap
* @return {!Promise<undefined>} * @return {!Promise<undefined>}
*/ */
async sourceMapLoaded(script, sourceMap) { async _updateScriptRanges(script, sourceMap) {
const hasBlackboxedMappings = sourceMap ? sourceMap.sourceURLs().some(url => this.isBlackboxedURL(url)) : false; let hasBlackboxedMappings = false;
if (!Bindings.blackboxManager.isBlackboxedURL(script.sourceURL, script.isContentScript()))
hasBlackboxedMappings = sourceMap ? sourceMap.sourceURLs().some(url => this.isBlackboxedURL(url)) : false;
if (!hasBlackboxedMappings) { if (!hasBlackboxedMappings) {
if (script[Bindings.BlackboxManager._blackboxedRanges] && await script.setBlackboxedRanges([])) if (script[Bindings.BlackboxManager._blackboxedRanges] && await script.setBlackboxedRanges([]))
delete script[Bindings.BlackboxManager._blackboxedRanges]; delete script[Bindings.BlackboxManager._blackboxedRanges];
...@@ -274,8 +273,9 @@ Bindings.BlackboxManager = class { ...@@ -274,8 +273,9 @@ Bindings.BlackboxManager = class {
const promises = []; const promises = [];
for (const debuggerModel of SDK.targetManager.models(SDK.DebuggerModel)) { for (const debuggerModel of SDK.targetManager.models(SDK.DebuggerModel)) {
promises.push(this._setBlackboxPatterns(debuggerModel)); promises.push(this._setBlackboxPatterns(debuggerModel));
const sourceMapManager = debuggerModel.sourceMapManager();
for (const script of debuggerModel.scripts()) { for (const script of debuggerModel.scripts()) {
promises.push(this.sourceMapLoaded(script, this._debuggerWorkspaceBinding.sourceMapForScript(script)) promises.push(this._updateScriptRanges(script, sourceMapManager.sourceMapForClient(script))
.then(() => this._debuggerWorkspaceBinding.updateLocations(script))); .then(() => this._debuggerWorkspaceBinding.updateLocations(script)));
} }
} }
......
...@@ -213,7 +213,6 @@ Bindings.CompilerScriptMapping = class { ...@@ -213,7 +213,6 @@ Bindings.CompilerScriptMapping = class {
if (Bindings.blackboxManager.isBlackboxedURL(script.sourceURL, script.isContentScript())) if (Bindings.blackboxManager.isBlackboxedURL(script.sourceURL, script.isContentScript()))
return; return;
Bindings.blackboxManager.sourceMapLoaded(script, sourceMap);
this._populateSourceMapSources(script, sourceMap); this._populateSourceMapSources(script, sourceMap);
this._sourceMapAttachedForTest(sourceMap); this._sourceMapAttachedForTest(sourceMap);
......
...@@ -180,16 +180,6 @@ Bindings.DebuggerWorkspaceBinding = class { ...@@ -180,16 +180,6 @@ Bindings.DebuggerWorkspaceBinding = class {
return modelData._compilerMapping.sourceMapForScript(script); return modelData._compilerMapping.sourceMapForScript(script);
} }
/**
* @param {!SDK.Script} script
*/
maybeLoadSourceMap(script) {
const modelData = this._debuggerModelToData.get(script.debuggerModel);
if (!modelData)
return;
modelData._compilerMapping.maybeLoadSourceMap(script);
}
/** /**
* @param {!Common.Event} event * @param {!Common.Event} event
*/ */
...@@ -390,7 +380,8 @@ Bindings.DebuggerWorkspaceBinding.Location = class extends Bindings.LiveLocation ...@@ -390,7 +380,8 @@ Bindings.DebuggerWorkspaceBinding.Location = class extends Bindings.LiveLocation
* @return {boolean} * @return {boolean}
*/ */
isBlackboxed() { isBlackboxed() {
return Bindings.blackboxManager.isBlackboxedRawLocation(this._rawLocation); const uiLocation = this.uiLocation();
return uiLocation ? Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode) : false;
} }
}; };
......
...@@ -43,7 +43,6 @@ Components.JSPresentationUtils.buildStackTracePreviewContents = function( ...@@ -43,7 +43,6 @@ Components.JSPresentationUtils.buildStackTracePreviewContents = function(
element.style.display = 'inline-block'; element.style.display = 'inline-block';
const shadowRoot = UI.createShadowRootWithCoreStyles(element, 'components/jsUtils.css'); const shadowRoot = UI.createShadowRootWithCoreStyles(element, 'components/jsUtils.css');
const contentElement = shadowRoot.createChild('table', 'stack-preview-container'); const contentElement = shadowRoot.createChild('table', 'stack-preview-container');
const debuggerModel = target ? target.model(SDK.DebuggerModel) : null;
let totalHiddenCallFramesCount = 0; let totalHiddenCallFramesCount = 0;
/** /**
...@@ -59,15 +58,11 @@ Components.JSPresentationUtils.buildStackTracePreviewContents = function( ...@@ -59,15 +58,11 @@ Components.JSPresentationUtils.buildStackTracePreviewContents = function(
const link = linkifier.maybeLinkifyConsoleCallFrame(target, stackFrame); const link = linkifier.maybeLinkifyConsoleCallFrame(target, stackFrame);
if (link) { if (link) {
link.addEventListener('contextmenu', populateContextMenu.bind(null, link)); link.addEventListener('contextmenu', populateContextMenu.bind(null, link));
if (debuggerModel) { const uiLocation = Components.Linkifier.uiLocation(link);
const location = debuggerModel.createRawLocationByScriptId( if (uiLocation && Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode)) {
stackFrame.scriptId, stackFrame.lineNumber, stackFrame.columnNumber); row.classList.add('blackboxed');
if (location && Bindings.blackboxManager.isBlackboxedRawLocation(location)) { ++hiddenCallFrames;
row.classList.add('blackboxed');
++hiddenCallFrames;
}
} }
row.createChild('td').textContent = ' @ '; row.createChild('td').textContent = ' @ ';
row.createChild('td').appendChild(link); row.createChild('td').appendChild(link);
} }
......
...@@ -52,12 +52,14 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { ...@@ -52,12 +52,14 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
this.contentElement.appendChild(this._showMoreMessageElement); this.contentElement.appendChild(this._showMoreMessageElement);
this._showBlackboxed = false; this._showBlackboxed = false;
Bindings.blackboxManager.addChangeListener(this._update.bind(this));
this._locationPool = new Bindings.LiveLocationPool(); this._locationPool = new Bindings.LiveLocationPool();
this._updateThrottler = new Common.Throttler(100); this._updateThrottler = new Common.Throttler(100);
this._maxAsyncStackChainDepth = Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth; this._maxAsyncStackChainDepth = Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth;
this._update(); this._update();
this._updateItemThrottler = new Common.Throttler(100);
this._scheduledForUpdateItems = new Set();
} }
/** /**
...@@ -93,17 +95,12 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { ...@@ -93,17 +95,12 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
let debuggerModel = details.debuggerModel; let debuggerModel = details.debuggerModel;
this._notPausedMessageElement.classList.add('hidden'); this._notPausedMessageElement.classList.add('hidden');
const showBlackboxed = this._showBlackboxed || const items = details.callFrames.map(frame => {
details.callFrames.every(frame => Bindings.blackboxManager.isBlackboxedRawLocation(frame.location())); const item = Sources.CallStackSidebarPane.Item.createForDebuggerCallFrame(
frame, this._locationPool, this._refreshItem.bind(this));
let hiddenCallFramesCount = 0; item[Sources.CallStackSidebarPane._debuggerCallFrameSymbol] = frame;
let items = details.callFrames.map(frame => ({debuggerCallFrame: frame, debuggerModel: debuggerModel})); return item;
if (!showBlackboxed) { });
items = items.filter(
item => !Bindings.blackboxManager.isBlackboxedRawLocation(
/** @type {!SDK.DebuggerModel.Location} */ (this._itemLocation(item))));
hiddenCallFramesCount += details.callFrames.length - items.length;
}
let asyncStackTrace = details.asyncStackTrace; let asyncStackTrace = details.asyncStackTrace;
if (!asyncStackTrace && details.asyncStackTraceId) { if (!asyncStackTrace && details.asyncStackTraceId) {
...@@ -124,19 +121,8 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { ...@@ -124,19 +121,8 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
title = UI.asyncStackTraceLabel(asyncStackTrace.description); title = UI.asyncStackTraceLabel(asyncStackTrace.description);
} }
let asyncItems = items.push(...Sources.CallStackSidebarPane.Item.createItemsForAsyncStack(
asyncStackTrace.callFrames.map(frame => ({runtimeCallFrame: frame, debuggerModel: debuggerModel})); title, debuggerModel, asyncStackTrace.callFrames, this._locationPool, this._refreshItem.bind(this)));
if (!showBlackboxed) {
asyncItems = asyncItems.filter(
item => !Bindings.blackboxManager.isBlackboxedRawLocation(
/** @type {!SDK.DebuggerModel.Location} */ (this._itemLocation(item))));
hiddenCallFramesCount += asyncStackTrace.callFrames.length - asyncItems.length;
}
if (asyncItems.length) {
items.push({asyncStackHeader: title});
items = items.concat(asyncItems);
}
--maxAsyncStackChainDepth; --maxAsyncStackChainDepth;
peviousStackTrace = asyncStackTrace.callFrames; peviousStackTrace = asyncStackTrace.callFrames;
...@@ -150,24 +136,7 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { ...@@ -150,24 +136,7 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
asyncStackTrace = null; asyncStackTrace = null;
} }
} }
if (asyncStackTrace) this._showMoreMessageElement.classList.toggle('hidden', !asyncStackTrace);
this._showMoreMessageElement.classList.remove('hidden');
else
this._showMoreMessageElement.classList.add('hidden');
if (!hiddenCallFramesCount) {
this._blackboxedMessageElement.classList.add('hidden');
} else {
if (hiddenCallFramesCount === 1) {
this._blackboxedMessageElement.firstChild.textContent =
Common.UIString('1 stack frame is hidden (blackboxed).');
} else {
this._blackboxedMessageElement.firstChild.textContent =
Common.UIString('%d stack frames are hidden (blackboxed).', hiddenCallFramesCount);
}
this._blackboxedMessageElement.classList.remove('hidden');
}
this._items.replaceAll(items); this._items.replaceAll(items);
if (this._maxAsyncStackChainDepth === Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth) if (this._maxAsyncStackChainDepth === Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth)
this._list.selectNextItem(true /* canWrap */, false /* center */); this._list.selectNextItem(true /* canWrap */, false /* center */);
...@@ -177,6 +146,42 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { ...@@ -177,6 +146,42 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
_updatedForTest() { _updatedForTest() {
} }
/**
* @param {!Sources.CallStackSidebarPane.Item} item
*/
_refreshItem(item) {
this._scheduledForUpdateItems.add(item);
this._updateItemThrottler.schedule(innerUpdate.bind(this));
/**
* @this {!Sources.CallStackSidebarPane}
* @return {!Promise<undefined>}
*/
function innerUpdate() {
const items = Array.from(this._scheduledForUpdateItems);
this._scheduledForUpdateItems.clear();
this._muteActivateItem = true;
if (!this._showBlackboxed && this._items.every(item => item.isBlackboxed)) {
this._showBlackboxed = true;
this._items.replaceAll(Array.from(this._items));
this._blackboxedMessageElement.classList.toggle('hidden', true);
} else {
const itemsSet = new Set(items);
let hasBlackboxed = false;
for (let i = 0; i < this._items.length; ++i) {
const item = this._items.at(i);
if (itemsSet.has(item))
this._items.replace(i, item);
hasBlackboxed = hasBlackboxed || item.isBlackboxed;
}
this._blackboxedMessageElement.classList.toggle('hidden', this._showBlackboxed || !hasBlackboxed);
}
delete this._muteActivateItem;
return Promise.resolve();
}
}
/** /**
* @override * @override
* @param {!Sources.CallStackSidebarPane.Item} item * @param {!Sources.CallStackSidebarPane.Item} item
...@@ -185,31 +190,16 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { ...@@ -185,31 +190,16 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
createElementForItem(item) { createElementForItem(item) {
const element = createElementWithClass('div', 'call-frame-item'); const element = createElementWithClass('div', 'call-frame-item');
const title = element.createChild('div', 'call-frame-item-title'); const title = element.createChild('div', 'call-frame-item-title');
title.createChild('div', 'call-frame-title-text').textContent = this._itemTitle(item); title.createChild('div', 'call-frame-title-text').textContent = item.title;
if (item.asyncStackHeader) if (item.isAsyncHeader) {
element.classList.add('async-header'); element.classList.add('async-header');
} else {
const location = this._itemLocation(item);
if (location) {
if (Bindings.blackboxManager.isBlackboxedRawLocation(location))
element.classList.add('blackboxed-call-frame');
/**
* @param {!Bindings.LiveLocation} liveLocation
*/
function updateLocation(liveLocation) {
const uiLocation = liveLocation.uiLocation();
if (!uiLocation)
return;
const text = uiLocation.linkText();
linkElement.textContent = text.trimMiddle(30);
linkElement.title = text;
}
const linkElement = element.createChild('div', 'call-frame-location'); const linkElement = element.createChild('div', 'call-frame-location');
Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(location, updateLocation, this._locationPool); linkElement.textContent = item.linkText.trimMiddle(30);
linkElement.title = item.linkText;
element.classList.toggle('blackboxed-call-frame', item.isBlackboxed);
} }
element.classList.toggle('hidden', !this._showBlackboxed && item.isBlackboxed);
element.appendChild(UI.Icon.create('smallicon-thick-right-arrow', 'selected-call-frame-icon')); element.appendChild(UI.Icon.create('smallicon-thick-right-arrow', 'selected-call-frame-icon'));
return element; return element;
} }
...@@ -230,7 +220,7 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { ...@@ -230,7 +220,7 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
* @return {boolean} * @return {boolean}
*/ */
isItemSelectable(item) { isItemSelectable(item) {
return !!item.debuggerCallFrame; return !!item[Sources.CallStackSidebarPane._debuggerCallFrameSymbol];
} }
/** /**
...@@ -249,34 +239,6 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { ...@@ -249,34 +239,6 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
this._activateItem(to); this._activateItem(to);
} }
/**
* @param {!Sources.CallStackSidebarPane.Item} item
* @return {string}
*/
_itemTitle(item) {
if (item.debuggerCallFrame)
return UI.beautifyFunctionName(item.debuggerCallFrame.functionName);
if (item.runtimeCallFrame)
return UI.beautifyFunctionName(item.runtimeCallFrame.functionName);
return item.asyncStackHeader || '';
}
/**
* @param {!Sources.CallStackSidebarPane.Item} item
* @return {?SDK.DebuggerModel.Location}
*/
_itemLocation(item) {
if (item.debuggerCallFrame)
return item.debuggerCallFrame.location();
if (!item.debuggerModel)
return null;
if (item.runtimeCallFrame) {
const frame = item.runtimeCallFrame;
return new SDK.DebuggerModel.Location(item.debuggerModel, frame.scriptId, frame.lineNumber, frame.columnNumber);
}
return null;
}
/** /**
* @return {!Element} * @return {!Element}
*/ */
...@@ -284,11 +246,13 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { ...@@ -284,11 +246,13 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
const element = createElementWithClass('div', 'blackboxed-message'); const element = createElementWithClass('div', 'blackboxed-message');
element.createChild('span'); element.createChild('span');
const showAllLink = element.createChild('span', 'link'); const showAllLink = element.createChild('span', 'link');
showAllLink.textContent = Common.UIString('Show'); showAllLink.textContent = Common.UIString('Show blackboxed frames');
showAllLink.addEventListener('click', () => { showAllLink.addEventListener('click', () => {
this._showBlackboxed = true; this._showBlackboxed = true;
this._update(); for (const item of this._items)
}, false); this._refreshItem(item);
this._blackboxedMessageElement.classList.toggle('hidden', true);
});
return element; return element;
} }
...@@ -315,13 +279,12 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { ...@@ -315,13 +279,12 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
if (!item) if (!item)
return; return;
const contextMenu = new UI.ContextMenu(event); const contextMenu = new UI.ContextMenu(event);
if (item.debuggerCallFrame) const debuggerCallFrame = item[Sources.CallStackSidebarPane._debuggerCallFrameSymbol];
contextMenu.defaultSection().appendItem(Common.UIString('Restart frame'), () => item.debuggerCallFrame.restart()); if (debuggerCallFrame)
contextMenu.defaultSection().appendItem(Common.UIString('Restart frame'), () => debuggerCallFrame.restart());
contextMenu.defaultSection().appendItem(Common.UIString('Copy stack trace'), this._copyStackTrace.bind(this)); contextMenu.defaultSection().appendItem(Common.UIString('Copy stack trace'), this._copyStackTrace.bind(this));
const location = this._itemLocation(item); if (item.uiLocation)
const uiLocation = location ? Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location) : null; this.appendBlackboxURLContextMenuItems(contextMenu, item.uiLocation.uiSourceCode);
if (uiLocation)
this.appendBlackboxURLContextMenuItems(contextMenu, uiLocation.uiSourceCode);
contextMenu.show(); contextMenu.show();
} }
...@@ -338,14 +301,15 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { ...@@ -338,14 +301,15 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
* @param {!Sources.CallStackSidebarPane.Item} item * @param {!Sources.CallStackSidebarPane.Item} item
*/ */
_activateItem(item) { _activateItem(item) {
const location = this._itemLocation(item); const uiLocation = item.uiLocation;
if (!location) if (this._muteActivateItem || !uiLocation)
return; return;
if (item.debuggerCallFrame && UI.context.flavor(SDK.DebuggerModel.CallFrame) !== item.debuggerCallFrame) { const debuggerCallFrame = item[Sources.CallStackSidebarPane._debuggerCallFrameSymbol];
item.debuggerModel.setSelectedCallFrame(item.debuggerCallFrame); if (debuggerCallFrame && UI.context.flavor(SDK.DebuggerModel.CallFrame) !== debuggerCallFrame) {
UI.context.setFlavor(SDK.DebuggerModel.CallFrame, item.debuggerCallFrame); debuggerCallFrame.debuggerModel.setSelectedCallFrame(debuggerCallFrame);
UI.context.setFlavor(SDK.DebuggerModel.CallFrame, debuggerCallFrame);
} else { } else {
Common.Revealer.reveal(Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location)); Common.Revealer.reveal(uiLocation);
} }
} }
...@@ -401,29 +365,19 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView { ...@@ -401,29 +365,19 @@ Sources.CallStackSidebarPane = class extends UI.SimpleView {
_copyStackTrace() { _copyStackTrace() {
const text = []; const text = [];
for (const item of this._items) { for (const item of this._items) {
let itemText = this._itemTitle(item); let itemText = item.title;
const location = this._itemLocation(item); if (item.uiLocation)
const uiLocation = location ? Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location) : null; itemText += ' (' + item.uiLocation.linkText(true /* skipTrim */) + ')';
if (uiLocation)
itemText += ' (' + uiLocation.linkText(true /* skipTrim */) + ')';
text.push(itemText); text.push(itemText);
} }
InspectorFrontendHost.copyText(text.join('\n')); InspectorFrontendHost.copyText(text.join('\n'));
} }
}; };
Sources.CallStackSidebarPane._debuggerCallFrameSymbol = Symbol('debuggerCallFrame');
Sources.CallStackSidebarPane._elementSymbol = Symbol('element');
Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth = 32; Sources.CallStackSidebarPane._defaultMaxAsyncStackChainDepth = 32;
/**
* @typedef {{
* debuggerCallFrame: (SDK.DebuggerModel.CallFrame|undefined),
* asyncStackHeader: (string|undefined),
* runtimeCallFrame: (Protocol.Runtime.CallFrame|undefined),
* debuggerModel: (!SDK.DebuggerModel|undefined)
* }}
*/
Sources.CallStackSidebarPane.Item;
/** /**
* @implements {UI.ActionDelegate} * @implements {UI.ActionDelegate}
*/ */
...@@ -447,3 +401,94 @@ Sources.CallStackSidebarPane.ActionDelegate = class { ...@@ -447,3 +401,94 @@ Sources.CallStackSidebarPane.ActionDelegate = class {
return false; return false;
} }
}; };
Sources.CallStackSidebarPane.Item = class {
/**
* @param {!SDK.DebuggerModel.CallFrame} frame
* @param {!Bindings.LiveLocationPool} locationPool
* @param {function(!Sources.CallStackSidebarPane.Item)} updateDelegate
* @return {!Sources.CallStackSidebarPane.Item}
*/
static createForDebuggerCallFrame(frame, locationPool, updateDelegate) {
const item = new Sources.CallStackSidebarPane.Item(UI.beautifyFunctionName(frame.functionName), updateDelegate);
Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(
frame.location(), item._update.bind(item), locationPool);
return item;
}
/**
* @param {string} title
* @param {?SDK.DebuggerModel} debuggerModel
* @param {!Array<!Protocol.Runtime.CallFrame>} frames
* @param {!Bindings.LiveLocationPool} locationPool
* @param {function(!Sources.CallStackSidebarPane.Item)} updateDelegate
* @return {!Array<!Sources.CallStackSidebarPane.Item>}
*/
static createItemsForAsyncStack(title, debuggerModel, frames, locationPool, updateDelegate) {
const whiteboxedItemsSymbol = Symbol('whiteboxedItems');
const asyncHeaderItem = new Sources.CallStackSidebarPane.Item(title, updateDelegate);
asyncHeaderItem[whiteboxedItemsSymbol] = new Set();
asyncHeaderItem.isAsyncHeader = true;
const asyncFrameItems = frames.map(frame => {
const item = new Sources.CallStackSidebarPane.Item(UI.beautifyFunctionName(frame.functionName), update);
const rawLocation = debuggerModel ?
debuggerModel.createRawLocationByScriptId(frame.scriptId, frame.lineNumber, frame.columnNumber) :
null;
if (!rawLocation) {
item.linkText = (frame.url || '<unknown>') + ':' + (frame.lineNumber + 1);
item.updateDelegate(item);
} else {
Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(
rawLocation, item._update.bind(item), locationPool);
}
return item;
});
updateDelegate(asyncHeaderItem);
return [asyncHeaderItem, ...asyncFrameItems];
/**
* @param {!Sources.CallStackSidebarPane.Item} item
*/
function update(item) {
updateDelegate(item);
let shouldUpdate = false;
const items = asyncHeaderItem[whiteboxedItemsSymbol];
if (item.isBlackboxed) {
items.delete(item);
shouldUpdate = items.size === 0;
} else {
shouldUpdate = items.size === 0;
items.add(item);
}
asyncHeaderItem.isBlackboxed = asyncHeaderItem[whiteboxedItemsSymbol].size === 0;
if (shouldUpdate)
updateDelegate(asyncHeaderItem);
}
}
/**
* @param {string} title
* @param {function(!Sources.CallStackSidebarPane.Item)} updateDelegate
*/
constructor(title, updateDelegate) {
this.isBlackboxed = false;
this.title = title;
this.linkText = '';
this.uiLocation = null;
this.isAsyncHeader = false;
this.updateDelegate = updateDelegate;
}
/**
* @param {!Bindings.LiveLocation} liveLocation
*/
_update(liveLocation) {
const uiLocation = liveLocation.uiLocation();
this.isBlackboxed = uiLocation ? Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode) : false;
this.linkText = uiLocation ? uiLocation.linkText() : '';
this.uiLocation = uiLocation;
this.updateDelegate(this);
}
};
...@@ -299,7 +299,8 @@ SourcesTestRunner.captureStackTraceIntoString = function(callFrames, asyncStackT ...@@ -299,7 +299,8 @@ SourcesTestRunner.captureStackTraceIntoString = function(callFrames, asyncStackT
const location = locationFunction.call(frame); const location = locationFunction.call(frame);
const script = location.script(); const script = location.script();
const uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location); const uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(location);
const isFramework = Bindings.blackboxManager.isBlackboxedRawLocation(location); const isFramework =
uiLocation ? Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode) : false;
if (options.dropFrameworkCallFrames && isFramework) if (options.dropFrameworkCallFrames && isFramework)
continue; continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment