Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chrome / test / data / third_party / spaceport / js / util / report.js
blob06977868fbef6c123093537eccacfaacd3c62186
1 define([ ], function () {
2 function serializeCsvCell(text) {
3 if (typeof text === 'undefined' || text === null) {
4 return serializeCsvCell('N/A');
5 } else if (/[",]/.test(text)) {
6 return '"' + text.replace(/"/g, '""') + '"';
7 } else {
8 return text;
12 function th(text) {
13 var th = document.createElement('th');
14 th.textContent = text;
15 return th;
18 function td(text) {
19 var td = document.createElement('td');
20 td.textContent = text;
21 return td;
24 function tr(cells) {
25 var tr = document.createElement('tr');
26 cells.forEach(function (cell) {
27 tr.appendChild(cell);
28 });
29 return tr;
32 var report = {
33 makeTableLayout: function tabulate(sourceTable) {
34 function levelKeys(level) {
35 return Object.keys(level).filter(function (key) {
36 return !/^\$/.test(key);
37 });
40 var levels = [ ];
41 var c = sourceTable;
42 while (c) {
43 levels.push(c);
44 c = c.$children;
47 // Array name means vertical; string name means horizontal
48 var columns = [ ];
49 levels.forEach(function (level, i) {
50 switch (level.$mode) {
51 default:
52 case 'vertical':
53 columns.push({
54 name: levelKeys(level),
55 rowSpan: null,
56 title: level.$title,
57 level: level
58 });
60 if (i === levels.length - 1) {
61 // If the last level is vertical, insert a new column
62 // just for the data.
63 columns.push({
64 name: null,
65 rowSpan: 1,
66 title: '(null)',
67 level: null
68 });
71 break;
73 case 'horizontal':
74 levelKeys(level).forEach(function (name) {
75 columns.push({
76 name: name,
77 rowSpan: null,
78 title: level[name],
79 level: level
80 });
81 });
82 break;
84 });
86 var verticalSizes = [ ];
87 var currentSize = 1;
88 levels.reverse();
89 levels.forEach(function (level) {
90 verticalSizes.unshift(currentSize);
92 switch (level.$mode) {
93 default:
94 case 'vertical':
95 currentSize *= levelKeys(level).length;
96 break;
98 case 'horizontal':
99 levelKeys(level).slice(1).forEach(function () {
100 verticalSizes.unshift(currentSize);
102 break;
105 levels.reverse();
107 columns.forEach(function (column, i) {
108 column.rowSpan = verticalSizes[i];
111 return {
112 columns: columns,
113 rowCount: currentSize
117 tableTemplate: function table(rootPath, layout) {
118 var table = document.createElement('table');
119 var header = document.createElement('thead');
120 table.appendChild(header);
122 header.appendChild(tr(layout.columns.map(function (column) {
123 return th(column.title);
124 })));
126 var body = document.createElement('tbody');
127 table.appendChild(body);
129 var rowIndex, columnIndex;
130 for (rowIndex = 0; rowIndex < layout.rowCount; ++rowIndex) {
131 var path = [ rootPath ];
132 var columnEls = [ ];
133 for (columnIndex = 0; columnIndex < layout.columns.length; ++columnIndex) {
134 var column = layout.columns[columnIndex];
136 var cell;
137 var name = column.name;
138 if (Array.isArray(name)) {
139 name = name[Math.floor(rowIndex / column.rowSpan) % name.length];
140 cell = th(column.level[name]);
141 path.push(name);
142 } else {
143 cell = td('');
144 cell.setAttribute('data-property', name);
147 if (column.level.$errors) {
148 var errorMessageEl = document.createElement('span');
149 errorMessageEl.className = 'error-message';
150 cell.appendChild(errorMessageEl);
153 if (rowIndex % column.rowSpan === 0) {
154 cell.rowSpan = column.rowSpan;
155 columnEls.push(cell);
159 var rowEl = tr(columnEls);
160 rowEl.id = path.join('-');
161 rowEl.className = 'test';
162 body.appendChild(rowEl);
165 return table;
168 csvByTable: function csvByTable(records) {
169 return records.map(function (record) {
170 return record.map(serializeCsvCell).join(',');
171 }).join('\n');
174 csvByObject: function csvByObject(object) {
175 var records = [ ];
177 function write(object, stack) {
178 if (object && typeof object.valueOf === 'function') {
179 object = object.valueOf();
182 if (object === null) {
183 return;
186 switch (typeof object) {
187 case 'object':
188 Object.keys(object).forEach(function (key) {
189 write(object[key], stack.concat([ key ]));
191 break;
193 case 'string':
194 case 'number':
195 case 'boolean':
196 records.push(stack.concat([ String(object) ]));
197 break;
199 default:
200 throw new TypeError('Cannot serialize object ' + object);
204 write(object, [ ]);
205 return report.csvByTable(records);
208 csvByLayout: function csv(data, layout, prefix) {
209 function getValue(object, path) {
210 path = path.slice();
211 while (object && path.length) {
212 object = object[path.shift()];
214 return object;
217 var records = [ ];
219 var rowIndex, columnIndex;
220 for (rowIndex = 0; rowIndex < layout.rowCount; ++rowIndex) {
221 var path = [ ];
222 var record = prefix.slice(); // PREFIX IS A HACK FIXME
223 records.push(record);
224 for (columnIndex = 0; columnIndex < layout.columns.length; ++columnIndex) {
225 var column = layout.columns[columnIndex];
227 var cell;
228 var name = column.name;
229 if (Array.isArray(name)) {
230 name = name[Math.floor(rowIndex / column.rowSpan) % name.length];
231 cell = column.level[name];
232 path.push(name);
233 } else if (name === null) {
234 cell = getValue(data, path);
235 } else {
236 cell = getValue(data, path.concat([ name ]));
239 record.push(cell);
243 return report.csvByTable(records);
247 return report;