| OLD | NEW |
| (Empty) | |
| 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; |
| 9 } |
| 10 } |
| 11 |
| 12 function th(text) { |
| 13 var th = document.createElement('th'); |
| 14 th.textContent = text; |
| 15 return th; |
| 16 } |
| 17 |
| 18 function td(text) { |
| 19 var td = document.createElement('td'); |
| 20 td.textContent = text; |
| 21 return td; |
| 22 } |
| 23 |
| 24 function tr(cells) { |
| 25 var tr = document.createElement('tr'); |
| 26 cells.forEach(function (cell) { |
| 27 tr.appendChild(cell); |
| 28 }); |
| 29 return tr; |
| 30 } |
| 31 |
| 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 }); |
| 38 } |
| 39 |
| 40 var levels = [ ]; |
| 41 var c = sourceTable; |
| 42 while (c) { |
| 43 levels.push(c); |
| 44 c = c.$children; |
| 45 } |
| 46 |
| 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 }); |
| 59 |
| 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 }); |
| 69 } |
| 70 |
| 71 break; |
| 72 |
| 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; |
| 83 } |
| 84 }); |
| 85 |
| 86 var verticalSizes = [ ]; |
| 87 var currentSize = 1; |
| 88 levels.reverse(); |
| 89 levels.forEach(function (level) { |
| 90 verticalSizes.unshift(currentSize); |
| 91 |
| 92 switch (level.$mode) { |
| 93 default: |
| 94 case 'vertical': |
| 95 currentSize *= levelKeys(level).length; |
| 96 break; |
| 97 |
| 98 case 'horizontal': |
| 99 levelKeys(level).slice(1).forEach(function () { |
| 100 verticalSizes.unshift(currentSize); |
| 101 }); |
| 102 break; |
| 103 } |
| 104 }); |
| 105 levels.reverse(); |
| 106 |
| 107 columns.forEach(function (column, i) { |
| 108 column.rowSpan = verticalSizes[i]; |
| 109 }); |
| 110 |
| 111 return { |
| 112 columns: columns, |
| 113 rowCount: currentSize |
| 114 }; |
| 115 }, |
| 116 |
| 117 tableTemplate: function table(rootPath, layout) { |
| 118 var table = document.createElement('table'); |
| 119 var header = document.createElement('thead'); |
| 120 table.appendChild(header); |
| 121 |
| 122 header.appendChild(tr(layout.columns.map(function (column) { |
| 123 return th(column.title); |
| 124 }))); |
| 125 |
| 126 var body = document.createElement('tbody'); |
| 127 table.appendChild(body); |
| 128 |
| 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; ++col
umnIndex) { |
| 134 var column = layout.columns[columnIndex]; |
| 135 |
| 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); |
| 145 } |
| 146 |
| 147 if (column.level.$errors) { |
| 148 var errorMessageEl = document.createElement('span'); |
| 149 errorMessageEl.className = 'error-message'; |
| 150 cell.appendChild(errorMessageEl); |
| 151 } |
| 152 |
| 153 if (rowIndex % column.rowSpan === 0) { |
| 154 cell.rowSpan = column.rowSpan; |
| 155 columnEls.push(cell); |
| 156 } |
| 157 } |
| 158 |
| 159 var rowEl = tr(columnEls); |
| 160 rowEl.id = path.join('-'); |
| 161 rowEl.className = 'test'; |
| 162 body.appendChild(rowEl); |
| 163 } |
| 164 |
| 165 return table; |
| 166 }, |
| 167 |
| 168 csvByTable: function csvByTable(records) { |
| 169 return records.map(function (record) { |
| 170 return record.map(serializeCsvCell).join(','); |
| 171 }).join('\n'); |
| 172 }, |
| 173 |
| 174 csvByObject: function csvByObject(object) { |
| 175 var records = [ ]; |
| 176 |
| 177 function write(object, stack) { |
| 178 if (object && typeof object.valueOf === 'function') { |
| 179 object = object.valueOf(); |
| 180 } |
| 181 |
| 182 if (object === null) { |
| 183 return; |
| 184 } |
| 185 |
| 186 switch (typeof object) { |
| 187 case 'object': |
| 188 Object.keys(object).forEach(function (key) { |
| 189 write(object[key], stack.concat([ key ])); |
| 190 }); |
| 191 break; |
| 192 |
| 193 case 'string': |
| 194 case 'number': |
| 195 case 'boolean': |
| 196 records.push(stack.concat([ String(object) ])); |
| 197 break; |
| 198 |
| 199 default: |
| 200 throw new TypeError('Cannot serialize object ' + object); |
| 201 } |
| 202 } |
| 203 |
| 204 write(object, [ ]); |
| 205 return report.csvByTable(records); |
| 206 }, |
| 207 |
| 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()]; |
| 213 } |
| 214 return object; |
| 215 } |
| 216 |
| 217 var records = [ ]; |
| 218 |
| 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; ++col
umnIndex) { |
| 225 var column = layout.columns[columnIndex]; |
| 226 |
| 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 ])); |
| 237 } |
| 238 |
| 239 record.push(cell); |
| 240 } |
| 241 } |
| 242 |
| 243 return report.csvByTable(records); |
| 244 } |
| 245 }; |
| 246 |
| 247 return report; |
| 248 }); |
| OLD | NEW |