Title: [181612] trunk
Revision
181612
Author
joep...@webkit.org
Date
2015-03-16 21:41:31 -0700 (Mon, 16 Mar 2015)

Log Message

Web Inspector: Better Console Previews for Arrays / Small Objects
https://bugs.webkit.org/show_bug.cgi?id=142322

Reviewed by Timothy Hatcher.

Source/_javascript_Core:

* inspector/InjectedScriptSource.js:
Create deep valuePreviews for simple previewable objects,
such as arrays with 5 values, or basic objects with
3 properties.

Source/WebInspectorUI:

* UserInterface/Views/ObjectPreviewView.js:
If there is a sub-preview, show the sub-preview.

* UserInterface/Views/ObjectTreeView.js:
(WebInspector.ObjectTreeView):
For an ObjectTree that is not a root (e.g. one inside of
an array/set/map property tree element) allow it to be
expanded even if the preview is lossless.

LayoutTests:

* inspector/model/remote-object-expected.txt:
* inspector/model/remote-object.html:
Include a test with cyclic values, and update
results which now have sub-previews.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (181611 => 181612)


--- trunk/LayoutTests/ChangeLog	2015-03-17 04:02:52 UTC (rev 181611)
+++ trunk/LayoutTests/ChangeLog	2015-03-17 04:41:31 UTC (rev 181612)
@@ -1,3 +1,15 @@
+2015-03-16  Joseph Pecoraro  <pecor...@apple.com>
+
+        Web Inspector: Better Console Previews for Arrays / Small Objects
+        https://bugs.webkit.org/show_bug.cgi?id=142322
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/model/remote-object-expected.txt:
+        * inspector/model/remote-object.html:
+        Include a test with cyclic values, and update
+        results which now have sub-previews.
+
 2015-03-16  Ryosuke Niwa  <rn...@webkit.org>
 
         Implement default constructor

Modified: trunk/LayoutTests/inspector/model/remote-object-expected.txt (181611 => 181612)


--- trunk/LayoutTests/inspector/model/remote-object-expected.txt	2015-03-17 04:02:52 UTC (rev 181611)
+++ trunk/LayoutTests/inspector/model/remote-object-expected.txt	2015-03-17 04:41:31 UTC (rev 181612)
@@ -592,7 +592,7 @@
     "_type": "object",
     "_subtype": "array",
     "_description": "Array",
-    "_lossless": false,
+    "_lossless": true,
     "_overflow": false,
     "_size": 3,
     "_properties": [
@@ -600,19 +600,64 @@
         "_name": "0",
         "_type": "object",
         "_subtype": "array",
-        "_value": "Array"
+        "_valuePreview": {
+          "_type": "object",
+          "_subtype": "array",
+          "_description": "Array",
+          "_lossless": true,
+          "_overflow": false,
+          "_size": 1,
+          "_properties": [
+            {
+              "_name": "0",
+              "_type": "number",
+              "_value": "1"
+            }
+          ],
+          "_entries": null
+        }
       },
       {
         "_name": "1",
         "_type": "object",
         "_subtype": "array",
-        "_value": "Array"
+        "_valuePreview": {
+          "_type": "object",
+          "_subtype": "array",
+          "_description": "Array",
+          "_lossless": true,
+          "_overflow": false,
+          "_size": 1,
+          "_properties": [
+            {
+              "_name": "0",
+              "_type": "number",
+              "_value": "2"
+            }
+          ],
+          "_entries": null
+        }
       },
       {
         "_name": "2",
         "_type": "object",
         "_subtype": "array",
-        "_value": "Array"
+        "_valuePreview": {
+          "_type": "object",
+          "_subtype": "array",
+          "_description": "Array",
+          "_lossless": true,
+          "_overflow": false,
+          "_size": 1,
+          "_properties": [
+            {
+              "_name": "0",
+              "_type": "number",
+              "_value": "3"
+            }
+          ],
+          "_entries": null
+        }
       }
     ],
     "_entries": null
@@ -678,24 +723,63 @@
     "_type": "object",
     "_subtype": "array",
     "_description": "Array",
