Use tables to draw stack-frames.

BUG=#753
R=nduca@chromium.org, nduca@google.com

Review URL: https://codereview.appspot.com/255970044
diff --git a/tracing/tracing/ui/analysis/stack_frame.html b/tracing/tracing/ui/analysis/stack_frame.html
index afc4f57..25414f7 100644
--- a/tracing/tracing/ui/analysis/stack_frame.html
+++ b/tracing/tracing/ui/analysis/stack_frame.html
@@ -4,7 +4,7 @@
 Use of this source code is governed by a BSD-style license that can be
 found in the LICENSE file.
 -->
-<link rel="import" href="/ui/analysis/generic_object_view.html">
+<link rel="import" href="/ui/base/table.html">
 
 <polymer-element name="tr-ui-a-stack-frame">
   <template>
@@ -15,8 +15,7 @@
       align-items: center;
     }
     </style>
-    <tr-ui-a-generic-object-view id="ov">
-    </tr-ui-a-generic-object-view>
+    <tr-ui-b-table id="table"></tr-ui-b-table>
   </template>
   <script>
   'use strict';
@@ -24,6 +23,8 @@
   Polymer({
     ready: function() {
       this.stackFrame_ = undefined;
+      this.$.table.tableColumns = [];
+      this.$.table.showHeader = false;
     },
 
     get stackFrame() {
@@ -31,8 +32,48 @@
     },
 
     set stackFrame(stackFrame) {
+      var table = this.$.table;
+
       this.stackFrame_ = stackFrame;
-      this.$.ov.object = stackFrame.getUserFriendlyStackTrace();
+      if (stackFrame === undefined) {
+        table.tableColumns = [];
+        table.tableRows = [];
+        table.rebuild();
+        return;
+      }
+
+      var hasCategory = false;
+      var hasName = false;
+      var hasTitle = false;
+
+      table.tableRows = stackFrame.stackTrace;
+      table.tableRows.forEach(function(row) {
+        hasCategory |= row.category !== undefined;
+        hasName |= row.name !== undefined;
+        hasTitle |= row.title !== undefined;
+      });
+
+      var cols = [];
+      if (hasCategory)
+        cols.push({
+          title: 'Category',
+          value: function(row) { return row.category; }
+        });
+
+      if (hasName)
+        cols.push({
+          title: 'Name',
+          value: function(row) { return row.name; }
+        });
+
+      if (hasTitle)
+        cols.push({
+          title: 'Title',
+          value: function(row) { return row.title; }
+        });
+
+      table.tableColumns = cols;
+      table.rebuild();
     }
   });
   </script>
diff --git a/tracing/tracing/ui/analysis/stack_frame_test.html b/tracing/tracing/ui/analysis/stack_frame_test.html
index 18380c7..c7ddcfa 100644
--- a/tracing/tracing/ui/analysis/stack_frame_test.html
+++ b/tracing/tracing/ui/analysis/stack_frame_test.html
@@ -18,5 +18,17 @@
     stackFrameView.stackFrame = fA;
     this.addHTMLOutput(stackFrameView);
   });
+
+  test('clearingStackFrame', function() {
+    var model = new tr.Model();
+    var fA = tr.c.test_utils.newStackTrace(model, 'cat', ['a1', 'a2', 'a3']);
+
+    var stackFrameView = document.createElement('tr-ui-a-stack-frame');
+    stackFrameView.stackFrame = fA;
+    stackFrameView.stackFrame = undefined;
+
+    assert.isUndefined(stackFrameView.stackFrame);
+    assert.lengthOf(stackFrameView.$.table.$.body.children, 0);
+  });
 });
 </script>