115e05479c2d0ec8d5c883ae6ac242f7910dbc44
[WebKit.git] / Source / WebCore / inspector / front-end / ScopeChainSidebarPane.js
1 /*
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  */
26
27 WebInspector.ScopeChainSidebarPane = function()
28 {
29     WebInspector.SidebarPane.call(this, WebInspector.UIString("Scope Variables"));
30     this._sections = [];
31     this._expandedSections = {};
32     this._expandedProperties = [];
33 }
34
35 WebInspector.ScopeChainSidebarPane.prototype = {
36     update: function(callFrame)
37     {
38         this.bodyElement.removeChildren();
39
40         if (!callFrame) {
41             var infoElement = document.createElement("div");
42             infoElement.className = "info";
43             infoElement.textContent = WebInspector.UIString("Not Paused");
44             this.bodyElement.appendChild(infoElement);
45             return;
46         }
47
48         for (var i = 0; i < this._sections.length; ++i) {
49             var section = this._sections[i];
50             if (!section.title)
51                 continue;
52             if (section.expanded)
53                 this._expandedSections[section.title] = true;
54             else
55                 delete this._expandedSections[section.title];
56         }
57
58         this._sections = [];
59
60         var foundLocalScope = false;
61         var scopeChain = callFrame.scopeChain;
62         for (var i = 0; i < scopeChain.length; ++i) {
63             var scope = scopeChain[i];
64             var title = null;
65             var subtitle = scope.object.description;
66             var emptyPlaceholder = null;
67             var extraProperties = null;
68
69             switch (scope.type) {
70                 case "local":
71                     foundLocalScope = true;
72                     title = WebInspector.UIString("Local");
73                     emptyPlaceholder = WebInspector.UIString("No Variables");
74                     subtitle = null;
75                     if (callFrame.this)
76                         extraProperties = [ new WebInspector.RemoteObjectProperty("this", WebInspector.RemoteObject.fromPayload(callFrame.this)) ];
77                     if (i == 0) {
78                         var exception = WebInspector.debuggerModel.debuggerPausedDetails.exception;
79                         if (exception) {
80                             extraProperties = extraProperties || [];
81                             extraProperties.push(new WebInspector.RemoteObjectProperty("<exception>", WebInspector.RemoteObject.fromPayload(exception)));
82                         }
83                     }
84                     break;
85                 case "closure":
86                     title = WebInspector.UIString("Closure");
87                     emptyPlaceholder = WebInspector.UIString("No Variables");
88                     subtitle = null;
89                     break;
90                 case "catch":
91                     title = WebInspector.UIString("Catch");
92                     break;
93                 case "with":
94                     title = WebInspector.UIString("With Block");
95                     break;
96                 case "global":
97                     title = WebInspector.UIString("Global");
98                     break;
99             }
100
101             if (!title || title === subtitle)
102                 subtitle = null;
103
104             var section = new WebInspector.ObjectPropertiesSection(WebInspector.RemoteObject.fromPayload(scope.object), title, subtitle, emptyPlaceholder, true, extraProperties, WebInspector.ScopeVariableTreeElement);
105             section.editInSelectedCallFrameWhenPaused = true;
106             section.pane = this;
107
108             if (!foundLocalScope || scope.type === "local" || title in this._expandedSections)
109                 section.expanded = true;
110
111             this._sections.push(section);
112             this.bodyElement.appendChild(section.element);
113         }
114     }
115 }
116
117 WebInspector.ScopeChainSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
118
119 WebInspector.ScopeVariableTreeElement = function(property)
120 {
121     WebInspector.ObjectPropertyTreeElement.call(this, property);
122 }
123
124 WebInspector.ScopeVariableTreeElement.prototype = {
125     onattach: function()
126     {
127         WebInspector.ObjectPropertyTreeElement.prototype.onattach.call(this);
128         if (this.hasChildren && this.propertyIdentifier in this.treeOutline.section.pane._expandedProperties)
129             this.expand();
130     },
131
132     onexpand: function()
133     {
134         this.treeOutline.section.pane._expandedProperties[this.propertyIdentifier] = true;
135     },
136
137     oncollapse: function()
138     {
139         delete this.treeOutline.section.pane._expandedProperties[this.propertyIdentifier];
140     },
141
142     get propertyIdentifier()
143     {
144         if ("_propertyIdentifier" in this)
145             return this._propertyIdentifier;
146         var section = this.treeOutline.section;
147         this._propertyIdentifier = section.title + ":" + (section.subtitle ? section.subtitle + ":" : "") + this.propertyPath;
148         return this._propertyIdentifier;
149     },
150
151     get propertyPath()
152     {
153         if ("_propertyPath" in this)
154             return this._propertyPath;
155
156         var current = this;
157         var result;
158
159         do {
160             if (result)
161                 result = current.property.name + "." + result;
162             else
163                 result = current.property.name;
164             current = current.parent;
165         } while (current && !current.root);
166
167         this._propertyPath = result;
168         return result;
169     }
170 }
171
172 WebInspector.ScopeVariableTreeElement.prototype.__proto__ = WebInspector.ObjectPropertyTreeElement.prototype;