-    "_lossless": false,
+    "_lossless": true,
     "_overflow": false,
     "_size": 3,
     "_properties": [
       {
         "_name": "0",
         "_type": "object",
-        "_value": "Object"
+        "_valuePreview": {
+          "_type": "object",
+          "_description": "Object",
+          "_lossless": true,
+          "_overflow": false,
+          "_properties": [
+            {
+              "_name": "a",
+              "_type": "number",
+              "_value": "1"
+            }
+          ],
+          "_entries": null
+        }
       },
       {
         "_name": "1",
         "_type": "object",
-        "_value": "Object"
+        "_valuePreview": {
+          "_type": "object",
+          "_description": "Object",
+          "_lossless": true,
+          "_overflow": false,
+          "_properties": [
+            {
+              "_name": "b",
+              "_type": "number",
+              "_value": "2"
+            }
+          ],
+          "_entries": null
+        }
       },
       {
         "_name": "2",
         "_type": "object",
-        "_value": "Object"
+        "_valuePreview": {
+          "_type": "object",
+          "_description": "Object",
+          "_lossless": true,
+          "_overflow": false,
+          "_properties": [
+            {
+              "_name": "c",
+              "_type": "number",
+              "_value": "2"
+            }
+          ],
+          "_entries": null
+        }
       }
     ],
     "_entries": null
@@ -714,7 +798,7 @@
     "_type": "object",
     "_subtype": "array",
     "_description": "Array",
-    "_lossless": false,
+    "_lossless": true,
     "_overflow": false,
     "_size": 1,
     "_properties": [
@@ -722,7 +806,71 @@
         "_name": "0",
         "_type": "object",
         "_subtype": "array",
-        "_value": "Array"
+        "_valuePreview": {
+          "_type": "object",
+          "_subtype": "array",
+          "_description": "Array",
+          "_lossless": true,
+          "_overflow": false,
+          "_size": 3,
+          "_properties": [
+            {
+              "_name": "0",
+              "_type": "object",
+              "_valuePreview": {
+                "_type": "object",
+                "_description": "Object",
+                "_lossless": true,
+                "_overflow": false,
+                "_properties": [
+                  {
+                    "_name": "a",
+                    "_type": "number",
+                    "_value": "1"
+                  }
+                ],
+                "_entries": null
+              }
+            },
+            {
+              "_name": "1",
+              "_type": "object",
+              "_valuePreview": {
+                "_type": "object",
+                "_description": "Object",
+                "_lossless": true,
+                "_overflow": false,
+                "_properties": [
+                  {
+                    "_name": "b",
+                    "_type": "number",
+                    "_value": "2"
+                  }
+                ],
+                "_entries": null
+              }
+            },
+            {
+              "_name": "2",
+              "_type": "object",
+              "_valuePreview": {
+                "_type": "object",
+                "_description": "Object",
+                "_lossless": true,
+                "_overflow": false,
+                "_properties": [
+                  {
+                    "_name": "c",
+                    "_type": "number",
+                    "_value": "2"
+                  }
+                ],
+                "_entries": null
+              }
+            }
+          ],
+          "_entries": null
+        }
       }
     ],
     "_entries": null
@@ -1554,6 +1702,33 @@
 }
 
 -----------------------------------------------------
