Web Inspector: document Debugger.paused, introduce types for ids in Debugger domain.
[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 details = WebInspector.debuggerModel.debuggerPausedDetails;
79                         var exception = details.reason === WebInspector.ScriptsPanel.BreakReason.Exception ? details.auxData : 0;
80                         if (exception) {
81                             extraProperties = extraProperties || [];
82                             extraProperties.push(new WebInspector.RemoteObjectProperty("<exception>", WebInspector.RemoteObject.fromPayload(exception)));
83                         }
84                     }
85                     break;
86                 case "closure":
87                     title = WebInspector.UIString("Closure");
88                     emptyPlaceholder = WebInspector.UIString("No Variables");
89                     subtitle = null;
90                     break;
91                 case "catch":
92                     title = WebInspector.UIString("Catch");
93                     break;
94                 case "with":
95                     title = WebInspector.UIString("With Block");
96                     break;
97                 case "global":
98                     title = WebInspector.UIString("Global");
99                     break;
100             }
101
102             if (!title || title === subtitle)
103                 subtitle = null;
104
105             var section = new WebInspector.ObjectPropertiesSection(WebInspector.RemoteObject.fromPayload(scope.object), title, subtitle, emptyPlaceholder, true, extraProperties, WebInspector.ScopeVariableTreeElement);
106             section.editInSelectedCallFrameWhenPaused = true;
107             section.pane = this;
108
109             if (!foundLocalScope || scope.type === "local" || title in this._expandedSections)
110                 section.expanded = true;
111
112             this._sections.push(section);
113             this.bodyElement.appendChild(section.element);
114         }
115     }
116 }
117
118 WebInspector.ScopeChainSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
119
120 WebInspector.ScopeVariableTreeElement = function(property)
121 {
122     WebInspector.ObjectPropertyTreeElement.call(this, property);
123 }
124
125 WebInspector.ScopeVariableTreeElement.prototype = {
126     onattach: function()
127     {
128         WebInspector.ObjectPropertyTreeElement.prototype.onattach.call(this);
129         if (this.hasChildren && this.propertyIdentifier in this.treeOutline.section.pane._expandedProperties)
130             this.expand();
131     },
132
133     onexpand: function()
134     {
135         this.treeOutline.section.pane._expandedProperties[this.propertyIdentifier] = true;
136     },
137
138     oncollapse: function()
139     {
140         delete this.treeOutline.section.pane._expandedProperties[this.propertyIdentifier];
141     },
142
143     get propertyIdentifier()
144     {
145         if ("_propertyIdentifier" in this)
146             return this._propertyIdentifier;
147         var section = this.treeOutline.section;
148         this._propertyIdentifier = section.title + ":" + (section.subtitle ? section.subtitle + ":" : "") + this.propertyPath;
149         return this._propertyIdentifier;
150     },
151
152     get propertyPath()
153     {
154         if ("_propertyPath" in this)
155             return this._propertyPath;
156
157         var current = this;
158         var result;
159
160         do {
161             if (result)
162                 result = current.property.name + "." + result;
163             else
164                 result = current.property.name;
165             current = current.parent;
166         } while (current && !current.root);
167
168         this._propertyPath = result;
169         return result;
170     }
171 }
172
173 WebInspector.ScopeVariableTreeElement.prototype.__proto__ = WebInspector.ObjectPropertyTreeElement.prototype;