Web Inspector: Make Getter/Setter RemoteObject property and ObjectPreview handling...
authorjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Feb 2015 00:31:42 +0000 (00:31 +0000)
committerjoepeck@webkit.org <joepeck@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Feb 2015 00:31:42 +0000 (00:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=141587

Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

Convert getProperties(ownAndGetterProperties) to getDisplayableProperties().
Mark PropertyDescriptors that are presumed to be native getters / bindings
separately so that the frontend may display them differently.

* inspector/InjectedScript.cpp:
(Inspector::InjectedScript::getProperties):
(Inspector::InjectedScript::getDisplayableProperties):
* inspector/InjectedScript.h:
* inspector/InjectedScriptSource.js:
* inspector/agents/InspectorRuntimeAgent.cpp:
(Inspector::InspectorRuntimeAgent::getProperties):
(Inspector::InspectorRuntimeAgent::getDisplayableProperties):
* inspector/agents/InspectorRuntimeAgent.h:
* inspector/protocol/Runtime.json:

Source/WebInspectorUI:

* UserInterface/Models/CallFrame.js:
(WebInspector.CallFrame.prototype.collectScopeChainVariableNames):
* UserInterface/Models/PropertyDescriptor.js:
(WebInspector.PropertyDescriptor.prototype.get nativeGetter):
* UserInterface/Protocol/RemoteObject.js:
(WebInspector.RemoteObject.fromPayload):
(WebInspector.RemoteObject.prototype.getOwnPropertyDescriptors):
(WebInspector.RemoteObject.prototype.getAllPropertyDescriptors):
(WebInspector.RemoteObject.prototype.getDisplayablePropertyDescriptors):
(WebInspector.RemoteObject.prototype._getPropertyDescriptors):
(WebInspector.RemoteObject.prototype.if):
(WebInspector.RemoteObject.prototype.deprecatedGetOwnProperties):
(WebInspector.RemoteObject.prototype.deprecatedGetAllProperties):
(WebInspector.RemoteObject.prototype._deprecatedGetProperties):
(WebInspector.RemoteObject.prototype.getOwnAndGetterPropertyDescriptors): Deleted.
(WebInspector.RemoteObject.prototype.callback): Deleted.
(WebInspector.RemoteObject.prototype.getOwnProperties): Deleted.
(WebInspector.RemoteObject.prototype.getOwnAndGetterProperties): Deleted.
(WebInspector.RemoteObject.prototype.getAllProperties): Deleted.
(WebInspector.RemoteObject.prototype.set else): Deleted.
* UserInterface/Views/ConsoleMessageImpl.js:
(WebInspector.ConsoleMessageImpl.prototype._formatParameterAsArray):
* UserInterface/Views/DOMNodeDetailsSidebarPanel.js:
(WebInspector.DOMNodeDetailsSidebarPanel.prototype._refreshProperties.nodePrototypesReady):
* UserInterface/Views/ObjectPropertiesSection.js:
(WebInspector.ObjectPropertiesSection.prototype.update):
(WebInspector.ObjectPropertyTreeElement.prototype.onpopulate):
* UserInterface/Views/ObjectTreePropertyTreeElement.js:
(WebInspector.ObjectTreePropertyTreeElement.prototype.):
(WebInspector.ObjectTreePropertyTreeElement.prototype):
* UserInterface/Views/ObjectTreeView.js:
(WebInspector.ObjectTreeView.prototype.update):

LayoutTests:

* inspector/model/remote-object-get-properties-expected.txt:
* inspector/model/remote-object-get-properties.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@180594 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/model/remote-object-get-properties-expected.txt
LayoutTests/inspector/model/remote-object-get-properties.html
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/InjectedScript.cpp
Source/JavaScriptCore/inspector/InjectedScript.h
Source/JavaScriptCore/inspector/InjectedScriptSource.js
Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.h
Source/JavaScriptCore/inspector/protocol/Runtime.json
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Models/CallFrame.js
Source/WebInspectorUI/UserInterface/Models/PropertyDescriptor.js
Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js
Source/WebInspectorUI/UserInterface/Views/ConsoleMessageImpl.js
Source/WebInspectorUI/UserInterface/Views/DOMNodeDetailsSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/ObjectPropertiesSection.js
Source/WebInspectorUI/UserInterface/Views/ObjectTreePropertyTreeElement.js
Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.js

index ebd804d..2372dd6 100644 (file)
@@ -1,3 +1,13 @@
+2015-02-24  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Make Getter/Setter RemoteObject property and ObjectPreview handling consistent
+        https://bugs.webkit.org/show_bug.cgi?id=141587
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/model/remote-object-get-properties-expected.txt:
+        * inspector/model/remote-object-get-properties.html:
+
 2015-02-24  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         Constructor returning null should construct an object instead of null
index fb93bee..7a8a69f 100644 (file)
@@ -9,7 +9,7 @@ OWN PROPERTIES:
     b
     __proto__
 
-OWN AND GETTER PROPERTIES:
+DISPLAYABLE PROPERTIES:
     a
     b
     __proto__
@@ -40,7 +40,7 @@ OWN PROPERTIES:
     clipboardData
     __proto__
 
-OWN AND GETTER PROPERTIES:
+DISPLAYABLE PROPERTIES:
     clipboardData
     type
     target
@@ -116,12 +116,9 @@ OWN PROPERTIES:
     _foo
     __proto__
 
-OWN AND GETTER PROPERTIES:
+DISPLAYABLE PROPERTIES:
     _bar
     _foo
-    getterProperty
-    foo
-    bar
     __proto__
 
 ALL PROPERTIES:
@@ -154,8 +151,7 @@ description: ClassWithBadGetter
 OWN PROPERTIES:
     __proto__
 
-OWN AND GETTER PROPERTIES:
-    badGetter
+DISPLAYABLE PROPERTIES:
     __proto__
 
 ALL PROPERTIES:
@@ -187,7 +183,7 @@ OWN PROPERTIES:
     prototype
     __proto__
 
-OWN AND GETTER PROPERTIES:
+DISPLAYABLE PROPERTIES:
     arguments
     caller
     length
@@ -235,7 +231,7 @@ OWN PROPERTIES:
     boundThis
     boundArgs
 
-OWN AND GETTER PROPERTIES:
+DISPLAYABLE PROPERTIES:
     name
     length
     arguments
index fc0e2e7..c9bed73 100644 (file)
@@ -87,8 +87,8 @@ function test()
                 }
             });
 
