diff options
Diffstat (limited to 'Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js')
-rw-r--r-- | Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js b/Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js new file mode 100644 index 000000000..53afa1392 --- /dev/null +++ b/Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2015 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. + */ + +WebInspector.ObjectTreeBaseTreeElement = class ObjectTreeBaseTreeElement extends WebInspector.GeneralTreeElement +{ + constructor(representedObject, propertyPath, property) + { + console.assert(representedObject); + console.assert(propertyPath instanceof WebInspector.PropertyPath); + console.assert(!property || property instanceof WebInspector.PropertyDescriptor); + + super(null, null, null, representedObject, false); + + this._property = property; + this._propertyPath = propertyPath; + + this.toggleOnClick = true; + this.selectable = false; + this.tooltipHandledSeparately = true; + } + + // Public + + get property() + { + return this._property; + } + + get propertyPath() + { + return this._propertyPath; + } + + // Protected + + resolvedValue() + { + console.assert(this._property); + if (this._getterValue) + return this._getterValue; + if (this._property.hasValue()) + return this._property.value; + return null; + } + + resolvedValuePropertyPath() + { + console.assert(this._property); + if (this._getterValue) + return this._propertyPath.appendPropertyDescriptor(this._getterValue, this._property, WebInspector.PropertyPath.Type.Value); + if (this._property.hasValue()) + return this._propertyPath.appendPropertyDescriptor(this._property.value, this._property, WebInspector.PropertyPath.Type.Value); + return null; + } + + thisPropertyPath() + { + console.assert(this._property); + return this._propertyPath.appendPropertyDescriptor(null, this._property, this.propertyPathType()); + } + + hadError() + { + console.assert(this._property); + return this._property.wasThrown || this._getterHadError; + } + + propertyPathType() + { + console.assert(this._property); + if (this._getterValue || this._property.hasValue()) + return WebInspector.PropertyPath.Type.Value; + if (this._property.hasGetter()) + return WebInspector.PropertyPath.Type.Getter; + if (this._property.hasSetter()) + return WebInspector.PropertyPath.Type.Setter; + return WebInspector.PropertyPath.Type.Value; + } + + propertyPathString(propertyPath) + { + if (propertyPath.isFullPathImpossible()) + return WebInspector.UIString("Unable to determine path to property from root"); + + return propertyPath.displayPath(this.propertyPathType()); + } + + createGetterElement(interactive) + { + var getterElement = document.createElement("img"); + getterElement.className = "getter"; + + if (!interactive) { + getterElement.classList.add("disabled"); + getterElement.title = WebInspector.UIString("Getter"); + return getterElement; + } + + getterElement.title = WebInspector.UIString("Invoke getter"); + getterElement.addEventListener("click", (event) => { + event.stopPropagation(); + var lastNonPrototypeObject = this._propertyPath.lastNonPrototypeObject; + var getterObject = this._property.get; + lastNonPrototypeObject.invokeGetter(getterObject, (error, result, wasThrown) => { + this._getterHadError = !!(error || wasThrown); + this._getterValue = result; + if (this.invokedGetter && typeof this.invokedGetter === "function") + this.invokedGetter(); + }); + }); + + return getterElement; + } + + createSetterElement(interactive) + { + var setterElement = document.createElement("img"); + setterElement.className = "setter"; + setterElement.title = WebInspector.UIString("Setter"); + + if (!interactive) + setterElement.classList.add("disabled"); + + return setterElement; + } + + populateContextMenu(contextMenu, event) + { + if (event.__addedObjectPreviewContextMenuItems) + return; + if (event.__addedObjectTreeContextMenuItems) + return; + + event.__addedObjectTreeContextMenuItems = true; + + if (typeof this.treeOutline.objectTreeElementAddContextMenuItems === "function") { + this.treeOutline.objectTreeElementAddContextMenuItems(this, contextMenu); + if (!contextMenu.isEmpty()) + contextMenu.appendSeparator(); + } + + let resolvedValue = this.resolvedValue(); + if (!resolvedValue) + return; + + if (this._property && this._property.symbol) + contextMenu.appendItem(WebInspector.UIString("Log Symbol"), this._logSymbolProperty.bind(this)); + + contextMenu.appendItem(WebInspector.UIString("Log Value"), this._logValue.bind(this)); + + let propertyPath = this.resolvedValuePropertyPath(); + if (propertyPath && !propertyPath.isFullPathImpossible()) { + contextMenu.appendItem(WebInspector.UIString("Copy Path to Property"), () => { + InspectorFrontendHost.copyText(propertyPath.displayPath(WebInspector.PropertyPath.Type.Value)); + }); + } + + contextMenu.appendSeparator(); + + this._appendMenusItemsForObject(contextMenu, resolvedValue); + + super.populateContextMenu(contextMenu, event); + } + + // Private + + _logSymbolProperty() + { + var symbol = this._property.symbol; + if (!symbol) + return; + + var text = WebInspector.UIString("Selected Symbol"); + WebInspector.consoleLogViewController.appendImmediateExecutionWithResult(text, symbol, true); + } + + _logValue(value) + { + var resolvedValue = value || this.resolvedValue(); + if (!resolvedValue) + return; + + var propertyPath = this.resolvedValuePropertyPath(); + var isImpossible = propertyPath.isFullPathImpossible(); + var text = isImpossible ? WebInspector.UIString("Selected Value") : propertyPath.displayPath(this.propertyPathType()); + + if (!isImpossible) + WebInspector.quickConsole.prompt.pushHistoryItem(text); + + WebInspector.consoleLogViewController.appendImmediateExecutionWithResult(text, resolvedValue, isImpossible); + } + + _appendMenusItemsForObject(contextMenu, resolvedValue) + { + if (resolvedValue.type === "function") { + // FIXME: We should better handle bound functions. + if (!isFunctionStringNativeCode(resolvedValue.description)) { + contextMenu.appendItem(WebInspector.UIString("Jump to Definition"), function() { + resolvedValue.target.DebuggerAgent.getFunctionDetails(resolvedValue.objectId, function(error, response) { + if (error) + return; + + let location = response.location; + let sourceCode = WebInspector.debuggerManager.scriptForIdentifier(location.scriptId, resolvedValue.target); + if (!sourceCode) + return; + + let sourceCodeLocation = sourceCode.createSourceCodeLocation(location.lineNumber, location.columnNumber || 0); + WebInspector.showSourceCodeLocation(sourceCodeLocation); + }); + }); + } + return; + } + + if (resolvedValue.subtype === "node") { + contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), function() { + resolvedValue.pushNodeToFrontend(function(nodeId) { + WebInspector.domTreeManager.nodeForId(nodeId).copyNode(); + }); + }); + + contextMenu.appendItem(WebInspector.UIString("Scroll Into View"), function() { + function scrollIntoView() { this.scrollIntoViewIfNeeded(true); } + resolvedValue.callFunction(scrollIntoView, undefined, false, function() {}); + }); + + contextMenu.appendSeparator(); + + contextMenu.appendItem(WebInspector.UIString("Reveal in DOM Tree"), function() { + resolvedValue.pushNodeToFrontend(function(nodeId) { + WebInspector.domTreeManager.inspectElement(nodeId); + }); + }); + return; + } + } +}; |