blob: 60527a9037b19f8df8dd12521b572dd14481b837 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2011 Google Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
Tim van der Lippe8987f8f2020-01-03 15:03:1626
Tim van der Lippefbbf9812020-02-13 14:43:4627import * as Common from '../common/common.js';
28import * as Components from '../components/components.js';
29import * as ObjectUI from '../object_ui/object_ui.js';
30import * as SDK from '../sdk/sdk.js';
31import * as UI from '../ui/ui.js';
32
Paul Lewis39944952020-01-22 15:45:1833import {resolveScopeInObject, resolveThisObject} from './SourceMapNamesResolver.js';
34
Blink Reformat4c46d092018-04-07 15:32:3735/**
Tim van der Lippefbbf9812020-02-13 14:43:4636 * @implements {UI.ContextFlavorListener.ContextFlavorListener}
Blink Reformat4c46d092018-04-07 15:32:3737 * @unrestricted
38 */
Philip Pfaffe674ff272020-04-30 13:55:5239export class ScopeChainSidebarPane extends UI.Widget.VBox {
Blink Reformat4c46d092018-04-07 15:32:3740 constructor() {
41 super(true);
42 this.registerRequiredCSS('sources/scopeChainSidebarPane.css');
Tim van der Lippefbbf9812020-02-13 14:43:4643 this._treeOutline = new ObjectUI.ObjectPropertiesSection.ObjectPropertiesSectionsTreeOutline();
Jack Lynch2938cf32019-11-05 19:24:1244 this._treeOutline.registerRequiredCSS('sources/scopeChainSidebarPane.css');
45 this._treeOutline.setShowSelectionOnKeyboardFocus(/* show */ true);
Tim van der Lippefbbf9812020-02-13 14:43:4646 this._expandController =
47 new ObjectUI.ObjectPropertiesSection.ObjectPropertiesSectionsTreeExpandController(this._treeOutline);
48 this._linkifier = new Components.Linkifier.Linkifier();
Simon Zünd51a46de2020-09-22 13:52:4449 this._infoElement = document.createElement('div');
Jack Lynch2938cf32019-11-05 19:24:1250 this._infoElement.className = 'gray-info-message';
51 this._infoElement.textContent = ls`Not paused`;
52 this._infoElement.tabIndex = -1;
Blink Reformat4c46d092018-04-07 15:32:3753 this._update();
54 }
55
56 /**
57 * @override
58 * @param {?Object} object
59 */
60 flavorChanged(object) {
61 this._update();
62 }
63
Jack Lynch2938cf32019-11-05 19:24:1264 /**
65 * @override
66 */
67 focus() {
68 if (this.hasFocus()) {
69 return;
70 }
71
Tim van der Lipped1a00aa2020-08-19 16:03:5672 if (UI.Context.Context.instance().flavor(SDK.DebuggerModel.DebuggerPausedDetails)) {
Jack Lynch2938cf32019-11-05 19:24:1273 this._treeOutline.forceSelect();
74 }
75 }
76
Simon Zünd51a46de2020-09-22 13:52:4477 /**
78 * @param {!SDK.DebuggerModel.CallFrame} callFrame
Benedikt Meurerfa971632020-10-23 08:42:0579 * @return {!Promise<!Array<!SDK.DebuggerModel.ScopeChainEntry>>}
Simon Zünd51a46de2020-09-22 13:52:4480 */
Benedikt Meurerfa971632020-10-23 08:42:0581 async _getScopeChain(callFrame) {
82 return (await callFrame.sourceScopeChain) || callFrame.scopeChain();
Philip Pfaffef5d825a2020-01-27 16:00:5383 }
84
Blink Reformat4c46d092018-04-07 15:32:3785 _update() {
Tim van der Lipped1a00aa2020-08-19 16:03:5686 const callFrame = UI.Context.Context.instance().flavor(SDK.DebuggerModel.CallFrame);
87 const details = UI.Context.Context.instance().flavor(SDK.DebuggerModel.DebuggerPausedDetails);
Blink Reformat4c46d092018-04-07 15:32:3788 this._linkifier.reset();
Paul Lewis39944952020-01-22 15:45:1889 resolveThisObject(callFrame).then(this._innerUpdate.bind(this, details, callFrame));
Blink Reformat4c46d092018-04-07 15:32:3790 }
91
92 /**
Tim van der Lippefbbf9812020-02-13 14:43:4693 * @param {?SDK.DebuggerModel.DebuggerPausedDetails} details
Blink Reformat4c46d092018-04-07 15:32:3794 * @param {?SDK.DebuggerModel.CallFrame} callFrame
Tim van der Lippefbbf9812020-02-13 14:43:4695 * @param {?SDK.RemoteObject.RemoteObject} thisObject
Blink Reformat4c46d092018-04-07 15:32:3796 */
Benedikt Meurerfa971632020-10-23 08:42:0597 async _innerUpdate(details, callFrame, thisObject) {
Jack Lynch2938cf32019-11-05 19:24:1298 this._treeOutline.removeChildren();
Blink Reformat4c46d092018-04-07 15:32:3799 this.contentElement.removeChildren();
100
101 if (!details || !callFrame) {
Jack Lynch2938cf32019-11-05 19:24:12102 this.contentElement.appendChild(this._infoElement);
Blink Reformat4c46d092018-04-07 15:32:37103 return;
104 }
105
Jack Lynch2938cf32019-11-05 19:24:12106 this.contentElement.appendChild(this._treeOutline.element);
Blink Reformat4c46d092018-04-07 15:32:37107 let foundLocalScope = false;
Benedikt Meurerfa971632020-10-23 08:42:05108 const scopeChain = await this._getScopeChain(callFrame);
Philip Pfaffe674ff272020-04-30 13:55:52109 for (let i = 0; i < scopeChain.length; ++i) {
110 const scope = scopeChain[i];
111 const extraProperties = this._extraPropertiesForScope(scope, details, callFrame, thisObject, i === 0);
Blink Reformat4c46d092018-04-07 15:32:37112
Philip Pfaffe674ff272020-04-30 13:55:52113 if (scope.type() === Protocol.Debugger.ScopeType.Local) {
114 foundLocalScope = true;
115 }
Blink Reformat4c46d092018-04-07 15:32:37116
Philip Pfaffe674ff272020-04-30 13:55:52117 const section = this._createScopeSectionTreeElement(scope, extraProperties);
118 if (scope.type() === Protocol.Debugger.ScopeType.Global) {
119 section.collapse();
120 } else if (!foundLocalScope || scope.type() === Protocol.Debugger.ScopeType.Local) {
121 section.expand();
122 }
Blink Reformat4c46d092018-04-07 15:32:37123
Philip Pfaffe674ff272020-04-30 13:55:52124 this._treeOutline.appendChild(section);
125 if (i === 0) {
126 section.select(/* omitFocus */ true);
Jack Lynch2938cf32019-11-05 19:24:12127 }
Blink Reformat4c46d092018-04-07 15:32:37128 }
129 this._sidebarPaneUpdatedForTest();
130 }
131
Jack Lynch2938cf32019-11-05 19:24:12132 /**
Benedikt Meurer38243f32020-10-08 13:30:04133 * @param {!SDK.DebuggerModel.ScopeChainEntry} scope
Tim van der Lippefbbf9812020-02-13 14:43:46134 * @param {!Array.<!SDK.RemoteObject.RemoteObjectProperty>} extraProperties
Jack Lynch2938cf32019-11-05 19:24:12135 * @return {!ObjectUI.ObjectPropertiesSection.RootElement}
136 */
137 _createScopeSectionTreeElement(scope, extraProperties) {
138 let emptyPlaceholder = null;
139 if (scope.type() === Protocol.Debugger.ScopeType.Local || Protocol.Debugger.ScopeType.Closure) {
140 emptyPlaceholder = ls`No variables`;
141 }
142
143 let title = scope.typeName();
144 if (scope.type() === Protocol.Debugger.ScopeType.Closure) {
145 const scopeName = scope.name();
146 if (scopeName) {
Tim van der Lippefbbf9812020-02-13 14:43:46147 title = ls`Closure (${UI.UIUtils.beautifyFunctionName(scopeName)})`;
Jack Lynch2938cf32019-11-05 19:24:12148 } else {
149 title = ls`Closure`;
150 }
151 }
Simon Zünd51a46de2020-09-22 13:52:44152 /** @type {?string} */
Jack Lynch2938cf32019-11-05 19:24:12153 let subtitle = scope.description();
154 if (!title || title === subtitle) {
Simon Zünd51a46de2020-09-22 13:52:44155 subtitle = null;
Jack Lynch2938cf32019-11-05 19:24:12156 }
Benedikt Meurer723d5432020-10-09 09:02:42157 const icon = scope.icon();
Jack Lynch2938cf32019-11-05 19:24:12158
Tim van der Lippee7f27052020-05-01 15:15:28159 const titleElement = document.createElement('div');
160 titleElement.classList.add('scope-chain-sidebar-pane-section-header');
161 titleElement.classList.add('tree-element-title');
Benedikt Meurer723d5432020-10-09 09:02:42162 if (icon) {
163 const iconElement = document.createElement('img');
164 iconElement.classList.add('scope-chain-sidebar-pane-section-icon');
165 iconElement.src = icon;
166 titleElement.appendChild(iconElement);
167 }
Jack Lynch2938cf32019-11-05 19:24:12168 titleElement.createChild('div', 'scope-chain-sidebar-pane-section-subtitle').textContent = subtitle;
169 titleElement.createChild('div', 'scope-chain-sidebar-pane-section-title').textContent = title;
170
171 const section = new ObjectUI.ObjectPropertiesSection.RootElement(
Paul Lewis39944952020-01-22 15:45:18172 resolveScopeInObject(scope), this._linkifier, emptyPlaceholder,
Jack Lynch2938cf32019-11-05 19:24:12173 /* ignoreHasOwnProperty */ true, extraProperties);
174 section.title = titleElement;
175 section.listItemElement.classList.add('scope-chain-sidebar-pane-section');
Kim-Anh Tran9f22ceb2020-05-27 09:46:54176 section.listItemElement.setAttribute('aria-label', title);
Jack Lynch2938cf32019-11-05 19:24:12177 this._expandController.watchSection(title + (subtitle ? ':' + subtitle : ''), section);
178
179 return section;
180 }
181
182 /**
Benedikt Meurer38243f32020-10-08 13:30:04183 * @param {!SDK.DebuggerModel.ScopeChainEntry} scope
Simon Zünd51a46de2020-09-22 13:52:44184 * @param {!SDK.DebuggerModel.DebuggerPausedDetails} details
185 * @param {!SDK.DebuggerModel.CallFrame} callFrame
Tim van der Lippefbbf9812020-02-13 14:43:46186 * @param {?SDK.RemoteObject.RemoteObject} thisObject
Jack Lynch2938cf32019-11-05 19:24:12187 * @param {boolean} isFirstScope
Tim van der Lippefbbf9812020-02-13 14:43:46188 * @return {!Array.<!SDK.RemoteObject.RemoteObjectProperty>}
Jack Lynch2938cf32019-11-05 19:24:12189 */
190 _extraPropertiesForScope(scope, details, callFrame, thisObject, isFirstScope) {
Kim-Anh Tran9f22ceb2020-05-27 09:46:54191 if (scope.type() !== Protocol.Debugger.ScopeType.Local || callFrame.script.isWasm()) {
Jack Lynch2938cf32019-11-05 19:24:12192 return [];
193 }
194
195 const extraProperties = [];
196 if (thisObject) {
Tim van der Lippefbbf9812020-02-13 14:43:46197 extraProperties.push(new SDK.RemoteObject.RemoteObjectProperty('this', thisObject));
Jack Lynch2938cf32019-11-05 19:24:12198 }
199 if (isFirstScope) {
200 const exception = details.exception();
201 if (exception) {
Tim van der Lippefbbf9812020-02-13 14:43:46202 extraProperties.push(new SDK.RemoteObject.RemoteObjectProperty(
203 Common.UIString.UIString('Exception'), exception, undefined, undefined, undefined, undefined, undefined,
Jack Lynch2938cf32019-11-05 19:24:12204 /* synthetic */ true));
205 }
206 const returnValue = callFrame.returnValue();
207 if (returnValue) {
Tim van der Lippefbbf9812020-02-13 14:43:46208 extraProperties.push(new SDK.RemoteObject.RemoteObjectProperty(
209 Common.UIString.UIString('Return value'), returnValue, undefined, undefined, undefined, undefined,
210 undefined,
Jack Lynch2938cf32019-11-05 19:24:12211 /* synthetic */ true, callFrame.setReturnValue.bind(callFrame)));
212 }
213 }
214
215 return extraProperties;
216 }
217
Blink Reformat4c46d092018-04-07 15:32:37218 _sidebarPaneUpdatedForTest() {
219 }
Tim van der Lippe8987f8f2020-01-03 15:03:16220}
Blink Reformat4c46d092018-04-07 15:32:37221
Paul Lewis39944952020-01-22 15:45:18222export const pathSymbol = Symbol('path');