1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Inherit the prototype methods from one constructor into another. 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochfunction inherits(childCtor, parentCtor) { 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch function tempCtor() {}; 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tempCtor.prototype = parentCtor.prototype; 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch childCtor.superClass_ = parentCtor.prototype; 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch childCtor.prototype = new tempCtor(); 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch childCtor.prototype.constructor = childCtor; 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Sets the width (in pixels) on a DOM node. 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochfunction setNodeWidth(node, widthPx) { 20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick node.style.width = widthPx.toFixed(0) + 'px'; 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Sets the height (in pixels) on a DOM node. 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochfunction setNodeHeight(node, heightPx) { 27731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick node.style.height = heightPx.toFixed(0) + 'px'; 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Sets the position and size of a DOM node (in pixels). 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochfunction setNodePosition(node, leftPx, topPx, widthPx, heightPx) { 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick node.style.left = leftPx.toFixed(0) + 'px'; 35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick node.style.top = topPx.toFixed(0) + 'px'; 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setNodeWidth(node, widthPx); 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch setNodeHeight(node, heightPx); 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Sets the visibility for a DOM node. 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochfunction setNodeDisplay(node, isVisible) { 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node.style.display = isVisible ? '' : 'none'; 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Adds a node to |parentNode|, of type |tagName|. 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochfunction addNode(parentNode, tagName) { 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var elem = parentNode.ownerDocument.createElement(tagName); 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parentNode.appendChild(elem); 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return elem; 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * Adds |text| to node |parentNode|. 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochfunction addTextNode(parentNode, text) { 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var textNode = parentNode.ownerDocument.createTextNode(text); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parentNode.appendChild(textNode); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return textNode; 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * Adds a node to |parentNode|, of type |tagName|. Then adds 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * |text| to the new node. 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick */ 693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickfunction addNodeWithText(parentNode, tagName, text) { 703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var elem = parentNode.ownerDocument.createElement(tagName); 713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick parentNode.appendChild(elem); 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick addTextNode(elem, text); 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return elem; 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick/** 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Adds or removes a CSS class to |node|. 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochfunction changeClassName(node, classNameToAddOrRemove, isAdd) { 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Multiple classes can be separated by spaces. 81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick var currentNames = node.className.split(' '); 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (isAdd) { 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!(classNameToAddOrRemove in currentNames)) { 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch currentNames.push(classNameToAddOrRemove); 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (var i = 0; i < currentNames.length; ++i) { 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (currentNames[i] == classNameToAddOrRemove) { 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch currentNames.splice(i, 1); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick node.className = currentNames.join(' '); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochfunction getKeyWithValue(map, value) { 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (key in map) { 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (map[key] == value) 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return key; 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return '?'; 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * Looks up |key| in |map|, and returns the resulting entry, if there is one. 1093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * Otherwise, returns |key|. Intended primarily for use with incomplete 1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * tables, and for reasonable behavior with system enumerations that may be 1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * extended in the future. 1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick */ 1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickfunction tryGetValueWithKey(map, key) { 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (key in map) 1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return map[key]; 1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return key; 1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick/** 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Builds a string by repeating |str| |count| times. 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochfunction makeRepeatedString(str, count) { 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var out = []; 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (var i = 0; i < count; ++i) 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.push(str); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return out.join(''); 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * TablePrinter is a helper to format a table as ascii art or an HTML table. 1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * 1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * Usage: call addRow() and addCell() repeatedly to specify the data. 1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * 1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * addHeaderCell() can optionally be called to specify header cells for a 1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * single header row. The header row appears at the top of an HTML formatted 1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * table, and uses thead and th tags. In ascii tables, the header is separated 1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * from the table body by a partial row of dashes. 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * setTitle() can optionally be used to set a title that is displayed before 1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * the header row. In HTML tables, it uses the title class and in ascii tables 1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * it's between two rows of dashes. 1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * 1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * Once all the fields have been input, call toText() to format it as text or 1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * toHTML() to format it as HTML. 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochfunction TablePrinter() { 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this.rows_ = []; 1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick this.hasHeaderRow_ = false; 1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick this.title_ = null; 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick/** 153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick * Links are only used in HTML tables. 154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick */ 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochfunction TablePrinterCell(value) { 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this.text = '' + value; 157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick this.link = null; 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this.alignRight = false; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this.allowOverflow = false; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Starts a new row. 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTablePrinter.prototype.addRow = function() { 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this.rows_.push([]); 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Adds a column to the current row, setting its value to cellText. 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * @returns {!TablePrinterCell} the cell that was added. 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTablePrinter.prototype.addCell = function(cellText) { 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var r = this.rows_[this.rows_.length - 1]; 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var cell = new TablePrinterCell(cellText); 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch r.push(cell); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return cell; 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTablePrinter.prototype.setTitle = function(title) { 1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick this.title_ = title; 1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick/** 1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * Adds a header row, if not already present, and adds a new column to it, 1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * setting its contents to |headerText|. 1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * 1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * @returns {!TablePrinterCell} the cell that was added. 1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick */ 1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTablePrinter.prototype.addHeaderCell = function(headerText) { 1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Insert empty new row at start of |rows_| if currently no header row. 1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!this.hasHeaderRow_) { 1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick this.rows_.splice(0, 0, []); 1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick this.hasHeaderRow_ = true; 1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var cell = new TablePrinterCell(headerText); 1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick this.rows_[0].push(cell); 1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return cell; 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Returns the maximum number of columns this table contains. 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTablePrinter.prototype.getNumColumns = function() { 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var numColumns = 0; 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (var i = 0; i < this.rows_.length; ++i) { 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch numColumns = Math.max(numColumns, this.rows_[i].length); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return numColumns; 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Returns the cell at position (rowIndex, columnIndex), or null if there is 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * no such cell. 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTablePrinter.prototype.getCell_ = function(rowIndex, columnIndex) { 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rowIndex >= this.rows_.length) 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return null; 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var row = this.rows_[rowIndex]; 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (columnIndex >= row.length) 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return null; 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return row[columnIndex]; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Returns a formatted text representation of the table data. 2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * |spacing| indicates number of extra spaces, if any, to add between 2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * columns. 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 2313345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTablePrinter.prototype.toText = function(spacing) { 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var numColumns = this.getNumColumns(); 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Figure out the maximum width of each column. 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var columnWidths = []; 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch columnWidths.length = numColumns; 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (var i = 0; i < numColumns; ++i) 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch columnWidths[i] = 0; 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // If header row is present, temporarily add a spacer row to |rows_|. 2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (this.hasHeaderRow_) { 2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var headerSpacerRow = []; 2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (var c = 0; c < numColumns; ++c) { 2443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var cell = this.getCell_(0, c); 2453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!cell) 2463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick continue; 2473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var spacerStr = makeRepeatedString('-', cell.text.length); 2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick headerSpacerRow.push(new TablePrinterCell(spacerStr)); 2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick this.rows_.splice(1, 0, headerSpacerRow); 2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var numRows = this.rows_.length; 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (var c = 0; c < numColumns; ++c) { 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (var r = 0; r < numRows; ++r) { 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var cell = this.getCell_(r, c); 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cell && !cell.allowOverflow) { 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch columnWidths[c] = Math.max(columnWidths[c], cell.text.length); 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var out = []; 2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Print title, if present. 2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (this.title_) { 2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var titleSpacerStr = makeRepeatedString('-', this.title_.length); 2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.push(titleSpacerStr); 2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.push('\n'); 2703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.push(this.title_); 2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.push('\n'); 2723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.push(titleSpacerStr); 2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.push('\n'); 2743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Print each row. 2773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var spacingStr = makeRepeatedString(' ', spacing); 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (var r = 0; r < numRows; ++r) { 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (var c = 0; c < numColumns; ++c) { 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var cell = this.getCell_(r, c); 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cell) { 2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Pad the cell with spaces to make it fit the maximum column width. 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var padding = columnWidths[c] - cell.text.length; 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var paddingStr = makeRepeatedString(' ', padding); 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cell.alignRight) { 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.push(paddingStr); 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.push(cell.text); 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.push(cell.text); 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.push(paddingStr); 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick out.push(spacingStr); 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out.push('\n'); 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Remove spacer row under the header row, if one was added. 3003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (this.hasHeaderRow_) 3013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick this.rows_.splice(1, 1); 3023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return out.join(''); 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick/** 3073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * Adds a new HTML table to the node |parent| using the specified style. 3083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick */ 3093345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTablePrinter.prototype.toHTML = function(parent, style) { 3103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var numRows = this.rows_.length; 3113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var numColumns = this.getNumColumns(); 3123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var table = addNode(parent, 'table'); 3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick table.setAttribute('class', style); 3153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var thead = addNode(table, 'thead'); 3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var tbody = addNode(table, 'tbody'); 3183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Add title, if needed. 3203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (this.title_) { 3213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var tableTitleRow = addNode(thead, 'tr'); 3223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var tableTitle = addNodeWithText(tableTitleRow, 'th', this.title_); 3233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick tableTitle.colSpan = numColumns; 3243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick changeClassName(tableTitle, 'title', true); 3253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Fill table body, adding header row first, if needed. 3283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (var r = 0; r < numRows; ++r) { 3293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var cellType; 3303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var row; 3313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (r == 0 && this.hasHeaderRow_) { 3323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick row = addNode(thead, 'tr'); 3333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick cellType = 'th'; 3343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 3353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick row = addNode(tbody, 'tr'); 3363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick cellType = 'td'; 3373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (var c = 0; c < numColumns; ++c) { 3393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var cell = this.getCell_(r, c); 3403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (cell) { 341731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick var tableCell = addNode(row, cellType, cell.text); 3423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (cell.alignRight) 3433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick tableCell.alignRight = true; 3443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // If allowing overflow on the rightmost cell of a row, 3453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // make the cell span the rest of the columns. Otherwise, 3463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // ignore the flag. 3473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (cell.allowOverflow && !this.getCell_(r, c + 1)) 3483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick tableCell.colSpan = numColumns - c; 349731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (cell.link) { 350731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick var linkNode = addNodeWithText(tableCell, 'a', cell.text); 351731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick linkNode.href = cell.link; 352731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 353731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick addTextNode(tableCell, cell.text); 354731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 3553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return table; 3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 3603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 361