blob: 1e0d72855d553563e89720400b4b3f9047785f6b [file] [log] [blame]
/*
* Copyright (C) 2016 Apple 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. AND ITS CONTRIBUTORS ``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 ITS 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.
*/
WI.HeapSnapshotClusterContentView = class HeapSnapshotClusterContentView extends WI.ClusterContentView
{
constructor(heapSnapshot)
{
super(heapSnapshot);
console.assert(heapSnapshot instanceof WI.HeapSnapshotProxy || heapSnapshot instanceof WI.HeapSnapshotDiffProxy);
this._heapSnapshot = heapSnapshot;
function createPathComponent(displayName, className, identifier)
{
let pathComponent = new WI.HierarchicalPathComponent(displayName, className, identifier, false, true);
pathComponent.addEventListener(WI.HierarchicalPathComponent.Event.SiblingWasSelected, this._pathComponentSelected, this);
pathComponent.comparisonData = heapSnapshot;
return pathComponent;
}
this._shownInitialContent = false;
this._instancesContentView = null;
this._objectGraphContentView = null;
this._instancesPathComponent = createPathComponent.call(this, WI.UIString("Instances"), "heap-snapshot-instances-icon", WI.HeapSnapshotClusterContentView.InstancesIdentifier);
this._objectGraphPathComponent = createPathComponent.call(this, WI.UIString("Object Graph"), "heap-snapshot-object-graph-icon", WI.HeapSnapshotClusterContentView.ObjectGraphIdentifier);
if (this._supportsObjectGraph()) {
this._instancesPathComponent.nextSibling = this._objectGraphPathComponent;
this._objectGraphPathComponent.previousSibling = this._instancesPathComponent;
}
this._currentContentViewSetting = new WI.Setting("heap-snapshot-cluster-current-view", WI.HeapSnapshotClusterContentView.InstancesIdentifier);
}
// Static
static iconStyleClassNameForClassName(className, internal, isObjectType)
{
if (internal)
return "native";
if (isObjectType)
return "object";
switch (className) {
case "Object":
case "Array":
case "Map":
case "Set":
case "WeakMap":
case "WeakSet":
case "Promise":
case "Error":
case "Window":
case "Map Iterator":
case "Set Iterator":
case "Math":
case "JSON":
case "GlobalObject":
return "object";
case "Function":
return "function";
case "RegExp":
return "regex";
case "Number":
return "number";
case "Boolean":
return "boolean";
case "String":
case "string":
return "string";
case "Symbol":
case "symbol":
return "symbol";
}
if (className.endsWith("Prototype"))
return "object";
if (className.endsWith("Element") || className === "Node" || className === "Text")
return "node";
return "native";
}
// Public
get heapSnapshot() { return this._heapSnapshot; }
get instancesContentView()
{
if (!this._instancesContentView)
this._instancesContentView = new WI.HeapSnapshotInstancesContentView(this._heapSnapshot);
return this._instancesContentView;
}
get objectGraphContentView()
{
if (!this._supportsObjectGraph())
return null;
if (!this._objectGraphContentView)
this._objectGraphContentView = new WI.HeapSnapshotObjectGraphContentView(this._heapSnapshot);
return this._objectGraphContentView;
}
get selectionPathComponents()
{
let currentContentView = this._contentViewContainer.currentContentView;
if (!currentContentView)
return [];
let components = [this._pathComponentForContentView(currentContentView)];
return components.concat(currentContentView.selectionPathComponents);
}
shown()
{
super.shown();
if (this._shownInitialContent)
return;
this._showContentViewForIdentifier(this._currentContentViewSetting.value);
}
closed()
{
super.closed();
this._shownInitialContent = false;
}
saveToCookie(cookie)
{
cookie[WI.HeapSnapshotClusterContentView.ContentViewIdentifierCookieKey] = this._currentContentViewSetting.value;
}
restoreFromCookie(cookie)
{
this._showContentViewForIdentifier(cookie[WI.HeapSnapshotClusterContentView.ContentViewIdentifierCookieKey]);
}
showInstances()
{
this._shownInitialContent = true;
return this._showContentViewForIdentifier(WI.HeapSnapshotClusterContentView.InstancesIdentifier);
}
showObjectGraph()
{
this._shownInitialContent = true;
return this._showContentViewForIdentifier(WI.HeapSnapshotClusterContentView.ObjectGraphIdentifier);
}
// Private
_supportsObjectGraph()
{
return this._heapSnapshot instanceof WI.HeapSnapshotProxy;
}
_pathComponentForContentView(contentView)
{
console.assert(contentView);
if (!contentView)
return null;
if (contentView === this._instancesContentView)
return this._instancesPathComponent;
if (contentView === this._objectGraphContentView)
return this._objectGraphPathComponent;
console.error("Unknown contentView.");
return null;
}
_identifierForContentView(contentView)
{
console.assert(contentView);
if (!contentView)
return null;
if (contentView === this._instancesContentView)
return WI.HeapSnapshotClusterContentView.InstancesIdentifier;
if (contentView === this._objectGraphContentView)
return WI.HeapSnapshotClusterContentView.ObjectGraphIdentifier;
console.error("Unknown contentView.");
return null;
}
_showContentViewForIdentifier(identifier)
{
let contentViewToShow = null;
switch (identifier) {
case WI.HeapSnapshotClusterContentView.InstancesIdentifier:
contentViewToShow = this.instancesContentView;
break;
case WI.HeapSnapshotClusterContentView.ObjectGraphIdentifier:
contentViewToShow = this.objectGraphContentView;
break;
}
if (!contentViewToShow)
contentViewToShow = this.instancesContentView;
console.assert(contentViewToShow);
this._shownInitialContent = true;
this._currentContentViewSetting.value = this._identifierForContentView(contentViewToShow);
return this.contentViewContainer.showContentView(contentViewToShow);
}
_pathComponentSelected(event)
{
this._showContentViewForIdentifier(event.data.pathComponent.representedObject);
}
};
WI.HeapSnapshotClusterContentView.ContentViewIdentifierCookieKey = "heap-snapshot-cluster-content-view-identifier";
WI.HeapSnapshotClusterContentView.InstancesIdentifier = "instances";
WI.HeapSnapshotClusterContentView.ObjectGraphIdentifier = "object-graph";