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();