summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources/about_sys/about_sys.js
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/resources/about_sys/about_sys.js')
-rw-r--r--chrome/browser/resources/about_sys/about_sys.js186
1 files changed, 186 insertions, 0 deletions
diff --git a/chrome/browser/resources/about_sys/about_sys.js b/chrome/browser/resources/about_sys/about_sys.js
new file mode 100644
index 0000000..e9ecb4a
--- /dev/null
+++ b/chrome/browser/resources/about_sys/about_sys.js
@@ -0,0 +1,186 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var localStrings;
+
+// Contents of lines that act as delimiters for multi-line values.
+var DELIM_START = '---------- START ----------';
+var DELIM_END = '---------- END ----------';
+
+// Limit file size to 10 MiB to prevent hanging on accidental upload.
+var MAX_FILE_SIZE = 10485760;
+
+function getValueDivForButton(button) {
+ return $(button.id.substr(0, button.id.length - 4));
+}
+
+function getButtonForValueDiv(valueDiv) {
+ return $(valueDiv.id + '-btn');
+}
+
+function handleDragOver(e) {
+ e.dataTransfer.dropEffect = 'copy';
+ e.preventDefault();
+}
+
+function showError(fileName) {
+ $('status').textContent = localStrings.getStringF('parseError', fileName);
+}
+
+/**
+ * Toggles whether an item is collapsed or expanded.
+ */
+function changeCollapsedStatus() {
+ var valueDiv = getValueDivForButton(this);
+ if (valueDiv.parentNode.className == 'number-collapsed') {
+ valueDiv.parentNode.className = 'number-expanded';
+ this.textContent = localStrings.getString('collapseBtn');
+ } else {
+ valueDiv.parentNode.className = 'number-collapsed';
+ this.textContent = localStrings.getString('expandBtn');
+ }
+}
+
+/**
+ * Collapses all log items.
+ */
+function collapseAll() {
+ var valueDivs = document.getElementsByClassName('stat-value');
+ for (var i = 0; i < valueDivs.length; i++) {
+ var button = getButtonForValueDiv(valueDivs[i]);
+ if (button && button.className != 'button-hidden') {
+ button.textContent = localStrings.getString('expandBtn');
+ valueDivs[i].parentNode.className = 'number-collapsed';
+ }
+ }
+}
+
+/**
+ * Expands all log items.
+ */
+function expandAll() {
+ var valueDivs = document.getElementsByClassName('stat-value');
+ for (var i = 0; i < valueDivs.length; i++) {
+ var button = getButtonForValueDiv(valueDivs[i]);
+ if (button && button.className != 'button-hidden') {
+ button.textContent = localStrings.getString('collapseBtn');
+ valueDivs[i].parentNode.className = 'number-expanded';
+ }
+ }
+}
+
+/**
+ * Collapse only those log items with multi-line values.
+ */
+function collapseMultiLineStrings() {
+ var valueDivs = document.getElementsByClassName('stat-value');
+ var nameDivs = document.getElementsByClassName('stat-name');
+ for (var i = 0; i < valueDivs.length; i++) {
+ var button = getButtonForValueDiv(valueDivs[i]);
+ button.onclick = changeCollapsedStatus;
+ if (valueDivs[i].scrollHeight > (nameDivs[i].scrollHeight * 2)) {
+ button.className = '';
+ button.textContent = localStrings.getString('expandBtn');
+ valueDivs[i].parentNode.className = 'number-collapsed';
+ } else {
+ button.className = 'button-hidden';
+ valueDivs[i].parentNode.className = 'number';
+ }
+ }
+}
+
+/**
+ * Read in a log asynchronously, calling parseSystemLog if successful.
+ * @param {Event} e The drop event from dropping a file dragged onto the page.
+ */
+function importLog(e) {
+ var file = e.dataTransfer.files[0];
+ if (file && file.size <= MAX_FILE_SIZE) {
+ var reader = new FileReader();
+ reader.onload = function() {
+ if (parseSystemLog(this.result)) {
+ // Reset table title and status
+ $('tableTitle').textContent =
+ localStrings.getStringF('logFileTableTitle', file.name);
+ $('status').textContent = '';
+ } else {
+ showError(file.name);
+ }
+ };
+ reader.readAsText(file);
+ } else if (file) {
+ showError(file.name);
+ }
+ e.preventDefault();
+}
+
+/**
+ * Convert text-based log into list of name-value pairs.
+ * @param {string} text The raw text of a log.
+ * @return {boolean} True if the log was parsed successfully.
+ */
+function parseSystemLog(text) {
+ var details = [];
+ var lines = text.split('\n');
+ for (var i = 0, len = lines.length; i < len; i++) {
+ // Skip empty lines.
+ if (!lines[i])
+ continue;
+
+ var delimiter = lines[i].indexOf('=');
+ if (delimiter <= 0) {
+ if (i == lines.length - 1)
+ break;
+ // If '=' is missing here, format is wrong.
+ return false;
+ }
+
+ var name = lines[i].substring(0, delimiter);
+ var value = '';
+ // Set value if non-empty
+ if (lines[i].length > delimiter + 1)
+ value = lines[i].substring(delimiter + 1);
+
+ // Delimiters are based on kMultilineIndicatorString, kMultilineStartString,
+ // and kMultilineEndString in chrome/browser/feedback/feedback_data.cc.
+ // If these change, we should check for both the old and new versions.
+ if (value == '<multiline>') {
+ // Skip start delimiter.
+ if (i == len - 1 ||
+ lines[++i].indexOf(DELIM_START) == -1)
+ return false;
+
+ ++i;
+ value = '';
+ // Append lines between start and end delimiters.
+ while (i < len && lines[i] != DELIM_END)
+ value += lines[i++] + '\n';
+
+ // Remove trailing newline.
+ if (value)
+ value = value.substr(0, value.length - 1);
+ }
+ details.push({'statName': name, 'statValue': value});
+ }
+
+ templateData['details'] = details;
+ i18nTemplate.process(document, templateData);
+ jstProcess(new JsEvalContext(templateData), $('t'));
+
+ collapseMultiLineStrings();
+ return true;
+}
+
+document.addEventListener('DOMContentLoaded', function() {
+ localStrings = new LocalStrings();
+
+ $('collapseAll').onclick = collapseAll;
+ $('expandAll').onclick = expandAll;
+
+ var tp = $('t');
+ tp.addEventListener('dragover', handleDragOver, false);
+ tp.addEventListener('drop', importLog, false);
+
+ collapseMultiLineStrings();
+});