Web Inspector: Convert TreeElement classes to ES6
[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 = class ObjectTreeBaseTreeElement extends WebInspector.GeneralTreeElement
27 {
28     constructor(representedObject, propertyPath, property)
29     {
30         console.assert(representedObject);
31         console.assert(propertyPath instanceof WebInspector.PropertyPath);
32         console.assert(!property || property instanceof WebInspector.PropertyDescriptor);
33
34         super(null, null, null, representedObject, false);
35
36         this._property = property;
37         this._propertyPath = propertyPath;
38
39         this.small = true;
40         this.toggleOnClick = true;
41         this.selectable = false;
42         this.tooltipHandledSeparately = true;
43     }
44
45     // Public
46
47     get property()
48     {
49         return this._property;
50     }
51
52     get propertyPath()
53     {
54         return this._propertyPath;
55     }
56
57     // Protected
58
59     oncontextmenu(event)
60     {
61         this._contextMenuHandler(event);
62     }
63
64     resolvedValue()
65     {
66         console.assert(this._property);
67         if (this._getterValue)
68             return this._getterValue;
69         if (this._property.hasValue())
70             return this._property.value;
71         return null;
72     }
73
74     resolvedValuePropertyPath()
75     {
76         console.assert(this._property);
77         if (this._getterValue)
78             return this._propertyPath.appendPropertyDescriptor(this._getterValue, this._property, WebInspector.PropertyPath.Type.Value);
79         if (this._property.hasValue())
80             return this._propertyPath.appendPropertyDescriptor(this._property.value, this._property, WebInspector.PropertyPath.Type.Value);
81         return null;
82     }
83
84     thisPropertyPath()
85     {
86         console.assert(this._property);
87         return this._propertyPath.appendPropertyDescriptor(null, this._property, this.propertyPathType());
88     }
89
90     hadError()
91     {
92         console.assert(this._property);
93         return this._property.wasThrown || this._getterHadError;
94     }
95
96     propertyPathType()
97     {
98         console.assert(this._property);
99         if (this._getterValue || this._property.hasValue())
100             return WebInspector.PropertyPath.Type.Value;
101         if (this._property.hasGetter())
102             return WebInspector.PropertyPath.Type.Getter;
103         if (this._property.hasSetter())
104             return WebInspector.PropertyPath.Type.Setter;
105         return WebInspector.PropertyPath.Type.Value;
106     }
107
108     propertyPathString(propertyPath)
109     {
110         if (propertyPath.isFullPathImpossible())
111             return WebInspector.UIString("Unable to determine path to property from root");
112
113         return propertyPath.displayPath(this.propertyPathType());
114     }
115
116     createInteractiveGetterElement()
117     {
118         var getterElement = document.createElement("img");
119         getterElement.className = "getter";
120         getterElement.title = WebInspector.UIString("Invoke getter");
121
122         getterElement.addEventListener("click", function(event) {
123             event.stopPropagation();
124             var lastNonPrototypeObject = this._propertyPath.lastNonPrototypeObject;
125             var getterObject = this._property.get;
126             lastNonPrototypeObject.invokeGetter(getterObject, function(error, result, wasThrown) {
127                 this._getterHadError = !!(error || wasThrown);
128                 this._getterValue = result;
129                 if (this.invokedGetter && typeof this.invokedGetter === "function")
130                     this.invokedGetter();
131             }.bind(this));
132         }.bind(this));
133
134         return getterElement;
135     }
136
137     createReadOnlyIconElement()
138     {
139         var readOnlyElement = document.createElement("img");
140         readOnlyElement.className = "read-only";
141         readOnlyElement.title = WebInspector.UIString("Read only");
142         return readOnlyElement;
143     }
144
145     // Private
146
147     _logValue(value)
148     {
149         var resolvedValue = value || this.resolvedValue();
150         if (!resolvedValue)
151             return;
152
153         var propertyPath = this.resolvedValuePropertyPath();
154         var isImpossible = propertyPath.isFullPathImpossible();
155         var text = isImpossible ? WebInspector.UIString("Selected Value") : propertyPath.displayPath(this.propertyPathType());
156
157         if (!isImpossible)
158             WebInspector.quickConsole.prompt.pushHistoryItem(text);
159
160         WebInspector.consoleLogViewController.appendImmediateExecutionWithResult(text, resolvedValue);
161     }
162
163     _contextMenuHandler(event)
164     {
165         var resolvedValue = this.resolvedValue();
166         if (!resolvedValue)
167             return;
168
169         var contextMenu = new WebInspector.ContextMenu(event);
170         contextMenu.appendItem(WebInspector.UIString("Log Value"), this._logValue.bind(this));
171
172         var propertyPath = this.resolvedValuePropertyPath();
173         if (propertyPath && !propertyPath.isFullPathImpossible()) {
174             contextMenu.appendItem(WebInspector.UIString("Copy Path to Property"), function() {
175                 InspectorFrontendHost.copyText(propertyPath.displayPath(WebInspector.PropertyPath.Type.Value));
176             }.bind(this));
177         }
178
179         contextMenu.appendSeparator();
180
181         this._appendMenusItemsForObject(contextMenu, resolvedValue);
182
183         if (!contextMenu.isEmpty())
184             contextMenu.show();
185     }
186
187     _appendMenusItemsForObject(contextMenu, resolvedValue)
188     {
189         if (resolvedValue.type === "function") {
190             // FIXME: We should better handle bound functions.
191             if (!isFunctionStringNativeCode(resolvedValue.description)) {
192                 contextMenu.appendItem(WebInspector.UIString("Jump to Definition"), function() {
193                     DebuggerAgent.getFunctionDetails(resolvedValue.objectId, function(error, response) {
194                         if (error)
195                             return;
196
197                         var location = response.location;
198                         var sourceCode = WebInspector.debuggerManager.scriptForIdentifier(location.scriptId);
199                         if (!sourceCode)
200                             return;
201
202                         var sourceCodeLocation = sourceCode.createSourceCodeLocation(location.lineNumber, location.columnNumber || 0);
203                         WebInspector.resourceSidebarPanel.showSourceCodeLocation(sourceCodeLocation);
204                     });
205                 });
206             }
207             return;
208         }
209
210         if (resolvedValue.subtype === "node") {
211             contextMenu.appendItem(WebInspector.UIString("Reveal in DOM Tree"), function() {
212                 resolvedValue.pushNodeToFrontend(function(nodeId) {
213                     WebInspector.domTreeManager.inspectElement(nodeId);
214                 });
215             });
216             return;
217         }
218     }
219 };