blob: fb6778b92a5cbda00d3487cc27c4209b76ea290b [file] [log] [blame]
Chris Craikb122baf2015-03-05 13:58:42 -08001<!DOCTYPE html>
2<!--
3Copyright (c) 2013 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/core/analysis/analysis_link.html">
Chris Craik44c28202015-05-12 17:25:16 -07009<link rel="import" href="/base/time.html">
Chris Craikb122baf2015-03-05 13:58:42 -080010<link rel="import" href="/base/utils.html">
11<link rel="import" href="/base/ui.html">
12
13<polymer-element name="tv-c-analysis-generic-object-view"
14 is="HTMLUnknownElement">
15 <template>
16 <style>
17 :host {
18 display: block;
19 font-family: monospace;
20 }
21 </style>
Chris Craikbeca7ae2015-04-07 13:29:55 -070022 <div id="content">
23 </div>
Chris Craikb122baf2015-03-05 13:58:42 -080024 </template>
25
26 <script>
27 'use strict';
28
Chris Craik44c28202015-05-12 17:25:16 -070029 function isTable(object) {
30 if (!(object instanceof Array) ||
31 (object.length < 2)) return false;
32 for (var colName in object[0]) {
33 if (typeof colName !== 'string') return false;
34 }
35 for (var i = 0; i < object.length; ++i) {
36 if (!(object[i] instanceof Object)) return false;
37 for (var colName in object[i]) {
38 if (i && (object[0][colName] === undefined)) return false;
39 var cellType = typeof object[i][colName];
40 if (cellType !== 'string' && cellType != 'number') return false;
41 }
42 if (i) {
43 for (var colName in object[0]) {
44 if (object[i][colName] === undefined) return false;
45 }
46 }
47 }
48 return true;
49 }
50
Chris Craikb122baf2015-03-05 13:58:42 -080051 Polymer({
52 ready: function() {
53 this.object_ = undefined;
54 },
55
56 get object() {
57 return this.object_;
58 },
59
60 set object(object) {
61 this.object_ = object;
62 this.updateContents_();
63 },
64
65 updateContents_: function() {
Chris Craikbeca7ae2015-04-07 13:29:55 -070066 this.$.content.textContent = '';
Chris Craikb122baf2015-03-05 13:58:42 -080067 this.appendElementsForType_('', this.object_, 0, 0, 5, '');
68 },
69
70 appendElementsForType_: function(
71 label, object, indent, depth, maxDepth, suffix) {
72 if (depth > maxDepth) {
73 this.appendSimpleText_(
74 label, indent, '<recursion limit reached>', suffix);
75 return;
76 }
77
78 if (object === undefined) {
79 this.appendSimpleText_(label, indent, 'undefined', suffix);
80 return;
81 }
82
83 if (object === null) {
84 this.appendSimpleText_(label, indent, 'null', suffix);
85 return;
86 }
87
88 if (!(object instanceof Object)) {
89 var type = typeof object;
90 if (type == 'string') {
91 var objectReplaced = false;
92 if ((object[0] == '{' && object[object.length - 1] == '}') ||
93 (object[0] == '[' && object[object.length - 1] == ']')) {
94 try {
95 object = JSON.parse(object);
96 objectReplaced = true;
97 } catch (e) {
98 }
99 }
Chris Craik44c28202015-05-12 17:25:16 -0700100 if (!objectReplaced) {
101 if (object.indexOf('\n') !== -1) {
102 var lines = object.split('\n');
103 lines.forEach(function(line, i) {
104 var text, ioff, ll, ss;
105 if (i == 0) {
106 text = '"' + line;
107 ioff = 0;
108 ll = label;
109 ss = '';
110 } else if (i < lines.length - 1) {
111 text = line;
112 ioff = 1;
113 ll = '';
114 ss = '';
115 } else {
116 text = line + '"';
117 ioff = 1;
118 ll = '';
119 ss = suffix;
120 }
121
122 var el = this.appendSimpleText_(
123 ll, indent + ioff * label.length + ioff, text, ss);
124 el.style.whiteSpace = 'pre';
125 return el;
126 }, this);
127 return;
128 } else {
129 this.appendSimpleText_(
130 label, indent, '"' + object + '"', suffix);
131 return;
132 }
133 }
Chris Craikb122baf2015-03-05 13:58:42 -0800134 else {
135 /* Fall through to the flow below */
136 }
137 } else {
138 return this.appendSimpleText_(label, indent, object, suffix);
139 }
140 }
141
142 if (object instanceof tv.c.trace_model.ObjectSnapshot) {
143 var link = document.createElement('tv-c-analysis-link');
144 link.selection = new tv.c.Selection(object);
145 this.appendElementWithLabel_(label, indent, link, suffix);
146 return;
147 }
148
149 if (object instanceof tv.c.trace_model.ObjectInstance) {
150 var link = document.createElement('tv-c-analysis-link');
151 link.selection = new tv.c.Selection(object);
152 this.appendElementWithLabel_(label, indent, link, suffix);
153 return;
154 }
155
156 if (object instanceof tv.b.Rect) {
157 this.appendSimpleText_(label, indent, object.toString(), suffix);
158 return;
159 }
160
Chris Craik44c28202015-05-12 17:25:16 -0700161 if (object instanceof tv.b.TimeDuration) {
162 var el = this.ownerDocument.createElement('tv-c-a-time-span');
163 el.duration = object.duration;
164 this.appendElementWithLabel_(label, indent, el, suffix);
165 return;
166 }
167
168 if (object instanceof tv.b.TimeStamp) {
169 var el = this.ownerDocument.createElement('tv-c-a-time-stamp');
170 el.timestamp = object.timestamp;
171 this.appendElementWithLabel_(label, indent, el, suffix);
172 return;
173 }
174
Chris Craikb122baf2015-03-05 13:58:42 -0800175 if (object instanceof Array) {
176 this.appendElementsForArray_(
177 label, object, indent, depth, maxDepth, suffix);
178 return;
179 }
180
181 this.appendElementsForObject_(
182 label, object, indent, depth, maxDepth, suffix);
183 },
184
185 appendElementsForArray_: function(
186 label, object, indent, depth, maxDepth, suffix) {
187 if (object.length == 0) {
188 this.appendSimpleText_(label, indent, '[]', suffix);
189 return;
190 }
191
Chris Craik44c28202015-05-12 17:25:16 -0700192 if (isTable(object)) {
193 var table = document.createElement('table');
194 var tr = document.createElement('tr');
195 table.appendChild(tr);
196 var columns = [];
197 for (var colName in object[0]) {
198 columns.push(colName);
199 var th = document.createElement('th');
200 th.textContent = colName;
201 tr.appendChild(th);
202 }
203 object.forEach(function(row) {
204 var tr = document.createElement('tr');
205 table.appendChild(tr);
206 columns.forEach(function(colName) {
207 var cell = row[colName];
208 var td = document.createElement('td');
209 td.textContent = cell;
210 td.style.textAlign = isNaN(parseFloat(cell)) ? 'left' : 'right';
211 tr.appendChild(td);
212 });
213 });
214 this.appendElementWithLabel_(label, indent, table, suffix);
215 return;
216 }
217
Chris Craikb122baf2015-03-05 13:58:42 -0800218 this.appendElementsForType_(
219 label + '[',
220 object[0],
221 indent, depth + 1, maxDepth,
222 object.length > 1 ? ',' : ']' + suffix);
223 for (var i = 1; i < object.length; i++) {
224 this.appendElementsForType_(
225 '',
226 object[i],
227 indent + label.length + 1, depth + 1, maxDepth,
228 i < object.length - 1 ? ',' : ']' + suffix);
229 }
230 return;
231 },
232
233 appendElementsForObject_: function(
234 label, object, indent, depth, maxDepth, suffix) {
235 var keys = tv.b.dictionaryKeys(object);
236 if (keys.length == 0) {
237 this.appendSimpleText_(label, indent, '{}', suffix);
238 return;
239 }
240
241 this.appendElementsForType_(
242 label + '{' + keys[0] + ': ',
243 object[keys[0]],
244 indent, depth, maxDepth,
245 keys.length > 1 ? ',' : '}' + suffix);
246 for (var i = 1; i < keys.length; i++) {
247 this.appendElementsForType_(
248 keys[i] + ': ',
249 object[keys[i]],
250 indent + label.length + 1, depth + 1, maxDepth,
251 i < keys.length - 1 ? ',' : '}' + suffix);
252 }
253 },
254
255 appendElementWithLabel_: function(label, indent, dataElement, suffix) {
256 var row = document.createElement('div');
257
258 var indentSpan = document.createElement('span');
259 indentSpan.style.whiteSpace = 'pre';
260 for (var i = 0; i < indent; i++)
261 indentSpan.textContent += ' ';
262 row.appendChild(indentSpan);
263
264 var labelSpan = document.createElement('span');
265 labelSpan.textContent = label;
266 row.appendChild(labelSpan);
267
268 row.appendChild(dataElement);
269 var suffixSpan = document.createElement('span');
270 suffixSpan.textContent = suffix;
271 row.appendChild(suffixSpan);
272
273 row.dataElement = dataElement;
Chris Craikbeca7ae2015-04-07 13:29:55 -0700274 this.$.content.appendChild(row);
Chris Craikb122baf2015-03-05 13:58:42 -0800275 },
276
277 appendSimpleText_: function(label, indent, text, suffix) {
278 var el = this.ownerDocument.createElement('span');
279 el.textContent = text;
280 this.appendElementWithLabel_(label, indent, el, suffix);
281 return el;
282 }
283 });
284 </script>
285</polymer-element>
286
287<polymer-element name="tv-c-analysis-generic-object-view-with-label"
288 is="HTMLUnknownElement">
289 <template>
290 <style>
291 :host {
292 display: block;
293 }
294 </style>
295 </template>
296
297 <script>
298 'use strict';
299
300 Polymer({
301 ready: function() {
302 this.labelEl_ = document.createElement('div');
303 this.genericObjectView_ =
304 document.createElement('tv-c-analysis-generic-object-view');
305 this.shadowRoot.appendChild(this.labelEl_);
306 this.shadowRoot.appendChild(this.genericObjectView_);
307 },
308
309 get label() {
310 return this.labelEl_.textContent;
311 },
312
313 set label(label) {
314 this.labelEl_.textContent = label;
315 },
316
317 get object() {
318 return this.genericObjectView_.object;
319 },
320
321 set object(object) {
322 this.genericObjectView_.object = object;
323 }
324 });
325 </script>
326</polymer-element>