Title: [124876] trunk/Source/WebCore
Revision
124876
Author
[email protected]
Date
2012-08-07 04:28:24 -0700 (Tue, 07 Aug 2012)

Log Message

Web Inspector: display function scope in UI
https://bugs.webkit.org/show_bug.cgi?id=90631

Patch by Peter Rybin <[email protected]> on 2012-08-07
Reviewed by Yury Semikhatsky.

Two new tree element types added: function scope group node and scope node.
Scope node is only used to represent closure and catch scopes. Scopes that
have a real object beneath are represented as a property node.
A method that reads properties from RemoteObject and populate tree element
is factored out from RemoteObjectTreeElement for reuse.

* inspector/front-end/ObjectPropertiesSection.js:
(WebInspector.ObjectPropertyTreeElement.prototype.onpopulate):
(WebInspector.ObjectPropertyTreeElement.Populate.callback):
(WebInspector.ObjectPropertyTreeElement.Populate):
(WebInspector.FunctionScopeMainTreeElement):
(WebInspector.FunctionScopeMainTreeElement.prototype.onpopulate.didGetDetails):
(WebInspector.FunctionScopeMainTreeElement.prototype.onpopulate):
(WebInspector.FunctionScopeMainTreeElement.prototype.onattach):
(WebInspector.FunctionScopeMainTreeElement.prototype.update):
(WebInspector.ScopeTreeElement):
(WebInspector.ScopeTreeElement.prototype.onpopulate):
(WebInspector.ScopeTreeElement.prototype.onattach):
(WebInspector.ScopeTreeElement.prototype.update):
* inspector/front-end/RemoteObject.js:
(WebInspector.RemoteObjectProperty.fromScopeValue):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (124875 => 124876)


--- trunk/Source/WebCore/ChangeLog	2012-08-07 10:46:14 UTC (rev 124875)
+++ trunk/Source/WebCore/ChangeLog	2012-08-07 11:28:24 UTC (rev 124876)
@@ -1,3 +1,33 @@
+2012-08-07  Peter Rybin  <[email protected]>
+
+        Web Inspector: display function scope in UI
+        https://bugs.webkit.org/show_bug.cgi?id=90631
+
+        Reviewed by Yury Semikhatsky.
+
+        Two new tree element types added: function scope group node and scope node.
+        Scope node is only used to represent closure and catch scopes. Scopes that
+        have a real object beneath are represented as a property node.
+        A method that reads properties from RemoteObject and populate tree element
+        is factored out from RemoteObjectTreeElement for reuse.
+
+        * inspector/front-end/ObjectPropertiesSection.js:
+        (WebInspector.ObjectPropertyTreeElement.prototype.onpopulate):
+        (WebInspector.ObjectPropertyTreeElement.Populate.callback):
+        (WebInspector.ObjectPropertyTreeElement.Populate):
+        (WebInspector.FunctionScopeMainTreeElement):
+        (WebInspector.FunctionScopeMainTreeElement.prototype.onpopulate.didGetDetails):
+        (WebInspector.FunctionScopeMainTreeElement.prototype.onpopulate):
+        (WebInspector.FunctionScopeMainTreeElement.prototype.onattach):
+        (WebInspector.FunctionScopeMainTreeElement.prototype.update):
+        (WebInspector.ScopeTreeElement):
+        (WebInspector.ScopeTreeElement.prototype.onpopulate):
+        (WebInspector.ScopeTreeElement.prototype.onattach):
+        (WebInspector.ScopeTreeElement.prototype.update):
+        * inspector/front-end/RemoteObject.js:
+        (WebInspector.RemoteObjectProperty.fromScopeValue):
+
+
 2012-08-07  Vineet Chaudhary  <[email protected]>
 
         [V8] Remove custom toV8() calls for TypedArray.

Modified: trunk/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js (124875 => 124876)