+_expression_: o = {a:1}; o.b = o; o
+{
+  "_type": "object",
+  "_objectId": "<filtered>",
+  "_description": "Object",
+  "_preview": {
+    "_type": "object",
+    "_description": "Object",
+    "_lossless": false,
+    "_overflow": false,
+    "_properties": [
+      {
+        "_name": "a",
+        "_type": "number",
+        "_value": "1"
+      },
+      {
+        "_name": "b",
+        "_type": "object",
+        "_value": "Object"
+      }
+    ],
+    "_entries": null
+  }
+}
+
+-----------------------------------------------------
 _expression_: ({a:function a(){}, b:function b(){}, get getter(){}, set setter(v){}})
 {
   "_type": "object",
@@ -2948,14 +3123,23 @@
     "_type": "object",
     "_subtype": "iterator",
     "_description": "ArrayIterator",
-    "_lossless": false,
+    "_lossless": true,
     "_overflow": false,
     "_properties": [
       {
         "_name": "array",
         "_type": "object",
         "_subtype": "array",
-        "_value": "Array",
+        "_valuePreview": {
+          "_type": "object",
+          "_subtype": "array",
+          "_description": "Array",
+          "_lossless": true,
+          "_overflow": false,
+          "_size": 0,
+          "_properties": [],
+          "_entries": null
+        },
         "_internal": true
       },
       {
@@ -2980,14 +3164,29 @@
     "_type": "object",
     "_subtype": "iterator",
     "_description": "ArrayIterator",
-    "_lossless": false,
+    "_lossless": true,
     "_overflow": false,
     "_properties": [
       {
         "_name": "array",
         "_type": "object",
         "_subtype": "array",
-        "_value": "Array",
+        "_valuePreview": {
+          "_type": "object",
+          "_subtype": "array",
+          "_description": "Array",
+          "_lossless": true,
+          "_overflow": false,
+          "_size": 1,
+          "_properties": [
+            {
+              "_name": "0",
+              "_type": "number",
+              "_value": "1"
+            }
+          ],
+          "_entries": null
+        },
         "_internal": true
       },
       {
@@ -3684,14 +3883,34 @@
     "_type": "object",
     "_subtype": "iterator",
     "_description": "ArgumentsIterator",
-    "_lossless": false,
+    "_lossless": true,
     "_overflow": false,
     "_properties": [
       {
         "_name": "arguments",
         "_type": "object",
         "_subtype": "array",
-        "_value": "Arguments",
+        "_valuePreview": {
+          "_type": "object",
+          "_subtype": "array",
+          "_description": "Arguments",
+          "_lossless": true,
+          "_overflow": false,
+          "_size": 2,
+          "_properties": [
+            {
+              "_name": "0",
+              "_type": "number",
+              "_value": "1"
+            },
+            {
+              "_name": "1",
+              "_type": "string",
+              "_value": "two"
+            }
+          ],
+          "_entries": null
+        },
         "_internal": true
       }
     ],
@@ -3839,7 +4058,7 @@
   "_preview": {
     "_type": "object",
     "_description": "Promise",
-    "_lossless": false,
+    "_lossless": true,
     "_overflow": false,
     "_properties": [
       {
@@ -3851,7 +4070,20 @@
       {
         "_name": "result",
         "_type": "object",
-        "_value": "Object",
+        "_valuePreview": {
+          "_type": "object",
+          "_description": "Object",
+          "_lossless": true,
+          "_overflow": false,
+          "_properties": [
+            {
+              "_name": "result",
+              "_type": "number",
+              "_value": "1"
+            }
+          ],
+          "_entries": null
+        },
         "_internal": true
       }
     ],

Modified: trunk/LayoutTests/inspector/model/remote-object.html (181611 => 181612)


--- trunk/LayoutTests/inspector/model/remote-object.html	2015-03-17 04:02:52 UTC (rev 181611)
+++ trunk/LayoutTests/inspector/model/remote-object.html	2015-03-17 04:41:31 UTC (rev 181612)
@@ -91,6 +91,7 @@
         {_expression_: "({a: 1})"},
         {_expression_: "({a: 1, b: 0, c: -0})"},
         {_expression_: "({a: 1, b: \"string\", c: /regex/, d: Symbol('sym')})"},
+        {_expression_: "o = {a:1}; o.b = o; o"}, // Cyclic.
         {_expression_: "({a:function a(){}, b:function b(){}, get getter(){}, set setter(v){}})"},
         {_expression_: "function Foo() {}; new Foo"},
         {_expression_: "var Foo2 = function() {}; new Foo2"},

Modified: trunk/Source/_javascript_Core/ChangeLog (181611 => 181612)


--- trunk/Source/_javascript_Core/ChangeLog	2015-03-17 04:02:52 UTC (rev 181611)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-03-17 04:41:31 UTC (rev 181612)
@@ -1,3 +1,15 @@
+2015-03-16  Joseph Pecoraro  <pecor...@apple.com>
+
+        Web Inspector: Better Console Previews for Arrays / Small Objects
+        https://bugs.webkit.org/show_bug.cgi?id=142322
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/InjectedScriptSource.js:
+        Create deep valuePreviews for simple previewable objects,
+        such as arrays with 5 values, or basic objects with
+        3 properties.
+
 2015-03-16  Ryosuke Niwa  <rn...@webkit.org>
 
         Add support for default constructor

Modified: trunk/Source/_javascript_Core/inspector/InjectedScriptSource.js (181611 => 181612)


--- trunk/Source/_javascript_Core/inspector/InjectedScriptSource.js	2015-03-17 04:02:52 UTC (rev 181611)
+++ trunk/Source/_javascript_Core/inspector/InjectedScriptSource.js	2015-03-17 04:41:31 UTC (rev 181612)
@@ -990,13 +990,14 @@
                     return preview;
             }
 
+            if (preview.entries)
+                return preview;
+
             // Properties.
             var descriptors = injectedScript._propertyDescriptors(object, InjectedScript.CollectionMode.AllProperties);
             this._appendPropertyPreviews(preview, descriptors, false, propertiesThreshold, firstLevelKeys, secondLevelKeys);
             if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0)
                 return preview;
-
-            // FIXME: Iterator entries.
         } catch (e) {
             preview.lossless = false;
         }
@@ -1093,6 +1094,13 @@
                     preview.lossless = false;
                 if (subPreview.overflow)
                     preview.overflow = true;
+            } else if (this._isPreviewableObject(value)) {
+                var subPreview = this._createObjectPreviewForValue(value);
+                property.valuePreview = subPreview;
+                if (!subPreview.lossless)
+                    preview.lossless = false;
+                if (subPreview.overflow)
+                    preview.overflow = true;
             } else {
                 var description = "";
                 if (type !== "function")
@@ -1145,6 +1153,57 @@
         }, this);
     },
 
+    _isPreviewableObject: function(object)
+    {
+        return this._isPreviewableObjectInternal(object, new Set, 1);
+    },
+
+    _isPreviewableObjectInternal: function(object, knownObjects, depth)
+    {
+        // Deep object.
+        if (depth > 3)
+            return false;
+
+        // Primitive.
+        if (injectedScript.isPrimitiveValue(object) || isSymbol(object))
+            return true;
+
+        // Cyclic objects.
+        if (knownObjects.has(object))
+            return false;
+
+        ++depth;
+        knownObjects.add(object);
+
+        // Arrays are simple if they have 5 or less simple objects.
+        var subtype = injectedScript._subtype(object);
+        if (subtype === "array") {
+            var length = object.length;
+            if (length > 5)
+                return false;
+            for (var i = 0; i < length; ++i) {
+                if (!this._isPreviewableObjectInternal(object[i], knownObjects, depth))
+                    return false;
+            }
+            return true;
+        }
+
+        // Not a basic object.
+        if (object.__proto__ && object.__proto__.__proto__)
+            return false;
+
+        // Objects are simple if they have 3 or less simple properties.
+        var ownPropertyNames = Object.getOwnPropertyNames(object);
+        if (ownPropertyNames.length > 3)
+            return false;
+        for (var propertyName of ownPropertyNames) {
+            if (!this._isPreviewableObjectInternal(object[propertyName], knownObjects, depth))
+                return false;
+        }
+
+        return true;
+    },
+
     _abbreviateString: function(string, maxLength, middle)
     {
         if (string.length <= maxLength)

Modified: trunk/Source/WebInspectorUI/ChangeLog (181611 => 181612)


--- trunk/Source/WebInspectorUI/ChangeLog	2015-03-17 04:02:52 UTC (rev 181611)
+++ trunk/Source/WebInspectorUI/ChangeLog	2015-03-17 04:41:31 UTC (rev 181612)
@@ -1,3 +1,19 @@
+2015-03-16  Joseph Pecoraro  <pecor...@apple.com>
+
+        Web Inspector: Better Console Previews for Arrays / Small Objects
+        https://bugs.webkit.org/show_bug.cgi?id=142322
+
+        Reviewed by Timothy Hatcher.
+
+        * UserInterface/Views/ObjectPreviewView.js:
+        If there is a sub-preview, show the sub-preview.
+
+        * UserInterface/Views/ObjectTreeView.js:
+        (WebInspector.ObjectTreeView):
+        For an ObjectTree that is not a root (e.g. one inside of
+        an array/set/map property tree element) allow it to be
+        expanded even if the preview is lossless.
+
 2015-03-16  Nikita Vasilyev  <nvasil...@apple.com>
 
         Web Inspector: Rename ConsoleMessage and ConsoleMessageImpl to LegacyConsoleMessage and LegacyConsoleMessageImpl respectively

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectPreviewView.js (181611 => 181612)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectPreviewView.js	2015-03-17 04:02:52 UTC (rev 181611)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectPreviewView.js	2015-03-17 04:41:31 UTC (rev 181612)
@@ -211,7 +211,10 @@
                 element.appendChild(document.createTextNode(": "));
             }
 
-            element.appendChild(WebInspector.FormattedValue.createElementForPropertyPreview(property));
+            if (property.valuePreview)
+                this._appendPreview(element, property.valuePreview);
+            else
+                element.appendChild(WebInspector.FormattedValue.createElementForPropertyPreview(property));
         }
 
         if (preview.overflow)

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.js (181611 => 181612)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.js	2015-03-17 04:02:52 UTC (rev 181611)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.js	2015-03-17 04:41:31 UTC (rev 181612)
@@ -49,7 +49,7 @@
         this._previewView.element.addEventListener("click", this._handlePreviewOrTitleElementClick.bind(this));
         this._element.appendChild(this._previewView.element);
 
-        if (this._previewView.lossless && !forceExpanding) {
+        if (this._previewView.lossless && !this._propertyPath.parent && !forceExpanding) {
             this._hasLosslessPreview = true;
             this.element.classList.add("lossless-preview");
         }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to