1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 // Contents of lines that act as delimiters for multi-line values.
8 var DELIM_START = '---------- START ----------';
9 var DELIM_END = '---------- END ----------';
11 // Limit file size to 10 MiB to prevent hanging on accidental upload.
12 var MAX_FILE_SIZE = 10485760;
14 function getValueDivForButton(button) {
15 return $(button.id.substr(0, button.id.length - 4));
18 function getButtonForValueDiv(valueDiv) {
19 return $(valueDiv.id + '-btn');
22 function handleDragOver(e) {
23 e.dataTransfer.dropEffect = 'copy';
27 function showError(fileName) {
28 $('status').textContent = localStrings.getStringF('parseError', fileName);
32 * Toggles whether an item is collapsed or expanded.
34 function changeCollapsedStatus() {
35 var valueDiv = getValueDivForButton(this);
36 if (valueDiv.parentNode.className == 'number-collapsed') {
37 valueDiv.parentNode.className = 'number-expanded';
38 this.textContent = localStrings.getString('collapseBtn');
40 valueDiv.parentNode.className = 'number-collapsed';
41 this.textContent = localStrings.getString('expandBtn');
46 * Collapses all log items.
48 function collapseAll() {
49 var valueDivs = document.getElementsByClassName('stat-value');
50 for (var i = 0; i < valueDivs.length; i++) {
51 var button = getButtonForValueDiv(valueDivs[i]);
52 if (button && button.className != 'button-hidden') {
53 button.textContent = localStrings.getString('expandBtn');
54 valueDivs[i].parentNode.className = 'number-collapsed';
60 * Expands all log items.
62 function expandAll() {
63 var valueDivs = document.getElementsByClassName('stat-value');
64 for (var i = 0; i < valueDivs.length; i++) {
65 var button = getButtonForValueDiv(valueDivs[i]);
66 if (button && button.className != 'button-hidden') {
67 button.textContent = localStrings.getString('collapseBtn');
68 valueDivs[i].parentNode.className = 'number-expanded';
74 * Collapse only those log items with multi-line values.
76 function collapseMultiLineStrings() {
77 var valueDivs = document.getElementsByClassName('stat-value');
78 for (var i = 0; i < valueDivs.length; i++) {
79 var button = getButtonForValueDiv(valueDivs[i]);
80 button.onclick = changeCollapsedStatus;
81 if (valueDivs[i].textContent.split('\n').length > 1) {
82 button.className = '';
83 button.textContent = localStrings.getString('expandBtn');
84 valueDivs[i].parentNode.className = 'number-collapsed';
86 button.className = 'button-hidden';
87 valueDivs[i].parentNode.className = 'number';
93 * Read in a log asynchronously, calling parseSystemLog if successful.
94 * @param {Event} e The drop event from dropping a file dragged onto the page.
96 function importLog(e) {
97 var file = e.dataTransfer.files[0];
98 if (file && file.size <= MAX_FILE_SIZE) {
99 var reader = new FileReader();
100 reader.onload = function() {
101 if (parseSystemLog(this.result)) {
102 // Reset table title and status
103 $('tableTitle').textContent =
104 localStrings.getStringF('logFileTableTitle', file.name);
105 $('status').textContent = '';
107 showError(file.name);
110 reader.readAsText(file);
112 showError(file.name);
118 * Convert text-based log into list of name-value pairs.
119 * @param {string} text The raw text of a log.
120 * @return {boolean} True if the log was parsed successfully.
122 function parseSystemLog(text) {
124 var lines = text.split('\n');
125 for (var i = 0, len = lines.length; i < len; i++) {
130 var delimiter = lines[i].indexOf('=');
131 if (delimiter <= 0) {
132 if (i == lines.length - 1)
134 // If '=' is missing here, format is wrong.
138 var name = lines[i].substring(0, delimiter);
140 // Set value if non-empty
141 if (lines[i].length > delimiter + 1)
142 value = lines[i].substring(delimiter + 1);
144 // Delimiters are based on kMultilineIndicatorString, kMultilineStartString,
145 // and kMultilineEndString in chrome/browser/feedback/feedback_data.cc.
146 // If these change, we should check for both the old and new versions.
147 if (value == '<multiline>') {
148 // Skip start delimiter.
150 lines[++i].indexOf(DELIM_START) == -1)
155 // Append lines between start and end delimiters.
156 while (i < len && lines[i] != DELIM_END)
157 value += lines[i++] + '\n';
159 // Remove trailing newline.
161 value = value.substr(0, value.length - 1);
163 details.push({'statName': name, 'statValue': value});
166 templateData['details'] = details;
167 i18nTemplate.process(document, templateData);
168 jstProcess(new JsEvalContext(templateData), $('t'));
170 collapseMultiLineStrings();
174 document.addEventListener('DOMContentLoaded', function() {
175 localStrings = new LocalStrings();
177 $('collapseAll').onclick = collapseAll;
178 $('expandAll').onclick = expandAll;
181 tp.addEventListener('dragover', handleDragOver, false);
182 tp.addEventListener('drop', importLog, false);
184 collapseMultiLineStrings();