• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4
5var localStrings;
6
7// Contents of lines that act as delimiters for multi-line values.
8var DELIM_START = '---------- START ----------';
9var DELIM_END = '---------- END ----------';
10
11// Limit file size to 10 MiB to prevent hanging on accidental upload.
12var MAX_FILE_SIZE = 10485760;
13
14function getValueDivForButton(button) {
15  return $(button.id.substr(0, button.id.length - 4));
16}
17
18function getButtonForValueDiv(valueDiv) {
19  return $(valueDiv.id + '-btn');
20}
21
22function handleDragOver(e) {
23  e.dataTransfer.dropEffect = 'copy';
24  e.preventDefault();
25}
26
27function handleDrop(e) {
28  var file = e.dataTransfer.files[0];
29  if (file) {
30    e.preventDefault();
31    importLog(file);
32  }
33}
34
35function showError(fileName) {
36  $('status').textContent = localStrings.getStringF('parseError', fileName);
37}
38
39/**
40 * Toggles whether an item is collapsed or expanded.
41 */
42function changeCollapsedStatus() {
43  var valueDiv = getValueDivForButton(this);
44  if (valueDiv.parentNode.className == 'number-collapsed') {
45    valueDiv.parentNode.className = 'number-expanded';
46    this.textContent = localStrings.getString('collapseBtn');
47  } else {
48    valueDiv.parentNode.className = 'number-collapsed';
49    this.textContent = localStrings.getString('expandBtn');
50  }
51}
52
53/**
54 * Collapses all log items.
55 */
56function collapseAll() {
57  var valueDivs = document.getElementsByClassName('stat-value');
58  for (var i = 0; i < valueDivs.length; i++) {
59    var button = getButtonForValueDiv(valueDivs[i]);
60    if (button && button.className != 'button-hidden') {
61      button.textContent = localStrings.getString('expandBtn');
62      valueDivs[i].parentNode.className = 'number-collapsed';
63    }
64  }
65}
66
67/**
68 * Expands all log items.
69 */
70function expandAll() {
71  var valueDivs = document.getElementsByClassName('stat-value');
72  for (var i = 0; i < valueDivs.length; i++) {
73    var button = getButtonForValueDiv(valueDivs[i]);
74    if (button && button.className != 'button-hidden') {
75      button.textContent = localStrings.getString('collapseBtn');
76      valueDivs[i].parentNode.className = 'number-expanded';
77    }
78  }
79}
80
81/**
82 * Collapse only those log items with multi-line values.
83 */
84function collapseMultiLineStrings() {
85  var valueDivs = document.getElementsByClassName('stat-value');
86  var nameDivs = document.getElementsByClassName('stat-name');
87  for (var i = 0; i < valueDivs.length; i++) {
88    var button = getButtonForValueDiv(valueDivs[i]);
89    button.onclick = changeCollapsedStatus;
90    if (valueDivs[i].scrollHeight > (nameDivs[i].scrollHeight * 2)) {
91      button.className = '';
92      button.textContent = localStrings.getString('expandBtn');
93      valueDivs[i].parentNode.className = 'number-collapsed';
94    } else {
95      button.className = 'button-hidden';
96      valueDivs[i].parentNode.className = 'number';
97    }
98  }
99}
100
101/**
102 * Read in a log asynchronously, calling parseSystemLog if successful.
103 * @param {File} file The file to read.
104 */
105function importLog(file) {
106  if (file && file.size <= MAX_FILE_SIZE) {
107    var reader = new FileReader();
108    reader.onload = function() {
109      if (parseSystemLog(this.result)) {
110        // Reset table title and status
111        $('tableTitle').textContent =
112              localStrings.getStringF('logFileTableTitle', file.name);
113        $('status').textContent = '';
114      } else {
115        showError(file.name);
116      }
117    };
118    reader.readAsText(file);
119  } else if (file) {
120    showError(file.name);
121  }
122}
123
124/**
125 * Convert text-based log into list of name-value pairs.
126 * @param {string} text The raw text of a log.
127 * @return {boolean} True if the log was parsed successfully.
128 */
129function parseSystemLog(text) {
130  var details = [];
131  var lines = text.split('\n');
132  for (var i = 0, len = lines.length; i < len; i++) {
133    // Skip empty lines.
134    if (!lines[i])
135      continue;
136
137    var delimiter = lines[i].indexOf('=');
138    if (delimiter <= 0) {
139      if (i == lines.length - 1)
140         break;
141      // If '=' is missing here, format is wrong.
142      return false;
143    }
144
145    var name = lines[i].substring(0, delimiter);
146    var value = '';
147    // Set value if non-empty
148    if (lines[i].length > delimiter + 1)
149      value = lines[i].substring(delimiter + 1);
150
151    // Delimiters are based on kMultilineIndicatorString, kMultilineStartString,
152    // and kMultilineEndString in components/feedback/feedback_data.cc.
153    // If these change, we should check for both the old and new versions.
154    if (value == '<multiline>') {
155      // Skip start delimiter.
156      if (i == len - 1 ||
157          lines[++i].indexOf(DELIM_START) == -1)
158        return false;
159
160      ++i;
161      value = '';
162      // Append lines between start and end delimiters.
163      while (i < len && lines[i] != DELIM_END)
164        value += lines[i++] + '\n';
165
166      // Remove trailing newline.
167      if (value)
168        value = value.substr(0, value.length - 1);
169    }
170    details.push({'statName': name, 'statValue': value});
171  }
172
173  templateData['details'] = details;
174  i18nTemplate.process(document, templateData);
175  jstProcess(new JsEvalContext(templateData), $('t'));
176
177  collapseMultiLineStrings();
178  return true;
179}
180
181document.addEventListener('DOMContentLoaded', function() {
182  localStrings = new LocalStrings();
183
184  $('collapseAll').onclick = collapseAll;
185  $('expandAll').onclick = expandAll;
186
187  var tp = $('t');
188  tp.addEventListener('dragover', handleDragOver, false);
189  tp.addEventListener('drop', handleDrop, false);
190
191  collapseMultiLineStrings();
192});
193