--- trunk/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js	2012-08-07 10:46:14 UTC (rev 124875)
+++ trunk/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js	2012-08-07 11:28:24 UTC (rev 124876)
@@ -226,31 +226,7 @@
 WebInspector.ObjectPropertyTreeElement.prototype = {
     onpopulate: function()
     {
-        if (this.children.length && !this.shouldRefreshChildren)
-            return;
-
-        if (this.property.value.arrayLength() > WebInspector.ObjectPropertiesSection._arrayLoadThreshold) {
-            this.removeChildren();
-            WebInspector.ArrayGroupingTreeElement._populateArray(this, this.property.value, 0, this.property.value.arrayLength() - 1);
-            return;
-        }
-
-        function callback(properties)
-        {
-            this.removeChildren();
-            if (!properties)
-                return;
-
-            properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
-            for (var i = 0; i < properties.length; ++i) {
-                if (this.treeOutline.section.skipProto && properties[i].name === "__proto__")
-                    continue;
-                properties[i].parentObject = this.property.value;
-                this.appendChild(new this.treeOutline.section.treeElementConstructor(properties[i]));
-            }
-        }
-
-        this.property.value.getOwnProperties(callback.bind(this));
+        return WebInspector.ObjectPropertyTreeElement.populate(this, this.property.value);
     },
 
     ondblclick: function(event)
@@ -305,7 +281,7 @@
             this.valueElement.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), false);
 
         this.valueElement.title = description || "";
-        
+
         this.listItemElement.removeChildren();
 
         this.listItemElement.appendChild(this.nameElement);
@@ -468,11 +444,146 @@
     }
 }
 
