Web Inspector: Adopt Object Literal Method Property Syntax
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Views / ObjectTreeBaseTreeElement.js
1 /*
2  * Copyright (C) 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WebInspector.ObjectTreeBaseTreeElement = function(representedObject, propertyPath, property)
27 {
28     console.assert(representedObject);
29     console.assert(propertyPath instanceof WebInspector.PropertyPath);
30     console.assert(!property || property instanceof WebInspector.PropertyDescriptor);
31
32     this._property = property;
33     this._propertyPath = propertyPath;
34
35     WebInspector.GeneralTreeElement.call(this, null, null, null, representedObject, false);
36
37     this.small = true;
38     this.toggleOnClick = true;
39     this.selectable = false;
40     this.tooltipHandledSeparately = true;
41 };
42
43 WebInspector.ObjectTreeBaseTreeElement.prototype = {
44     constructor: WebInspector.ObjectTreeBaseTreeElement,
45     __proto__: WebInspector.GeneralTreeElement.prototype,
46
47     // Public
48
49     get property()
50     {
51         return this._property;
52     },
53
54     get propertyPath()
55     {
56         return this._propertyPath;
57     },
58
59     // Protected
60
61     oncontextmenu(event)
62     {
63         this._contextMenuHandler(event);
64     },
65
66     resolvedValue()
67     {
68         console.assert(this._property);
69         if (this._getterValue)
70             return this._getterValue;
71         if (this._property.hasValue())
72             return this._property.value;
73         return null;
74     },
75
76     resolvedValuePropertyPath()
77     {
78         console.assert(this._property);
79         if (this._getterValue)
80             return this._propertyPath.appendPropertyDescriptor(this._getterValue, this._property, WebInspector.PropertyPath.Type.Value);
81         if (this._property.hasValue())
82             return this._propertyPath.appendPropertyDescriptor(this._property.value, this._property, WebInspector.PropertyPath.Type.Value);
83         return null;
84     },
85
86     thisPropertyPath()
87     {
88         console.assert(this._property);
89         return this._propertyPath.appendPropertyDescriptor(null, this._property, this.propertyPathType());
90     },
91
92     hadError()
93     {
94         console.assert(this._property);
95         return this._property.wasThrown || this._getterHadError;
96     },
97
98     propertyPathType()
99     {
100         console.assert(this._property);
101         if (this._getterValue || this._property.hasValue())
102             return WebInspector.PropertyPath.Type.Value;
103         if (this._property.hasGetter())
104             return WebInspector.PropertyPath.Type.Getter;
105         if (this._property.hasSetter())
106             return WebInspector.PropertyPath.Type.Setter;
107         return WebInspector.PropertyPath.Type.Value;
108     },
109
110     propertyPathString(propertyPath)
111     {
112         if (propertyPath.isFullPathImpossible())
113             return WebInspector.UIString("Unable to determine path to property from root");
114
115         return propertyPath.displayPath(this.propertyPathType());
116     },
117
118     createInteractiveGetterElement()
119     {
120         var getterElement = document.createElement("img");
121         getterElement.className = "getter";
122         getterElement.title = WebInspector.UIString("Invoke getter");
123
124         getterElement.addEventListener("click", function(event) {
125             event.stopPropagation();
126             var lastNonPrototypeObject = this._propertyPath.lastNonPrototypeObject;
127             var getterObject = this._property.get;
128             lastNonPrototypeObject.invokeGetter(getterObject, function(error, result, wasThrown) {
129                 this._getterHadError = !!(error || wasThrown);
130                 this._getterValue = result;
131                 if (this.invokedGetter && typeof this.invokedGetter === "function")
132                     this.invokedGetter();
133             }.bind(this));
134         }.bind(this));
135
136         return getterElement;
137     },
138
139     createReadOnlyIconElement()
140     {
141         var readOnlyElement = document.createElement("img");
142         readOnlyElement.className = "read-only";
143         readOnlyElement.title = WebInspector.UIString("Read only");
144         return readOnlyElement;
145     },
146
147     // Private
148
149     _logValue(value)
150     {
151         var resolvedValue = value || this.resolvedValue();
152         if (!resolvedValue)
153             return;
154
155         var propertyPath = this.resolvedValuePropertyPath();
156         var isImpossible = propertyPath.isFullPathImpossible();
157         var text = isImpossible ? WebInspector.UIString("Selected Value") : propertyPath.displayPath(this.propertyPathType());
158
159         if (!isImpossible)
160             WebInspector.quickConsole.prompt.pushHistoryItem(text);
161
162         WebInspector.consoleLogViewController.appendImmediateExecutionWithResult(text, resolvedValue);
163     },
164
165     _contextMenuHandler(event)
166     {
167         var resolvedValue = this.resolvedValue();
168         if (!resolvedValue)
169             return;
170
171         var contextMenu = new WebInspector.ContextMenu(event);
172         contextMenu.appendItem(WebInspector.UIString("Log Value"), this._logValue.bind(this));
173
174         var propertyPath = this.resolvedValuePropertyPath();
175         if (propertyPath && !propertyPath.isFullPathImpossible()) {
176             contextMenu.appendItem(WebInspector.UIString("Copy Path to Property"), function() {
177                 InspectorFrontendHost.copyText(propertyPath.displayPath(WebInspector.PropertyPath.Type.Value));
178             }.bind(this));
179         }
180
181         contextMenu.appendSeparator();
182
183         this._appendMenusItemsForObject(contextMenu, resolvedValue);
184
185         if (!contextMenu.isEmpty())
186             contextMenu.show();
187     },
188
189     _appendMenusItemsForObject(contextMenu, resolvedValue)
190     {
191         if (resolvedValue.type === "function") {
192             // FIXME: We should better handle bound functions.
193             if (!isFunctionStringNativeCode(resolvedValue.description)) {
194                 contextMenu.appendItem(WebInspector.UIString("Jump to Definition"), function() {
195                     DebuggerAgent.getFunctionDetails(resolvedValue.objectId, function(error, response) {
196                         if (error)
197                             return;
198
199                         var location = response.location;
200                         var sourceCode = WebInspector.debuggerManager.scriptForIdentifier(location.scriptId);
201                         if (!sourceCode)
202                             return;
203
204                         var sourceCodeLocation = sourceCode.createSourceCodeLocation(location.lineNumber, location.columnNumber || 0);
205                         WebInspector.resourceSidebarPanel.showSourceCodeLocation(sourceCodeLocation);
206                     });
207                 });
208             }
209             return;
210         }
211
212         if (resolvedValue.subtype === "node") {
213             contextMenu.appendItem(WebInspector.UIString("Reveal in DOM Tree"), function() {
214                 resolvedValue.pushNodeToFrontend(function(nodeId) {
215                     WebInspector.domTreeManager.inspectElement(nodeId);
216                 });
217             });
218             return;
219         }
220     }
221 };