-            remoteObject.getOwnAndGetterPropertyDescriptors(function(properties) {
-                InspectorTest.log("\nOWN AND GETTER PROPERTIES:");
+            remoteObject.getDisplayablePropertyDescriptors(function(properties) {
+                InspectorTest.log("\nDISPLAYABLE PROPERTIES:");
                 for (var property of properties) {
                     InspectorTest.assert(property instanceof WebInspector.PropertyDescriptor);
                     InspectorTest.log("    " + property.name);
index c98b329..5a8f023 100644 (file)
@@ -1,3 +1,25 @@
+2015-02-24  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Make Getter/Setter RemoteObject property and ObjectPreview handling consistent
+        https://bugs.webkit.org/show_bug.cgi?id=141587
+
+        Reviewed by Timothy Hatcher.
+
+        Convert getProperties(ownAndGetterProperties) to getDisplayableProperties().
+        Mark PropertyDescriptors that are presumed to be native getters / bindings
+        separately so that the frontend may display them differently.
+
+        * inspector/InjectedScript.cpp:
+        (Inspector::InjectedScript::getProperties):
+        (Inspector::InjectedScript::getDisplayableProperties):
+        * inspector/InjectedScript.h:
+        * inspector/InjectedScriptSource.js:
+        * inspector/agents/InspectorRuntimeAgent.cpp:
+        (Inspector::InspectorRuntimeAgent::getProperties):
+        (Inspector::InspectorRuntimeAgent::getDisplayableProperties):
+        * inspector/agents/InspectorRuntimeAgent.h:
+        * inspector/protocol/Runtime.json:
+
 2015-02-24  Mark Lam  <mark.lam@apple.com>
 
         Rolling out r179753.  The fix was invalid.
index b87e0cc..66499ed 100644 (file)
@@ -107,12 +107,27 @@ void InjectedScript::getFunctionDetails(ErrorString& errorString, const String&
     *result = BindingTraits<Inspector::Protocol::Debugger::FunctionDetails>::runtimeCast(WTF::move(resultValue));
 }
 
-void InjectedScript::getProperties(ErrorString& errorString, const String& objectId, bool ownProperties, bool ownAndGetterProperties, bool generatePreview, RefPtr<Array<Inspector::Protocol::Runtime::PropertyDescriptor>>* properties)
+void InjectedScript::getProperties(ErrorString& errorString, const String& objectId, bool ownProperties, bool generatePreview, RefPtr<Array<Inspector::Protocol::Runtime::PropertyDescriptor>>* properties)
 {
     Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("getProperties"), inspectorEnvironment()->functionCallHandler());
     function.appendArgument(objectId);
     function.appendArgument(ownProperties);
-    function.appendArgument(ownAndGetterProperties);
+    function.appendArgument(generatePreview);
+
+    RefPtr<InspectorValue> result;
+    makeCall(function, &result);
+    if (!result || result->type() != InspectorValue::Type::Array) {
+        errorString = ASCIILiteral("Internal error");
+        return;
+    }
+
+    *properties = BindingTraits<Array<Inspector::Protocol::Runtime::PropertyDescriptor>>::runtimeCast(WTF::move(result));
+}
+
+void InjectedScript::getDisplayableProperties(ErrorString& errorString, const String& objectId, bool generatePreview, RefPtr<Array<Inspector::Protocol::Runtime::PropertyDescriptor>>* properties)
+{
+    Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("getDisplayableProperties"), inspectorEnvironment()->functionCallHandler());
+    function.appendArgument(objectId);
     function.appendArgument(generatePreview);
 
     RefPtr<InspectorValue> result;
index 8d297df..14a3cb0 100644 (file)
@@ -56,7 +56,8 @@ public:
     void callFunctionOn(ErrorString&, const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, RefPtr<Protocol::Runtime::RemoteObject>* result, Protocol::OptOutput<bool>* wasThrown);
     void evaluateOnCallFrame(ErrorString&, const Deprecated::ScriptValue& callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, RefPtr<Protocol::Runtime::RemoteObject>* result, Protocol::OptOutput<bool>* wasThrown);
     void getFunctionDetails(ErrorString&, const String& functionId, RefPtr<Protocol::Debugger::FunctionDetails>* result);
-    void getProperties(ErrorString&, const String& objectId, bool ownProperties, bool ownAndGetterProperties, bool generatePreview, RefPtr<Protocol::Array<Protocol::Runtime::PropertyDescriptor>>* result);
+    void getProperties(ErrorString&, const String& objectId, bool ownProperties, bool generatePreview, RefPtr<Protocol::Array<Protocol::Runtime::PropertyDescriptor>>* result);
+    void getDisplayableProperties(ErrorString&, const String& objectId, bool generatePreview, RefPtr<Protocol::Array<Protocol::Runtime::PropertyDescriptor>>* result);
     void getInternalProperties(ErrorString&, const String& objectId, bool generatePreview, RefPtr<Protocol::Array<Protocol::Runtime::InternalPropertyDescriptor>>* result);
     void getCollectionEntries(ErrorString&, const String& objectId, const String& objectGroup, int startIndex, int numberToFetch, RefPtr<Protocol::Array<Protocol::Runtime::CollectionEntry>>* entries);
 
index d7a1f41..04c9a98 100644 (file)
@@ -68,9 +68,9 @@ InjectedScript.primitiveTypes = {
 }
 
 InjectedScript.CollectionMode = {
-    OwnProperties: 1 << 0,    // own properties.
-    GetterProperties: 1 << 1, // getter properties in the prototype chain.
-    AllProperties: 1 << 2,    // all properties in the prototype chain.
+    OwnProperties: 1 << 0,          // own properties.
+    NativeGetterProperties: 1 << 1, // native getter properties in the prototype chain.
+    AllProperties: 1 << 2,          // all properties in the prototype chain.
 }
 
 InjectedScript.prototype = {
@@ -196,7 +196,7 @@ InjectedScript.prototype = {
         return result;
     },
 
-    getProperties: function(objectId, ownProperties, ownAndGetterProperties, generatePreview)
+    _getProperties: function(objectId, collectionMode, generatePreview)
     {
         var parsedObjectId = this._parseObjectId(objectId);
         var object = this._objectForId(parsedObjectId);
@@ -208,12 +208,6 @@ InjectedScript.prototype = {
         if (isSymbol(object))
             return false;
 
-        var collectionMode = InjectedScript.CollectionMode.AllProperties;
-        if (ownProperties)
-            collectionMode = InjectedScript.CollectionMode.OwnProperties;
-        else if (ownAndGetterProperties)
-            collectionMode = InjectedScript.CollectionMode.OwnProperties | InjectedScript.CollectionMode.GetterProperties;
-
         var descriptors = this._propertyDescriptors(object, collectionMode);
 
         // Go over properties, wrap object values.
@@ -234,6 +228,18 @@ InjectedScript.prototype = {
         return descriptors;
     },
 
+    getProperties: function(objectId, ownProperties, generatePreview)
+    {
+        var collectionMode = ownProperties ? InjectedScript.CollectionMode.OwnProperties : InjectedScript.CollectionMode.AllProperties;
+        return this._getProperties(objectId, collectionMode, generatePreview);
+    },
+
+    getDisplayableProperties: function(objectId, generatePreview)
+    {
+        var collectionMode = InjectedScript.CollectionMode.OwnProperties | InjectedScript.CollectionMode.NativeGetterProperties;
+        return this._getProperties(objectId, collectionMode, generatePreview);
+    },
+
     getInternalProperties: function(objectId, generatePreview)
     {
         var parsedObjectId = this._parseObjectId(objectId);
@@ -564,10 +570,13 @@ InjectedScript.prototype = {
         var nameProcessed = {};
         nameProcessed["__proto__"] = null;
 
-        function createFakeValueDescriptor(name, descriptor, isOwnProperty)
+        function createFakeValueDescriptor(name, descriptor, isOwnProperty, possibleNativeBindingGetter)
         {
             try {
-                return {name: name, value: object[name], writable: descriptor.writable || false, configurable: descriptor.configurable || false, enumerable: descriptor.enumerable || false};
+                var descriptor = {name: name, value: object[name], writable: descriptor.writable || false, configurable: descriptor.configurable || false, enumerable: descriptor.enumerable || false};
+                if (possibleNativeBindingGetter)
+                    descriptor.nativeGetter = true;
+                return descriptor;
             } catch (e) {
                 var errorDescriptor = {name: name, value: e, wasThrown: true};
                 if (isOwnProperty)
@@ -590,13 +599,10 @@ InjectedScript.prototype = {
                 return;
             }
 
-            // Getter properties.
-            if (collectionMode & InjectedScript.CollectionMode.GetterProperties) {
-                if (descriptor.hasOwnProperty("get") && descriptor.get) {
-                    // Getter property in the prototype chain. Create a fake value descriptor.
-                    descriptors.push(createFakeValueDescriptor(descriptor.name, descriptor, isOwnProperty));
-                    return;
-                }
+            // Native Getter properties.
+            if (collectionMode & InjectedScript.CollectionMode.NativeGetterProperties) {
+                // FIXME: <https://webkit.org/b/140575> Web Inspector: Native Bindings Descriptors are Incomplete
+                // if (descriptor.hasOwnProperty("get") && descriptor.get && isNativeFunction(descriptor.get)) { ... }
 
                 if (possibleNativeBindingGetter) {
                     // Possible getter property in the prototype chain.
@@ -628,7 +634,7 @@ InjectedScript.prototype = {
                     // FIXME: <https://webkit.org/b/140575> Web Inspector: Native Bindings Descriptors are Incomplete
                     // Developers may create such a descriptors, so we should be resilient:
                     // var x = {}; Object.defineProperty(x, "p", {get:undefined}); Object.getOwnPropertyDescriptor(x, "p")
-                    var fakeDescriptor = createFakeValueDescriptor(name, descriptor, isOwnProperty);
+                    var fakeDescriptor = createFakeValueDescriptor(name, descriptor, isOwnProperty, true);
                     processDescriptor(fakeDescriptor, isOwnProperty, true);
                     continue;
                 }
index aab02f9..5e8192e 100644 (file)
@@ -160,7 +160,7 @@ void InspectorRuntimeAgent::callFunctionOn(ErrorString& errorString, const Strin
     }
 }
 
-void InspectorRuntimeAgent::getProperties(ErrorString& errorString, const String& objectId, const bool* const ownProperties, const bool* const ownAndGetterProperties, const bool* const generatePreview, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::PropertyDescriptor>>& result, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>& internalProperties)
+void InspectorRuntimeAgent::getProperties(ErrorString& errorString, const String& objectId, const bool* const ownProperties, const bool* const generatePreview, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::PropertyDescriptor>>& result, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>& internalProperties)
 {
     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
     if (injectedScript.hasNoValue()) {
@@ -171,7 +171,25 @@ void InspectorRuntimeAgent::getProperties(ErrorString& errorString, const String
     ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions);
     muteConsole();
 
-    injectedScript.getProperties(errorString, objectId, asBool(ownProperties), asBool(ownAndGetterProperties), asBool(generatePreview), &result);
+    injectedScript.getProperties(errorString, objectId, asBool(ownProperties), asBool(generatePreview), &result);
+    injectedScript.getInternalProperties(errorString, objectId, asBool(generatePreview), &internalProperties);
+
+    unmuteConsole();
+    setPauseOnExceptionsState(m_scriptDebugServer, previousPauseOnExceptionsState);
+}
+
+void InspectorRuntimeAgent::getDisplayableProperties(ErrorString& errorString, const String& objectId, const bool* const generatePreview, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::PropertyDescriptor>>& result, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>& internalProperties)
+{
+    InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
+    if (injectedScript.hasNoValue()) {
+        errorString = ASCIILiteral("Inspected frame has gone");
+        return;
+    }
+
+    ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions);
+    muteConsole();
+
+    injectedScript.getDisplayableProperties(errorString, objectId, asBool(generatePreview), &result);
     injectedScript.getInternalProperties(errorString, objectId, asBool(generatePreview), &internalProperties);
 
     unmuteConsole();
index fd7b585..678f0c7 100644 (file)
@@ -63,7 +63,8 @@ public:
     virtual void evaluate(ErrorString&, const String& expression, const String* objectGroup, const bool* includeCommandLineAPI, const bool* doNotPauseOnExceptionsAndMuteConsole, const int* executionContextId, const bool* returnByValue, const bool* generatePreview, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result, Inspector::Protocol::OptOutput<bool>* wasThrown) override final;
     virtual void callFunctionOn(ErrorString&, const String& objectId, const String& expression, const RefPtr<Inspector::InspectorArray>&& optionalArguments, const bool* doNotPauseOnExceptionsAndMuteConsole, const bool* returnByValue, const bool* generatePreview, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result, Inspector::Protocol::OptOutput<bool>* wasThrown) override final;
     virtual void releaseObject(ErrorString&, const ErrorString& objectId) override final;
-    virtual void getProperties(ErrorString&, const String& objectId, const bool* ownProperties, const bool* ownAndGetterProperties, const bool* generatePreview, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::PropertyDescriptor>>& result, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>& internalProperties) override final;
+    virtual void getProperties(ErrorString&, const String& objectId, const bool* ownProperties, const bool* generatePreview, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::PropertyDescriptor>>& result, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>& internalProperties) override final;
+    virtual void getDisplayableProperties(ErrorString&, const String& objectId, const bool* generatePreview, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::PropertyDescriptor>>& result, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>& internalProperties) override final;
     virtual void getCollectionEntries(ErrorString&, const String& objectId, const String* objectGroup, const int* startIndex, const int* numberToFetch, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Runtime::CollectionEntry>>& entries) override final;
     virtual void releaseObjectGroup(ErrorString&, const String& objectGroup) override final;
     virtual void run(ErrorString&) override;
index f07d9c5..1bdd31f 100644 (file)
@@ -76,7 +76,8 @@
                 { "name": "configurable", "type": "boolean", "description": "True if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object." },
                 { "name": "enumerable", "type": "boolean", "description": "True if this property shows up during enumeration of the properties on the corresponding object." },
                 { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." },
-                { "name": "isOwn", "optional": true, "type": "boolean", "description": "True if the property is owned for the object." }
+                { "name": "isOwn", "optional": true, "type": "boolean", "description": "True if the property is owned for the object." },
+                { "name": "nativeGetter", "optional": true, "type": "boolean", "description": "True if the property value came from a native getter." }
             ]
         },
         {
             "parameters": [
                 { "name": "objectId", "$ref": "RemoteObjectId", "description": "Identifier of the object to return properties for." },
                 { "name": "ownProperties", "optional": true, "type": "boolean", "description": "If true, returns properties belonging only to the object itself, not to its prototype chain." },
-                { "name": "ownAndGetterProperties", "optional": true, "type": "boolean", "description": "If true, returns properties belonging to the object itself, and getters in its prototype chain." },
                 { "name": "generatePreview", "type": "boolean", "optional": true, "description": "Whether preview should be generated for property values." }
             ],
             "returns": [
             "description": "Returns properties of a given object. Object group of the result is inherited from the target object."
         },
         {
+            "name": "getDisplayableProperties",
+            "parameters": [
+                { "name": "objectId", "$ref": "RemoteObjectId", "description": "Identifier of the object to return properties for." },
+                { "name": "generatePreview", "type": "boolean", "optional": true, "description": "Whether preview should be generated for property values." }
+            ],
+            "returns": [
+                { "name": "properties", "type": "array", "items": { "$ref": "PropertyDescriptor"}, "description": "Object properties." },
+                { "name": "internalProperties", "optional": true, "type": "array", "items": { "$ref": "InternalPropertyDescriptor"}, "description": "Internal object properties." }
+            ],
+            "description": "Returns displayable properties of a given object. Object group of the result is inherited from the target object. Displayable properties are own properties, internal properties, and native getters in the prototype chain (assumed to be bindings and treated like own properties for the frontend)."
+        },
+        {
             "name": "getCollectionEntries",
             "description": "Returns entries of given Map / Set collection.",
             "parameters": [
index c604673..577b6c6 100644 (file)
@@ -1,5 +1,45 @@
 2015-02-24  Joseph Pecoraro  <pecoraro@apple.com>
 
+        Web Inspector: Make Getter/Setter RemoteObject property and ObjectPreview handling consistent
+        https://bugs.webkit.org/show_bug.cgi?id=141587
+
+        Reviewed by Timothy Hatcher.
+
+        * UserInterface/Models/CallFrame.js:
+        (WebInspector.CallFrame.prototype.collectScopeChainVariableNames):
+        * UserInterface/Models/PropertyDescriptor.js:
+        (WebInspector.PropertyDescriptor.prototype.get nativeGetter):
+        * UserInterface/Protocol/RemoteObject.js:
+        (WebInspector.RemoteObject.fromPayload):
+        (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptors):
+        (WebInspector.RemoteObject.prototype.getAllPropertyDescriptors):
+        (WebInspector.RemoteObject.prototype.getDisplayablePropertyDescriptors):
+        (WebInspector.RemoteObject.prototype._getPropertyDescriptors):
+        (WebInspector.RemoteObject.prototype.if):
+        (WebInspector.RemoteObject.prototype.deprecatedGetOwnProperties):
+        (WebInspector.RemoteObject.prototype.deprecatedGetAllProperties):
+        (WebInspector.RemoteObject.prototype._deprecatedGetProperties):
+        (WebInspector.RemoteObject.prototype.getOwnAndGetterPropertyDescriptors): Deleted.
+        (WebInspector.RemoteObject.prototype.callback): Deleted.
+        (WebInspector.RemoteObject.prototype.getOwnProperties): Deleted.
+        (WebInspector.RemoteObject.prototype.getOwnAndGetterProperties): Deleted.
+        (WebInspector.RemoteObject.prototype.getAllProperties): Deleted.
+        (WebInspector.RemoteObject.prototype.set else): Deleted.
+        * UserInterface/Views/ConsoleMessageImpl.js:
+        (WebInspector.ConsoleMessageImpl.prototype._formatParameterAsArray):
+        * UserInterface/Views/DOMNodeDetailsSidebarPanel.js:
+        (WebInspector.DOMNodeDetailsSidebarPanel.prototype._refreshProperties.nodePrototypesReady):
+        * UserInterface/Views/ObjectPropertiesSection.js:
+        (WebInspector.ObjectPropertiesSection.prototype.update):
+        (WebInspector.ObjectPropertyTreeElement.prototype.onpopulate):
+        * UserInterface/Views/ObjectTreePropertyTreeElement.js:
+        (WebInspector.ObjectTreePropertyTreeElement.prototype.):
+        (WebInspector.ObjectTreePropertyTreeElement.prototype):
+        * UserInterface/Views/ObjectTreeView.js:
+        (WebInspector.ObjectTreeView.prototype.update):
+
+2015-02-24  Joseph Pecoraro  <pecoraro@apple.com>
+
         Web Inspector: New Object Tree View UI
         https://bugs.webkit.org/show_bug.cgi?id=141932
 
index 6ffd0c8..1932675 100644 (file)
@@ -98,7 +98,7 @@ WebInspector.CallFrame.prototype = {
         }
 
         for (var i = 0; i < this._scopeChain.length; ++i)
-            this._scopeChain[i].object.getAllProperties(propertiesCollected);
+            this._scopeChain[i].object.deprecatedGetAllProperties(propertiesCollected);
     }
 };
 
index 60b3b03..77a2c66 100644 (file)
@@ -23,7 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-WebInspector.PropertyDescriptor = function(descriptor, isOwnProperty, wasThrown, isInternalProperty)
+WebInspector.PropertyDescriptor = function(descriptor, isOwnProperty, wasThrown, nativeGetter, isInternalProperty)
 {
     WebInspector.Object.call(this);
 
@@ -45,6 +45,7 @@ WebInspector.PropertyDescriptor = function(descriptor, isOwnProperty, wasThrown,
 
     this._own = isOwnProperty || false;
     this._wasThrown = wasThrown || false;
+    this._nativeGetterValue = nativeGetter || false;
     this._internal = isInternalProperty || false;
 };
 
@@ -64,7 +65,7 @@ WebInspector.PropertyDescriptor.fromPayload = function(payload, internal)
         payload.isOwn = true;
     }
 
-    return new WebInspector.PropertyDescriptor(payload, payload.isOwn, payload.wasThrown, internal);
+    return new WebInspector.PropertyDescriptor(payload, payload.isOwn, payload.wasThrown, payload.nativeGetter, internal);
 };
 
 WebInspector.PropertyDescriptor.prototype = {
@@ -118,6 +119,11 @@ WebInspector.PropertyDescriptor.prototype = {
         return this._wasThrown;
     },
 
+    get nativeGetter()
+    {
+        return this._nativeGetterValue;
+    },
+
     get isInternalProperty()
     {
         return this._internal;
index 0a894d3..c6fc765 100644 (file)
@@ -72,9 +72,9 @@ WebInspector.RemoteObject.fromPayload = function(payload)
         // COMPATIBILITY (iOS 8): iOS 7 and 8 did not have type/subtype/description on
         // Runtime.ObjectPreview. Copy them over from the RemoteObject.
         if (!payload.preview.type) {
-            payload.preview.type = obj.type;
-            payload.preview.subtype = obj.subtype;
-            payload.preview.description = obj.description;
+            payload.preview.type = payload.type;
+            payload.preview.subtype = payload.subtype;
+            payload.preview.description = payload.description;
         }
         payload.preview = WebInspector.ObjectPreview.fromPayload(payload.preview);
     }
@@ -147,132 +147,112 @@ WebInspector.RemoteObject.prototype = {
 
     getOwnPropertyDescriptors: function(callback)
     {
-        this._getPropertyDescriptors(true, false, callback);
-    },
-
-    getOwnAndGetterPropertyDescriptors: function(callback)
-    {
-        this._getPropertyDescriptors(false, true, callback);
+        this._getPropertyDescriptors(true, callback);
     },
 
     getAllPropertyDescriptors: function(callback)
     {
-        this._getPropertyDescriptors(false, false, callback);
+        this._getPropertyDescriptors(false, callback);
     },
 
-    _getPropertyDescriptors: function(ownProperties, ownAndGetterProperties, callback)
+    getDisplayablePropertyDescriptors: function(callback)
     {
         if (!this._objectId || this._isSymbol()) {
             callback([]);
             return;
         }
 
-        function remoteObjectBinder(error, properties, internalProperties)
-        {
-            if (error) {
-                callback(null);
-                return;
-            }
-
-            var descriptors = properties.map(function(payload) {
-                return WebInspector.PropertyDescriptor.fromPayload(payload);
-            });
-
-            if (internalProperties) {
-                descriptors = descriptors.concat(internalProperties.map(function(payload) {
-                    return WebInspector.PropertyDescriptor.fromPayload(payload, true);
-                }));
-            }
-
-            callback(descriptors);
-        }
-
-        // COMPATIBILITY (iOS 8): RuntimeAgent.getProperties did not support ownerAndGetterProperties.
+        // COMPATIBILITY (iOS 8): RuntimeAgent.getDisplayableProperties did not exist.
         // Here we do our best to reimplement it by getting all properties and reducing them down.
-        if (ownAndGetterProperties && !RuntimeAgent.getProperties.supports("ownAndGetterProperties")) {
+        if (!RuntimeAgent.getDisplayableProperties) {
             RuntimeAgent.getProperties(this._objectId, function(error, allProperties) {
                 var ownOrGetterPropertiesList = [];
                 if (allProperties) {
                     for (var property of allProperties) {
-                        if (property.isOwn || property.get || property.name === "__proto__") {
+                        if (property.isOwn || property.name === "__proto__") {
                             // Own property or getter property in prototype chain.
                             ownOrGetterPropertiesList.push(property);
                         } else if (property.value && property.name !== property.name.toUpperCase()) {
                             var type = property.value.type;
                             if (type && type !== "function" && property.name !== "constructor") {
                                 // Possible native binding getter property converted to a value. Also, no CONSTANT name style and not "constructor".
+                                // There is no way of knowing if this is native or not, so just go with it.
                                 ownOrGetterPropertiesList.push(property);
                             }
                         }
                     }
                 }
-                remoteObjectBinder(error, ownOrGetterPropertiesList);
-            });
+                this._getPropertyDescriptorsResolver(callback, error, ownOrGetterPropertiesList);
+            }.bind(this));
             return;
         }
 
-        RuntimeAgent.getProperties(this._objectId, ownProperties, ownAndGetterProperties, true, remoteObjectBinder);
+        RuntimeAgent.getDisplayableProperties(this._objectId, true, this._getPropertyDescriptorsResolver.bind(this, callback));
     },
 
-    // FIXME: Phase out these functions. They return RemoteObjectProperty instead of PropertyDescriptors.
+    _getPropertyDescriptors: function(ownProperties, callback)
+    {
+        if (!this._objectId || this._isSymbol()) {
+            callback([]);
+            return;
+        }
 
-    getOwnProperties: function(callback)
+
+        RuntimeAgent.getProperties(this._objectId, ownProperties, true, this._getPropertyDescriptorsResolver.bind(this, callback));
+    },
+
+    _getPropertyDescriptorsResolver: function(callback, error, properties, internalProperties)
     {
-        this._getProperties(true, false, callback);
+        if (error) {
+            callback(null);
+            return;
+        }
+
+        var descriptors = properties.map(function(payload) {
+            return WebInspector.PropertyDescriptor.fromPayload(payload);
+        });
+
+        if (internalProperties) {
+            descriptors = descriptors.concat(internalProperties.map(function(payload) {
+                return WebInspector.PropertyDescriptor.fromPayload(payload, true);
+            }));
+        }
+
+        callback(descriptors);
     },
 
-    getOwnAndGetterProperties: function(callback)
+    // FIXME: Phase out these functions. They return RemoteObjectProperty instead of PropertyDescriptors.
+
+    deprecatedGetOwnProperties: function(callback)
     {
-        this._getProperties(false, true, callback);
+        this._deprecatedGetProperties(true, callback);
     },
 
-    getAllProperties: function(callback)
+    deprecatedGetAllProperties: function(callback)
     {
-        this._getProperties(false, false, callback);
+        this._deprecatedGetProperties(false, callback);
     },
 
-    _getProperties: function(ownProperties, ownAndGetterProperties, callback)
+    _deprecatedGetProperties: function(ownProperties, callback)
     {
         if (!this._objectId || this._isSymbol()) {
             callback([]);
             return;
         }
 
-        function remoteObjectBinder(error, properties, internalProperties)
-        {
-            if (error) {
-                callback(null);
-                return;
-            }
-
-            // FIXME: WebInspector.PropertyDescriptor instead of RemoteObjectProperty.
-            if (internalProperties) {
-                properties = properties.concat(internalProperties.map(function(descriptor) {
-                    descriptor.writable = false;
-                    descriptor.configurable = false;
-                    descriptor.enumerable = false;
-                    descriptor.isOwn = true;
-                    return descriptor;
-                }));
-            }
+        RuntimeAgent.getProperties(this._objectId, ownProperties, this._deprecatedGetPropertiesResolver.bind(this, callback));
+    },
 
-            var result = [];
-            for (var i = 0; properties && i < properties.length; ++i) {
-                var property = properties[i];
-                if (property.get || property.set) {
-                    if (property.get)
-                        result.push(new WebInspector.RemoteObjectProperty("get " + property.name, WebInspector.RemoteObject.fromPayload(property.get), property));
-                    if (property.set)
-                        result.push(new WebInspector.RemoteObjectProperty("set " + property.name, WebInspector.RemoteObject.fromPayload(property.set), property));
-                } else
-                    result.push(new WebInspector.RemoteObjectProperty(property.name, WebInspector.RemoteObject.fromPayload(property.value), property));
-            }
-            callback(result);
+    deprecatedGetDisplayableProperties: function(callback)
+    {
+        if (!this._objectId || this._isSymbol()) {
+            callback([]);
+            return;
         }
 
         // COMPATIBILITY (iOS 8): RuntimeAgent.getProperties did not support ownerAndGetterProperties.
         // Here we do our best to reimplement it by getting all properties and reducing them down.
-        if (ownAndGetterProperties && !RuntimeAgent.getProperties.supports("ownAndGetterProperties")) {
+        if (!RuntimeAgent.getDisplayableProperties) {
             RuntimeAgent.getProperties(this._objectId, function(error, allProperties) {
                 var ownOrGetterPropertiesList = [];
                 if (allProperties) {
@@ -289,12 +269,43 @@ WebInspector.RemoteObject.prototype = {
                         }
                     }
                 }
-                remoteObjectBinder(error, ownOrGetterPropertiesList);
-            });
+                this._deprecatedGetPropertiesResolver(callback, error, ownOrGetterPropertiesList);
+            }.bind(this));
+            return;
+        }
+
+        RuntimeAgent.getDisplayableProperties(this._objectId, this._deprecatedGetPropertiesResolver.bind(this, callback));
+    },
+
+    _deprecatedGetPropertiesResolver: function(callback, error, properties, internalProperties)
+    {
+        if (error) {
+            callback(null);
             return;
         }
 
-        RuntimeAgent.getProperties(this._objectId, ownProperties, ownAndGetterProperties, remoteObjectBinder);
+        if (internalProperties) {
+            properties = properties.concat(internalProperties.map(function(descriptor) {
+                descriptor.writable = false;
+                descriptor.configurable = false;
+                descriptor.enumerable = false;
+                descriptor.isOwn = true;
+                return descriptor;
+            }));
+        }
+
+        var result = [];
+        for (var i = 0; properties && i < properties.length; ++i) {
+            var property = properties[i];
+            if (property.get || property.set) {
+                if (property.get)
+                    result.push(new WebInspector.RemoteObjectProperty("get " + property.name, WebInspector.RemoteObject.fromPayload(property.get), property));
+                if (property.set)
+                    result.push(new WebInspector.RemoteObjectProperty("set " + property.name, WebInspector.RemoteObject.fromPayload(property.set), property));
+            } else
+                result.push(new WebInspector.RemoteObjectProperty(property.name, WebInspector.RemoteObject.fromPayload(property.value), property));
+        }
+        callback(result);
     },
 
     setPropertyValue: function(name, value, callback)
index 3d9ff58..1e61fec 100644 (file)
@@ -332,7 +332,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
     _formatParameterAsArray: function(arr, elem)
     {
         // FIXME: Array previews look poor. Keep doing what we currently do for arrays.
-        arr.getOwnProperties(this._printArray.bind(this, arr, elem));
+        arr.deprecatedGetOwnProperties(this._printArray.bind(this, arr, elem));
     },
 
     _userProvidedColumnNames: function(columnNamesArgument)
index f803d3e..89d0d36 100644 (file)
@@ -175,7 +175,7 @@ WebInspector.DOMNodeDetailsSidebarPanel.prototype = {
             if (this.domNode !== domNode)
                 return;
 
-            object.getOwnProperties(fillSection.bind(this));
+            object.deprecatedGetOwnProperties(fillSection.bind(this));
         }
 
         function fillSection(prototypes)
index 7948822..33775ac 100644 (file)
@@ -52,9 +52,9 @@ WebInspector.ObjectPropertiesSection.prototype = {
         }
 
         if (this.getAllProperties)
-            this.object.getAllProperties(callback.bind(this));
+            this.object.deprecatedGetAllProperties(callback.bind(this));
         else
-            this.object.getOwnAndGetterProperties(callback.bind(this));
+            this.object.deprecatedGetDisplayableProperties(callback.bind(this));
     },
 
     updateProperties: function(properties, rootTreeElementConstructor, rootPropertyComparer)
@@ -171,9 +171,9 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
         };
 
         if (this.property.name === "__proto__")
-            this.property.value.getOwnProperties(callback.bind(this));
+            this.property.value.deprecatedGetOwnProperties(callback.bind(this));
         else
-            this.property.value.getOwnAndGetterProperties(callback.bind(this));
+            this.property.value.deprecatedGetDisplayableProperties(callback.bind(this));
     },
 
     ondblclick: function(event)
index dceaab0..bb51e5e 100644 (file)
@@ -403,9 +403,17 @@ WebInspector.ObjectTreePropertyTreeElement.prototype = {
                     prototypeName = this._sanitizedPrototypeString(resolvedValue);
             }
 
+            var isAPI = mode === WebInspector.ObjectTreeView.Mode.API;
+
             properties.sort(WebInspector.ObjectTreeView.ComparePropertyDescriptors);
-            for (var propertyDescriptor of properties)
+            for (var propertyDescriptor of properties) {
+                // FIXME: If this is a pure API ObjectTree, we should show the native getters.
+                // For now, just skip native binding getters in API mode, since we likely
+                // already showed them in the Properties section.
+                if (isAPI && propertyDescriptor.nativeGetter)
+                    continue;
                 this.appendChild(new WebInspector.ObjectTreePropertyTreeElement(propertyDescriptor, resolvedValuePropertyPath, mode, prototypeName));
+            }
 
             // FIXME: Re-enable Collection Entries with new UI.
             // if (mode === WebInspector.ObjectTreeView.Mode.Properties) {
@@ -417,6 +425,6 @@ WebInspector.ObjectTreePropertyTreeElement.prototype = {
         if (this._property.name === "__proto__")
             resolvedValue.getOwnPropertyDescriptors(callback.bind(this, WebInspector.ObjectTreeView.Mode.API));
         else
-            resolvedValue.getOwnPropertyDescriptors(callback.bind(this, this._mode));
+            resolvedValue.getDisplayablePropertyDescriptors(callback.bind(this, this._mode));
     },
 };
index cee820a..96353d0 100644 (file)
@@ -171,7 +171,7 @@ WebInspector.ObjectTreeView.prototype = {
 
     update: function()
     {
-        this._object.getOwnPropertyDescriptors(this._updateProperties.bind(this));
+        this._object.getDisplayablePropertyDescriptors(this._updateProperties.bind(this));
     },
 
     // Private