Diff
Modified: trunk/LayoutTests/ChangeLog (182046 => 182047)
--- trunk/LayoutTests/ChangeLog 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/LayoutTests/ChangeLog 2015-03-27 01:42:37 UTC (rev 182047)
@@ -1,3 +1,14 @@
+2015-03-26 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: ES6: Provide a better view for Classes in the console
+ https://bugs.webkit.org/show_bug.cgi?id=142999
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector/model/remote-object-expected.txt:
+ * inspector/model/remote-object.html:
+ Update the test to include coverage of the new "class" subtype of "function".
+
2015-03-26 Tim Horton <[email protected]>
REGRESSION (r181358 and r181507): Lots of sites think that we support touch events on OS X
Modified: trunk/LayoutTests/inspector/model/remote-object-expected.txt (182046 => 182047)
--- trunk/LayoutTests/inspector/model/remote-object-expected.txt 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/LayoutTests/inspector/model/remote-object-expected.txt 2015-03-27 01:42:37 UTC (rev 182047)
@@ -196,7 +196,7 @@
{
"_type": "function",
"_objectId": "<filtered>",
- "_description": "function () {}"
+ "_description": "function (){}"
}
-----------------------------------------------------
@@ -204,7 +204,7 @@
{
"_type": "function",
"_objectId": "<filtered>",
- "_description": "function foo() {}"
+ "_description": "function foo(){}"
}
-----------------------------------------------------
@@ -244,7 +244,7 @@
{
"_type": "function",
"_objectId": "<filtered>",
- "_description": "function () { return 1; }"
+ "_description": "function () { return 1 }"
}
-----------------------------------------------------
@@ -4092,6 +4092,69 @@
}
-----------------------------------------------------
+_expression_: Person = class Person { constructor(){} get fullName(){} methodName(p1, p2){} }; Person
+{
+ "_type": "function",
+ "_subtype": "class",
+ "_objectId": "<filtered>",
+ "_description": "class Person",
+ "_classPrototype": {
+ "_type": "object",
+ "_objectId": "<filtered>",
+ "_description": "Person"
+ }
+}
+
+-----------------------------------------------------
+_expression_: Person.prototype.methodName
+{
+ "_type": "function",
+ "_objectId": "<filtered>",
+ "_description": "function methodName(p1, p2){}"
+}
+
+-----------------------------------------------------
+_expression_: Alpha = class A { methodA(){} }; Beta = class B extends Alpha { methodB(){} }; Beta
+{
+ "_type": "function",
+ "_subtype": "class",
+ "_objectId": "<filtered>",
+ "_description": "class B",
+ "_classPrototype": {
+ "_type": "object",
+ "_objectId": "<filtered>",
+ "_description": "B"
+ }
+}
+
+-----------------------------------------------------
+_expression_: [Beta]
+{
+ "_type": "object",
+ "_subtype": "array",
+ "_objectId": "<filtered>",
+ "_description": "Array",
+ "_size": 1,
+ "_preview": {
+ "_type": "object",
+ "_subtype": "array",
+ "_description": "Array",
+ "_lossless": false,
+ "_overflow": false,
+ "_size": 1,
+ "_properties": [
+ {
+ "_name": "0",
+ "_type": "function",
+ "_subtype": "class",
+ "_value": "B"
+ }
+ ],
+ "_entries": null
+ }
+}
+
+-----------------------------------------------------
_expression_: Object.seal({})
{
"_type": "object",
Modified: trunk/LayoutTests/inspector/model/remote-object.html (182046 => 182047)
--- trunk/LayoutTests/inspector/model/remote-object.html 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/LayoutTests/inspector/model/remote-object.html 2015-03-27 01:42:37 UTC (rev 182047)
@@ -154,6 +154,13 @@
{_expression_: "Promise.resolve()"},
{_expression_: "Promise.resolve({result:1})"},
+ // Classes
+
+ {_expression_: "Person = class Person { constructor(){} get fullName(){} methodName(p1, p2){} }; Person"}, // Constructor => class type
+ {_expression_: "Person.prototype.methodName"}, // Method => just a function type
+ {_expression_: "Alpha = class A { methodA(){} }; Beta = class B extends Alpha { methodB(){} }; Beta"},
+ {_expression_: "[Beta]"},
+
// Improveable:
// Sealed / Frozen objects.
@@ -216,7 +223,11 @@
for (var step of steps) {
console.info("_expression_", step._expression_);
- console.log(eval(step._expression_));
+ try {
+ console.log(eval(step._expression_));
+ } catch (e) {
+ console.log("EXCEPTION: " + e);
+ }
}
}
</script>
Modified: trunk/Source/_javascript_Core/ChangeLog (182046 => 182047)
--- trunk/Source/_javascript_Core/ChangeLog 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-03-27 01:42:37 UTC (rev 182047)
@@ -1,3 +1,33 @@
+2015-03-26 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: ES6: Provide a better view for Classes in the console
+ https://bugs.webkit.org/show_bug.cgi?id=142999
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector/protocol/Runtime.json:
+ Provide a new `subtype` enum "class". This is a subtype of `type`
+ "function", all other subtypes are subtypes of `object` types.
+ For a class, the frontend will immediately want to get the prototype
+ to enumerate its methods, so include the `classPrototype`.
+
+ * inspector/JSInjectedScriptHost.cpp:
+ (Inspector::JSInjectedScriptHost::subtype):
+ Denote class construction functions as "class" subtypes.
+
+ * inspector/InjectedScriptSource.js:
+ Handling for the new "class" type.
+
+ * bytecode/UnlinkedCodeBlock.h:
+ (JSC::UnlinkedFunctionExecutable::isClassConstructorFunction):
+ * runtime/Executable.h:
+ (JSC::FunctionExecutable::isClassConstructorFunction):
+ * runtime/JSFunction.h:
+ * runtime/JSFunctionInlines.h:
+ (JSC::JSFunction::isClassConstructorFunction):
+ Check if this function is a class constructor function. That information
+ is on the UnlinkedFunctionExecutable, so plumb it through to JSFunction.
+
2015-03-26 Geoffrey Garen <[email protected]>
Function.prototype.toString should not decompile the AST
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (182046 => 182047)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2015-03-27 01:42:37 UTC (rev 182047)
@@ -166,6 +166,7 @@
static void destroy(JSCell*);
bool isBuiltinFunction() const { return m_isBuiltinFunction; }
+ bool isClassConstructorFunction() const { return constructorKind() != ConstructorKind::None; }
private:
UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionBodyNode*, UnlinkedFunctionKind);
Modified: trunk/Source/_javascript_Core/inspector/InjectedScriptSource.js (182046 => 182047)
--- trunk/Source/_javascript_Core/inspector/InjectedScriptSource.js 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/_javascript_Core/inspector/InjectedScriptSource.js 2015-03-27 01:42:37 UTC (rev 182047)
@@ -779,6 +779,9 @@
if (subtype === "array")
return className;
+ if (subtype === "class")
+ return obj.name;
+
// NodeList in JSC is a function, check for array prior to this.
if (typeof obj === "function")
return toString(obj);
@@ -922,6 +925,8 @@
this.size = object.size;
else if (subtype === "weakmap")
this.size = InjectedScriptHost.weakMapSize(object);
+ else if (subtype === "class")
+ this.classPrototype = injectedScript._wrapObject(object.prototype, objectGroupName);
if (generatePreview && this.type === "object")
this.preview = this._generatePreview(object, undefined, columnNames);
@@ -955,6 +960,8 @@
var remoteObject = new InjectedScript.RemoteObject(value, undefined, false, true, undefined);
if (remoteObject.objectId)
injectedScript.releaseObject(remoteObject.objectId);
+ if (remoteObject.classPrototype && remoteObject.classPrototype.objectId)
+ injectedScript.releaseObject(remoteObject.classPrototype.objectId);
return remoteObject.preview || remoteObject._emptyPreview();
},
@@ -1103,7 +1110,7 @@
preview.overflow = true;
} else {
var description = "";
- if (type !== "function")
+ if (type !== "function" || subtype === "class")
description = this._abbreviateString(injectedScript._describe(value), maxLength, subtype === "regexp");
property.value = description;
preview.lossless = false;
Modified: trunk/Source/_javascript_Core/inspector/JSInjectedScriptHost.cpp (182046 => 182047)
--- trunk/Source/_javascript_Core/inspector/JSInjectedScriptHost.cpp 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/_javascript_Core/inspector/JSInjectedScriptHost.cpp 2015-03-27 01:42:37 UTC (rev 182047)
@@ -136,9 +136,16 @@
return exec->vm().smallStrings.symbolString();
JSObject* object = asObject(value);
- if (object && object->isErrorInstance())
- return jsNontrivialString(exec, ASCIILiteral("error"));
+ if (object) {
+ if (object->isErrorInstance())
+ return jsNontrivialString(exec, ASCIILiteral("error"));
+ // Consider class constructor functions class objects.
+ JSFunction* function = jsDynamicCast<JSFunction*>(value);
+ if (function && function->isClassConstructorFunction())
+ return jsNontrivialString(exec, ASCIILiteral("class"));
+ }
+
if (value.inherits(JSArray::info()))
return jsNontrivialString(exec, ASCIILiteral("array"));
if (value.inherits(DateInstance::info()))
Modified: trunk/Source/_javascript_Core/inspector/protocol/Runtime.json (182046 => 182047)
--- trunk/Source/_javascript_Core/inspector/protocol/Runtime.json 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/_javascript_Core/inspector/protocol/Runtime.json 2015-03-27 01:42:37 UTC (rev 182047)
@@ -13,12 +13,13 @@
"description": "Mirror object referencing original _javascript_ object.",
"properties": [
{ "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol"], "description": "Object type." },
- { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "error", "map", "set", "weakmap", "iterator"], "description": "Object subtype hint. Specified for <code>object</code> type values only." },
+ { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "error", "map", "set", "weakmap", "iterator", "class"], "description": "Object subtype hint. Specified for <code>object</code> <code>function</code> (for class) type values only." },
{ "name": "className", "type": "string", "optional": true, "description": "Object class (constructor) name. Specified for <code>object</code> type values only." },
{ "name": "value", "type": "any", "optional": true, "description": "Remote object value (in case of primitive values or JSON values if it was requested)." },
{ "name": "description", "type": "string", "optional": true, "description": "String representation of the object." },
{ "name": "objectId", "$ref": "RemoteObjectId", "optional": true, "description": "Unique object identifier (for non-primitive values)." },
{ "name": "size", "type": "integer", "optional": true, "description": "Size of the array/collection. Specified for array/map/set/weakmap object type values only." },
+ { "name": "classPrototype", "$ref": "RemoteObject", "optional": true, "description": "Remote object for the class prototype. Specified for class object type values only." },
{ "name": "preview", "$ref": "ObjectPreview", "optional": true, "description": "Preview containing abbreviated property values. Specified for <code>object</code> type values only." }
]
},
@@ -28,7 +29,7 @@
"description": "Object containing abbreviated remote object value.",
"properties": [
{ "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol"], "description": "Object type." },
- { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "error", "map", "set", "weakmap", "iterator"], "description": "Object subtype hint. Specified for <code>object</code> type values only." },
+ { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "error", "map", "set", "weakmap", "iterator", "class"], "description": "Object subtype hint. Specified for <code>object</code> type values only." },
{ "name": "description", "type": "string", "optional": true, "description": "String representation of the object." },
{ "name": "lossless", "type": "boolean", "description": "Determines whether preview is lossless (contains all information of the original object)." },
{ "name": "overflow", "type": "boolean", "optional": true, "description": "True iff some of the properties of the original did not fit." },
@@ -43,7 +44,7 @@
"properties": [
{ "name": "name", "type": "string", "description": "Property name." },
{ "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol", "accessor"], "description": "Object type." },
- { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "error", "map", "set", "weakmap", "iterator"], "description": "Object subtype hint. Specified for <code>object</code> type values only." },
+ { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "error", "map", "set", "weakmap", "iterator", "class"], "description": "Object subtype hint. Specified for <code>object</code> type values only." },
{ "name": "value", "type": "string", "optional": true, "description": "User-friendly property value string." },
{ "name": "valuePreview", "$ref": "ObjectPreview", "optional": true, "description": "Nested value preview." },
{ "name": "internal", "type": "boolean", "optional": true, "description": "True if this is an internal property." }
Modified: trunk/Source/_javascript_Core/runtime/Executable.h (182046 => 182047)
--- trunk/Source/_javascript_Core/runtime/Executable.h 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/_javascript_Core/runtime/Executable.h 2015-03-27 01:42:37 UTC (rev 182047)
@@ -627,6 +627,7 @@
FunctionMode functionMode() { return m_unlinkedExecutable->functionMode(); }
bool isBuiltinFunction() const { return m_unlinkedExecutable->isBuiltinFunction(); }
+ bool isClassConstructorFunction() const { return m_unlinkedExecutable->isClassConstructorFunction(); }
const Identifier& name() { return m_unlinkedExecutable->name(); }
const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }
JSString* nameValue() const { return m_unlinkedExecutable->nameValue(); }
Modified: trunk/Source/_javascript_Core/runtime/JSFunction.h (182046 => 182047)
--- trunk/Source/_javascript_Core/runtime/JSFunction.h 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.h 2015-03-27 01:42:37 UTC (rev 182047)
@@ -125,6 +125,7 @@
bool isHostOrBuiltinFunction() const;
bool isBuiltinFunction() const;
JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
+ bool isClassConstructorFunction() const;
protected:
const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesGetPropertyNames | JSObject::StructureFlags;
Modified: trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h (182046 => 182047)
--- trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h 2015-03-27 01:42:37 UTC (rev 182047)
@@ -60,6 +60,11 @@
return isHostFunction() || isBuiltinFunction();
}
+inline bool JSFunction::isClassConstructorFunction() const
+{
+ return !isHostFunction() && jsExecutable()->isClassConstructorFunction();
+}
+
inline NativeFunction JSFunction::nativeFunction()
{
ASSERT(isHostFunctionNonInline());
Modified: trunk/Source/WebInspectorUI/ChangeLog (182046 => 182047)
--- trunk/Source/WebInspectorUI/ChangeLog 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/WebInspectorUI/ChangeLog 2015-03-27 01:42:37 UTC (rev 182047)
@@ -1,3 +1,52 @@
+2015-03-26 Joseph Pecoraro <[email protected]>
+
+ Web Inspector: ES6: Provide a better view for Classes in the console
+ https://bugs.webkit.org/show_bug.cgi?id=142999
+
+ Reviewed by Timothy Hatcher.
+
+ * UserInterface/Protocol/RemoteObject.js:
+ (WebInspector.RemoteObject):
+ (WebInspector.RemoteObject.fromPrimitiveValue):
+ (WebInspector.RemoteObject.fromPayload):
+ (WebInspector.RemoteObject.prototype.get classPrototype):
+ (WebInspector.RemoteObject.prototype.isClass):
+ Update our RemoteObject model object for the new subtype
+ and its unique properties.
+
+ * UserInterface/Views/FormattedValue.js:
+ (WebInspector.FormattedValue.createElementForTypesAndValue):
+ (WebInspector.FormattedValue.createObjectTreeOrFormattedValueForRemoteObject):
+ Better handle "class", as it is a new function subtype.
+
+ * UserInterface/Views/LegacyConsoleMessageImpl.js:
+ (WebInspector.LegacyConsoleMessageImpl):
+ (WebInspector.LegacyConsoleMessageImpl.prototype._formatParameterAsObject):
+ Format a "class" with ObjectTreeView.
+
+ * UserInterface/Views/ObjectTreeArrayIndexTreeElement.js:
+ * UserInterface/Views/ObjectTreeBaseTreeElement.js:
+ * UserInterface/Views/ObjectTreePropertyTreeElement.css:
+ (.object-tree-property .getter.disabled):
+ (.object-tree-property .getter:not(.disabled):hover):
+ (.object-tree-property .getter:hover): Deleted.
+ * UserInterface/Views/ObjectTreePropertyTreeElement.js:
+ In ClassAPI mode, you cannot invoke a getter since we don't have
+ an instance to invoke it on. So disable interactivity with getters.
+
+ * UserInterface/Views/ObjectTreeView.js:
+ (WebInspector.ObjectTreeView):
+ Update the modes to include an API mode for instances and classes.
+
+ (WebInspector.ObjectTreeView.defaultModeForObject):
+ * UserInterface/Views/SourceCodeTextEditor.js:
+ (WebInspector.SourceCodeTextEditor.prototype._showPopoverForObject):
+ Simplify ObjectTree construction to automatically determine mode based
+ on the RemoteObject that was provided.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ "Getter" tooltip.
+
2015-03-26 Timothy Hatcher <[email protected]>
Web Inspector: Convert TreeElement classes to ES6
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (182046 => 182047)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2015-03-27 01:42:37 UTC (rev 182047)
@@ -231,6 +231,7 @@
localizedStrings["Full URL"] = "Full URL";
localizedStrings["Function"] = "Function";
localizedStrings["Function Name Variable"] = "Function Name Variable";
+localizedStrings["Getter"] = "Getter";
localizedStrings["Global Breakpoints"] = "Global Breakpoints";
localizedStrings["Global Variables"] = "Global Variables";
localizedStrings["Grammar"] = "Grammar";
Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js (182046 => 182047)
--- trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js 2015-03-27 01:42:37 UTC (rev 182047)
@@ -31,7 +31,7 @@
WebInspector.RemoteObject = class RemoteObject
{
- constructor(objectId, type, subtype, value, description, size, preview)
+ constructor(objectId, type, subtype, value, description, size, classPrototype, preview)
{
console.assert(type);
console.assert(!preview || preview instanceof WebInspector.ObjectPreview);
@@ -40,7 +40,7 @@
this._subtype = subtype;
if (objectId) {
- // Object or Symbol.
+ // Object, Function, or Symbol.
console.assert(!subtype || typeof subtype === "string");
console.assert(!description || typeof description === "string");
console.assert(!value);
@@ -49,7 +49,11 @@
this._description = description;
this._hasChildren = type !== "symbol";
this._size = size;
+ this._classPrototype = classPrototype;
this._preview = preview;
+
+ if (subtype === "class")
+ this._description = "class " + this._description;
} else {
// Primitive or null.
console.assert(type !== "object" || value === null);
@@ -65,7 +69,7 @@
static fromPrimitiveValue(value)
{
- return new WebInspector.RemoteObject(undefined, typeof value, undefined, undefined, value);
+ return new WebInspector.RemoteObject(undefined, typeof value, undefined, value, undefined, undefined, undefined);
}
static fromPayload(payload)
@@ -82,6 +86,9 @@
}
}
+ if (payload.classPrototype)
+ payload.classPrototype = WebInspector.RemoteObject.fromPayload(payload.classPrototype);
+
if (payload.preview) {
// COMPATIBILITY (iOS 8): iOS 7 and 8 did not have type/subtype/description on
// Runtime.ObjectPreview. Copy them over from the RemoteObject.
@@ -95,7 +102,7 @@
payload.preview = WebInspector.ObjectPreview.fromPayload(payload.preview);
}
- return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.size, payload.preview);
+ return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.size, payload.classPrototype, payload.preview);
}
static createCallArgument(valueOrObject)
@@ -171,6 +178,11 @@
return this._size || 0;
}
+ get classPrototype()
+ {
+ return this._classPrototype;
+ }
+
get preview()
{
return this._preview;
@@ -323,6 +335,11 @@
return this._subtype === "array";
}
+ isClass()
+ {
+ return this._subtype === "class";
+ }
+
isCollectionType()
{
return this._subtype === "map" || this._subtype === "set" || this._subtype === "weakmap";
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/FormattedValue.js (182046 => 182047)
--- trunk/Source/WebInspectorUI/UserInterface/Views/FormattedValue.js 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/FormattedValue.js 2015-03-27 01:42:37 UTC (rev 182047)
@@ -86,9 +86,12 @@
return span;
}
- // Function: ellided in previews.
+ // Function: if class, show the description, otherwise ellide in previews.
if (type === "function") {
- span.textContent = isPreview ? "function" : displayString;
+ if (subtype === "class")
+ span.textContent = displayString;
+ else
+ span.textContent = isPreview ? "function" : displayString;
return span;
}
@@ -125,8 +128,8 @@
if (object.subtype === "node")
return WebInspector.FormattedValue.createElementForNode(object);
- if (object.type === "object") {
- var objectTree = new WebInspector.ObjectTreeView(object, WebInspector.ObjectTreeView.Mode.Properties, propertyPath, forceExpanding);
+ if (object.type === "object" || object.subtype === "class") {
+ var objectTree = new WebInspector.ObjectTreeView(object, null, propertyPath, forceExpanding);
return objectTree.element;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/LegacyConsoleMessageImpl.js (182046 => 182047)
--- trunk/Source/WebInspectorUI/UserInterface/Views/LegacyConsoleMessageImpl.js 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LegacyConsoleMessageImpl.js 2015-03-27 01:42:37 UTC (rev 182047)
@@ -46,6 +46,7 @@
"set": this._formatParameterAsObject,
"weakmap": this._formatParameterAsObject,
"iterator": this._formatParameterAsObject,
+ "class": this._formatParameterAsObject,
"array": this._formatParameterAsArray,
"node": this._formatParameterAsNode,
"string": this._formatParameterAsString
@@ -308,7 +309,8 @@
_formatParameterAsObject: function(obj, elem, forceExpansion)
{
- this._objectTree = new WebInspector.ObjectTreeView(obj, WebInspector.ObjectTreeView.Mode.Properties, this._rootPropertyPathForObject(obj), forceExpansion);
+ // FIXME: Should have a better ObjectTreeView mode for classes (static methods and methods).
+ this._objectTree = new WebInspector.ObjectTreeView(obj, null, this._rootPropertyPathForObject(obj), forceExpansion);
elem.appendChild(this._objectTree.element);
},
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeArrayIndexTreeElement.js (182046 => 182047)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeArrayIndexTreeElement.js 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeArrayIndexTreeElement.js 2015-03-27 01:42:37 UTC (rev 182047)
@@ -69,7 +69,7 @@
valueElement.appendChild(WebInspector.FormattedValue.createObjectTreeOrFormattedValueForRemoteObject(resolvedValue, this.resolvedValuePropertyPath()));
else {
if (this.property.hasGetter())
- container.appendChild(this.createInteractiveGetterElement());
+ container.appendChild(this.createInteractiveGetterElement(true));
if (!this.property.hasSetter())
container.appendChild(this.createReadOnlyIconElement());
// FIXME: What if just a setter?
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js (182046 => 182047)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeBaseTreeElement.js 2015-03-27 01:42:37 UTC (rev 182047)
@@ -113,12 +113,18 @@
return propertyPath.displayPath(this.propertyPathType());
}
- createInteractiveGetterElement()
+ createInteractiveGetterElement(enabled)
{
var getterElement = document.createElement("img");
getterElement.className = "getter";
+
+ if (!enabled) {
+ getterElement.classList.add("disabled");
+ getterElement.title = WebInspector.UIString("Getter");
+ return getterElement;
+ }
+
getterElement.title = WebInspector.UIString("Invoke getter");
-
getterElement.addEventListener("click", function(event) {
event.stopPropagation();
var lastNonPrototypeObject = this._propertyPath.lastNonPrototypeObject;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.css (182046 => 182047)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.css 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.css 2015-03-27 01:42:37 UTC (rev 182047)
@@ -157,7 +157,11 @@
margin-left: 3px;
}
-.object-tree-property .getter:hover {
+.object-tree-property .getter.disabled {
+ opacity: 0.35;
+}
+
+.object-tree-property .getter:not(.disabled):hover {
opacity: 1;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.js (182046 => 182047)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.js 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.js 2015-03-27 01:42:37 UTC (rev 182047)
@@ -169,7 +169,7 @@
} else {
valueOrGetterElement = document.createElement("span");
if (this.property.hasGetter())
- valueOrGetterElement.appendChild(this.createInteractiveGetterElement());
+ valueOrGetterElement.appendChild(this.createInteractiveGetterElement(this._mode !== WebInspector.ObjectTreeView.Mode.ClassAPI));
if (!this.property.hasSetter())
valueOrGetterElement.appendChild(this.createReadOnlyIconElement());
// FIXME: What if just a setter?
@@ -211,7 +211,7 @@
container.appendChild(paramElement);
} else {
if (this.property.hasGetter())
- container.appendChild(this.createInteractiveGetterElement());
+ container.appendChild(this.createInteractiveGetterElement(this._mode !== WebInspector.ObjectTreeView.Mode.ClassAPI));
if (!this.property.hasSetter())
container.appendChild(this.createReadOnlyIconElement());
// FIXME: What if just a setter?
@@ -304,8 +304,10 @@
var resolvedValue = this.resolvedValue();
if (resolvedValue.isCollectionType() && this._mode === WebInspector.ObjectTreeView.Mode.Properties)
resolvedValue.getCollectionEntries(0, 100, this._updateChildrenInternal.bind(this, this._updateEntries, this._mode));
+ else if (this._mode === WebInspector.ObjectTreeView.Mode.ClassAPI)
+ resolvedValue.getOwnPropertyDescriptors(this._updateChildrenInternal.bind(this, this._updateProperties, WebInspector.ObjectTreeView.Mode.ClassAPI));
else if (this.property.name === "__proto__")
- resolvedValue.getOwnPropertyDescriptors(this._updateChildrenInternal.bind(this, this._updateProperties, WebInspector.ObjectTreeView.Mode.API));
+ resolvedValue.getOwnPropertyDescriptors(this._updateChildrenInternal.bind(this, this._updateProperties, WebInspector.ObjectTreeView.Mode.PrototypeAPI));
else
resolvedValue.getDisplayablePropertyDescriptors(this._updateChildrenInternal.bind(this, this._updateProperties, this._mode));
}
@@ -353,7 +355,7 @@
var resolvedValue = this.resolvedValue();
var isArray = resolvedValue.isArray();
var isPropertyMode = mode === WebInspector.ObjectTreeView.Mode.Properties || this._getterValue;
- var isAPI = mode === WebInspector.ObjectTreeView.Mode.API;
+ var isAPI = mode !== WebInspector.ObjectTreeView.Mode.Prototype;
var prototypeName = undefined;
if (this.property.name === "__proto__") {
@@ -367,7 +369,7 @@
// already showed them in the Properties section.
if (isAPI && propertyDescriptor.nativeGetter)
continue;
-
+
if (isArray && isPropertyMode) {
if (propertyDescriptor.isIndexProperty())
this.appendChild(new WebInspector.ObjectTreeArrayIndexTreeElement(propertyDescriptor, propertyPath));
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.js (182046 => 182047)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.js 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.js 2015-03-27 01:42:37 UTC (rev 182047)
@@ -32,7 +32,7 @@
console.assert(!propertyPath || propertyPath instanceof WebInspector.PropertyPath);
this._object = object;
- this._mode = mode || WebInspector.ObjectTreeView.Mode.Properties;
+ this._mode = mode || WebInspector.ObjectTreeView.defaultModeForObject(object);
this._propertyPath = propertyPath || new WebInspector.PropertyPath(this._object, "this");
this._expanded = false;
this._hasLosslessPreview = false;
@@ -42,6 +42,10 @@
// listen for console clear events. Currently all ObjectTrees are in the console.
this._inConsole = true;
+ // Always force expanding for classes.
+ if (this._object.isClass())
+ forceExpanding = true;
+
this._element = document.createElement("div");
this._element.className = "object-tree";
@@ -70,6 +74,14 @@
// FIXME: Support editable ObjectTrees.
};
+WebInspector.ObjectTreeView.defaultModeForObject = function(object)
+{
+ if (object.subtype === "class")
+ return WebInspector.ObjectTreeView.Mode.ClassAPI;
+
+ return WebInspector.ObjectTreeView.Mode.Properties;
+}
+
WebInspector.ObjectTreeView.emptyMessageElement = function(message)
{
var emptyMessageElement = document.createElement("div");
@@ -79,8 +91,9 @@
};
WebInspector.ObjectTreeView.Mode = {
- Properties: Symbol("object-tree-properties"),
- API: Symbol("object-tree-api"),
+ Properties: Symbol("object-tree-properties"), // Properties
+ PrototypeAPI: Symbol("object-tree-prototype-api"), // API view on a live object instance, so getters can be invoked.
+ ClassAPI: Symbol("object-tree-class-api"), // API view without an object instance, can not invoke getters.
};
WebInspector.ObjectTreeView.ComparePropertyDescriptors = function(propertyA, propertyB)
@@ -221,6 +234,8 @@
{
if (this._object.isCollectionType() && this._mode === WebInspector.ObjectTreeView.Mode.Properties)
this._object.getCollectionEntries(0, 100, this._updateChildren.bind(this, this._updateEntries));
+ else if (this._object.isClass())
+ this._object.classPrototype.getDisplayablePropertyDescriptors(this._updateChildren.bind(this, this._updateProperties));
else
this._object.getDisplayablePropertyDescriptors(this._updateChildren.bind(this, this._updateProperties));
},
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js (182046 => 182047)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js 2015-03-27 01:02:38 UTC (rev 182046)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js 2015-03-27 01:42:37 UTC (rev 182047)
@@ -1525,7 +1525,7 @@
content.appendChild(titleElement);
// FIXME: If this is a variable, it would be nice to put the variable name in the PropertyPath.
- var objectTree = new WebInspector.ObjectTreeView(data, WebInspector.ObjectTreeView.Mode.Properties, null);
+ var objectTree = new WebInspector.ObjectTreeView(data);
objectTree.showOnlyProperties();
objectTree.expand();