+/**
+ * @param {TreeElement} treeElement
+ * @param {WebInspector.RemoteObject} value
+ */
+WebInspector.ObjectPropertyTreeElement.populate = function(treeElement, value) {
+    if (treeElement.children.length && !treeElement.shouldRefreshChildren)
+        return;
+
+    if (value.arrayLength() > WebInspector.ObjectPropertiesSection._arrayLoadThreshold) {
+        treeElement.removeChildren();
+        WebInspector.ArrayGroupingTreeElement._populateArray(treeElement, value, 0, value.arrayLength() - 1);
+        return;
+    }
+
+    function callback(properties)
+    {
+        treeElement.removeChildren();
+        if (!properties)
+            return;
+
+        properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
+        for (var i = 0; i < properties.length; ++i) {
+            if (treeElement.treeOutline.section.skipProto && properties[i].name === "__proto__")
+                continue;
+            properties[i].parentObject = value;
+            treeElement.appendChild(new treeElement.treeOutline.section.treeElementConstructor(properties[i]));
+        }
+        if (value.type === "function")
+            treeElement.appendChild(new WebInspector.FunctionScopeMainTreeElement(value));
+    }
+
+    value.getOwnProperties(callback);
+}
+
 WebInspector.ObjectPropertyTreeElement.prototype.__proto__ = TreeElement.prototype;
 
 /**
  * @constructor
  * @extends {TreeElement}
+ * @param {WebInspector.RemoteObject} remoteObject
+ */
+WebInspector.FunctionScopeMainTreeElement = function(remoteObject)
+{
+    TreeElement.call(this, "<function scope>", null, false);
+    this.toggleOnClick = true;
+    this.selectable = false;
+    this._remoteObject = remoteObject;
+    this.hasChildren = true;
+}
+
+WebInspector.FunctionScopeMainTreeElement.prototype = {
+    onpopulate: function()
+    {
+        if (this.children.length && !this.shouldRefreshChildren)
+            return;
+
+        function didGetDetails(error, response)
+        {
+            if (error) {
+                console.error(error);
+                return;
+            }
+            this.removeChildren();
+
+            var scopeChain = response.scopeChain;
+            for (var i = 0; i < scopeChain.length; ++i) {
+                var scope = scopeChain[i];
+                var title = null;
+                var isTrueObject;
+
+                switch (scope.type) {
+                    case "local":
+                        // Not really expecting this scope type here.
+                        title = WebInspector.UIString("Local");
+                        isTrueObject = false;
+                        break;
+                    case "closure":
+                        title = WebInspector.UIString("Closure");
+                        isTrueObject = false;
+                        break;
+                    case "catch":
+                        title = WebInspector.UIString("Catch");
+                        isTrueObject = false;
+                        break;
+                    case "with":
+                        title = WebInspector.UIString("With Block");
+                        isTrueObject = true;
+                        break;
+                    case "global":
+                        title = WebInspector.UIString("Global");
+                        isTrueObject = true;
+                        break;
+                }
+
+                var remoteObject = WebInspector.RemoteObject.fromPayload(scope.object);
+                if (isTrueObject) {
+                    var property = WebInspector.RemoteObjectProperty.fromScopeValue(title, remoteObject);
+                    property.parentObject = null;
+                    this.appendChild(new this.treeOutline.section.treeElementConstructor(property));
+                } else {
+                    var scopeTreeElement = new WebInspector.ScopeTreeElement(title, null, remoteObject);
+                    this.appendChild(scopeTreeElement);
+                }
+            }
+
+        }
+        DebuggerAgent.getFunctionDetails(this._remoteObject.objectId, didGetDetails.bind(this));
+
+    }
+};
+
+WebInspector.FunctionScopeMainTreeElement.prototype.__proto__ = TreeElement.prototype;
+
+/**
+ * @constructor
+ * @extends {TreeElement}
+ * @param {WebInspector.RemoteObject} remoteObject
+ */
+WebInspector.ScopeTreeElement = function(title, subtitle, remoteObject)
+{
+    // TODO: use subtitle parameter.
+    TreeElement.call(this, title, null, false);
+    this.toggleOnClick = true;
+    this.selectable = false;
+    this._remoteObject = remoteObject;
+    this.hasChildren = true;
+}
+
+WebInspector.ScopeTreeElement.prototype = {
+    onpopulate: function()
+    {
+        return WebInspector.ObjectPropertyTreeElement.populate(this, this._remoteObject);
+    }
+};
+
+WebInspector.ScopeTreeElement.prototype.__proto__ = TreeElement.prototype;
+
+/**
+ * @constructor
+ * @extends {TreeElement}
  * @param {WebInspector.RemoteObject} object
  * @param {number} fromIndex
  * @param {number} toIndex
@@ -679,7 +790,7 @@
     {
         if (this._populated)
             return;
-        
+
         this._populated = true;
 
         if (this._propertyCount >= WebInspector.ArrayGroupingTreeElement._bucketThreshold) {

Modified: trunk/Source/WebCore/inspector/front-end/RemoteObject.js (124875 => 124876)


--- trunk/Source/WebCore/inspector/front-end/RemoteObject.js	2012-08-07 10:46:14 UTC (rev 124875)
+++ trunk/Source/WebCore/inspector/front-end/RemoteObject.js	2012-08-07 11:28:24 UTC (rev 124876)
@@ -336,7 +336,7 @@
 /**
  * @constructor
  * @param {string} name
- * @param {WebInspector.RemoteObject} value 
+ * @param {WebInspector.RemoteObject} value
  * @param {Object=} descriptor
  */
 WebInspector.RemoteObjectProperty = function(name, value, descriptor)
@@ -359,6 +359,18 @@
     return new WebInspector.RemoteObjectProperty(name, WebInspector.RemoteObject.fromPrimitiveValue(value));
 }
 
+/**
+ * @param {string} name
+ * @param {WebInspector.RemoteObject} value
+ * @return {WebInspector.RemoteObjectProperty}
+ */
+WebInspector.RemoteObjectProperty.fromScopeValue = function(name, value)
+{
+    var result = new WebInspector.RemoteObjectProperty(name, value);
+    result.writable = false;
+    return result;
+}
+
 // The below is a wrapper around a local object that provides an interface comaptible
 // with RemoteObject, to be used by the UI code (primarily ObjectPropertiesSection).
 // Note that only JSON-compliant objects are currently supported, as there's no provision
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to