blob: f1ac92297cc45769c9a8cdc5bdc7774859437413 [file] [log] [blame]
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @implements {UI.ContextFlavorListener}
* @unrestricted
*/
Sources.ScopeChainSidebarPane = class extends UI.VBox {
constructor() {
super(true);
this.registerRequiredCSS('sources/scopeChainSidebarPane.css');
this._expandController = new ObjectUI.ObjectPropertiesSectionExpandController();
this._linkifier = new Components.Linkifier();
this._update();
}
/**
* @override
* @param {?Object} object
*/
flavorChanged(object) {
this._update();
}
_update() {
const callFrame = UI.context.flavor(SDK.DebuggerModel.CallFrame);
const details = UI.context.flavor(SDK.DebuggerPausedDetails);
this._linkifier.reset();
Sources.SourceMapNamesResolver.resolveThisObject(callFrame).then(this._innerUpdate.bind(this, details, callFrame));
}
/**
* @param {?SDK.DebuggerPausedDetails} details
* @param {?SDK.DebuggerModel.CallFrame} callFrame
* @param {?SDK.RemoteObject} thisObject
*/
_innerUpdate(details, callFrame, thisObject) {
this.contentElement.removeChildren();
if (!details || !callFrame) {
const infoElement = createElement('div');
infoElement.className = 'gray-info-message';
infoElement.textContent = Common.UIString('Not paused');
this.contentElement.appendChild(infoElement);
return;
}
let foundLocalScope = false;
const scopeChain = callFrame.scopeChain();
for (let i = 0; i < scopeChain.length; ++i) {
const scope = scopeChain[i];
let title = scope.typeName();
let emptyPlaceholder = null;
const extraProperties = [];
switch (scope.type()) {
case Protocol.Debugger.ScopeType.Local:
foundLocalScope = true;
emptyPlaceholder = Common.UIString('No variables');
if (thisObject)
extraProperties.push(new SDK.RemoteObjectProperty('this', thisObject));
if (i === 0) {
const exception = details.exception();
if (exception) {
extraProperties.push(new SDK.RemoteObjectProperty(
Common.UIString('Exception'), exception, undefined, undefined, undefined, undefined, undefined,
true));
}
const returnValue = callFrame.returnValue();
if (returnValue) {
extraProperties.push(new SDK.RemoteObjectProperty(
Common.UIString('Return value'), returnValue, undefined, undefined, undefined, undefined, undefined,
true, callFrame.setReturnValue.bind(callFrame)));
}
}
break;
case Protocol.Debugger.ScopeType.Closure:
const scopeName = scope.name();
if (scopeName)
title = Common.UIString('Closure (%s)', UI.beautifyFunctionName(scopeName));
else
title = Common.UIString('Closure');
emptyPlaceholder = Common.UIString('No variables');
break;
}
let subtitle = scope.description();
if (!title || title === subtitle)
subtitle = undefined;
const titleElement = createElementWithClass('div', 'scope-chain-sidebar-pane-section-header');
titleElement.createChild('div', 'scope-chain-sidebar-pane-section-subtitle').textContent = subtitle;
titleElement.createChild('div', 'scope-chain-sidebar-pane-section-title').textContent = title;
const section = new ObjectUI.ObjectPropertiesSection(
Sources.SourceMapNamesResolver.resolveScopeInObject(scope), titleElement, this._linkifier, emptyPlaceholder,
true, extraProperties);
this._expandController.watchSection(title + (subtitle ? ':' + subtitle : ''), section);
if (scope.type() === Protocol.Debugger.ScopeType.Global)
section.objectTreeElement().collapse();
else if (!foundLocalScope || scope.type() === Protocol.Debugger.ScopeType.Local)
section.objectTreeElement().expand();
section.element.classList.add('scope-chain-sidebar-pane-section');
this.contentElement.appendChild(section.element);
}
this._sidebarPaneUpdatedForTest();
}
_sidebarPaneUpdatedForTest() {
}
};
Sources.ScopeChainSidebarPane._pathSymbol = Symbol('path');