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.
5 // Contents of lines that act as delimiters for multi-line values.
6 var DELIM_START = '---------- START ----------';
7 var DELIM_END = '---------- END ----------';
9 // Limit file size to 10 MiB to prevent hanging on accidental upload.
10 var MAX_FILE_SIZE = 10485760;
12 function getValueDivForButton(button) {
13 return $(button.id.substr(0, button.id.length - 4));
16 function getButtonForValueDiv(valueDiv) {
17 return $(valueDiv.id + '-btn');
20 function handleDragOver(e) {
21 e.dataTransfer.dropEffect = 'copy';
25 function handleDrop(e) {
26 var file = e.dataTransfer.files[0];
33 function showError(fileName) {
34 $('status').textContent = loadTimeData.getStringF('parseError', fileName);
38 * Toggles whether an item is collapsed or expanded.
40 function changeCollapsedStatus() {
41 var valueDiv = getValueDivForButton(this);
42 if (valueDiv.parentNode.className == 'number-collapsed') {
43 valueDiv.parentNode.className = 'number-expanded';
44 this.textContent = loadTimeData.getString('collapseBtn');
46 valueDiv.parentNode.className = 'number-collapsed';
47 this.textContent = loadTimeData.getString('expandBtn');
52 * Collapses all log items.
54 function collapseAll() {
55 var valueDivs = document.getElementsByClassName('stat-value');
56 for (var i = 0; i < valueDivs.length; i++) {
57 var button = getButtonForValueDiv(valueDivs[i]);
58 if (button && button.className != 'button-hidden') {
59 button.textContent = loadTimeData.getString('expandBtn');
60 valueDivs[i].parentNode.className = 'number-collapsed';
66 * Expands all log items.
68 function expandAll() {
69 var valueDivs = document.getElementsByClassName('stat-value');
70 for (var i = 0; i < valueDivs.length; i++) {
71 var button = getButtonForValueDiv(valueDivs[i]);
72 if (button && button.className != 'button-hidden') {
73 button.textContent = loadTimeData.getString('collapseBtn');
74 valueDivs[i].parentNode.className = 'number-expanded';
80 * Collapse only those log items with multi-line values.
82 function collapseMultiLineStrings() {
83 var valueDivs = document.getElementsByClassName('stat-value');
84 var nameDivs = document.getElementsByClassName('stat-name');
85 for (var i = 0; i < valueDivs.length; i++) {
86 var button = getButtonForValueDiv(valueDivs[i]);
87 button.onclick = changeCollapsedStatus;
88 if (valueDivs[i].scrollHeight > (nameDivs[i].scrollHeight * 2)) {
89 button.className = '';
90 button.textContent = loadTimeData.getString('expandBtn');
91 valueDivs[i].parentNode.className = 'number-collapsed';
93 button.className = 'button-hidden';
94 valueDivs[i].parentNode.className = 'number';
100 * Read in a log asynchronously, calling parseSystemLog if successful.
101 * @param {File} file The file to read.
103 function importLog(file) {
104 if (file && file.size <= MAX_FILE_SIZE) {
105 var reader = new FileReader();
106 reader.onload = function() {
107 if (parseSystemLog(this.result)) {
108 // Reset table title and status
109 $('tableTitle').textContent =
110 loadTimeData.getStringF('logFileTableTitle', file.name);
111 $('status').textContent = '';
113 showError(file.name);
116 reader.readAsText(file);
118 showError(file.name);
123 * Convert text-based log into list of name-value pairs.
124 * @param {string} text The raw text of a log.
125 * @return {boolean} True if the log was parsed successfully.
127 function parseSystemLog(text) {
129 var lines = text.split('\n');
130 for (var i = 0, len = lines.length; i < len; i++) {
135 var delimiter = lines[i].indexOf('=');
136 if (delimiter <= 0) {
137 if (i == lines.length - 1)
139 // If '=' is missing here, format is wrong.
143 var name = lines[i].substring(0, delimiter);
145 // Set value if non-empty
146 if (lines[i].length > delimiter + 1)
147 value = lines[i].substring(delimiter + 1);
149 // Delimiters are based on kMultilineIndicatorString, kMultilineStartString,
150 // and kMultilineEndString in components/feedback/feedback_data.cc.
151 // If these change, we should check for both the old and new versions.
152 if (value == '<multiline>') {
153 // Skip start delimiter.
155 lines[++i].indexOf(DELIM_START) == -1)
160 // Append lines between start and end delimiters.
161 while (i < len && lines[i] != DELIM_END)
162 value += lines[i++] + '\n';
164 // Remove trailing newline.
166 value = value.substr(0, value.length - 1);
168 details.push({'statName': name, 'statValue': value});
171 var templateData = {'details': details};
172 jstProcess(new JsEvalContext(templateData), $('t'));
174 collapseMultiLineStrings();
178 document.addEventListener('DOMContentLoaded', function() {
179 jstProcess(loadTimeData.createJsEvalContext(), $('t'));
181 $('collapseAll').onclick = collapseAll;
182 $('expandAll').onclick = expandAll;
185 tp.addEventListener('dragover', handleDragOver, false);
186 tp.addEventListener('drop', handleDrop, false);
188 collapseMultiLineStrings();