| Index: chrome/browser/resources/feedback/js/sys_info.js
|
| diff --git a/chrome/browser/resources/feedback/js/sys_info.js b/chrome/browser/resources/feedback/js/sys_info.js
|
| index fcbd37c9ed0cedc554bf657f7278c7cc7e5b824a..6fc7a09c39a7aae7ee198db918be4fa70ada9655 100644
|
| --- a/chrome/browser/resources/feedback/js/sys_info.js
|
| +++ b/chrome/browser/resources/feedback/js/sys_info.js
|
| @@ -8,6 +8,18 @@
|
| */
|
| var loadTimeData = null;
|
|
|
| +/**
|
| + * A queue of a sequence of closures that will incrementally build the sys info
|
| + * html table.
|
| + */
|
| +var tableCreationClosuresQueue = [];
|
| +
|
| +/**
|
| + * The time used to post delayed tasks in MS. Currently set to be enough for two
|
| + * frames.
|
| + */
|
| +var STANDARD_DELAY_MS = 32;
|
| +
|
| function getValueDivForButton(button) {
|
| return $(button.id.substr(0, button.id.length - 4));
|
| }
|
| @@ -17,17 +29,47 @@ function getButtonForValueDiv(valueDiv) {
|
| }
|
|
|
| /**
|
| + * Expands the multiline table cell that contains the given valueDiv.
|
| + * @param {HTMLElement} button The expand button.
|
| + * @param {HTMLElement} valueDiv The div that contains the multiline logs.
|
| + * @param {number} delayFactor A value used for increasing the delay after which
|
| + * the cell will be expanded. Useful for expandAll() since it expands the
|
| + * multiline cells one after another with each expension done slightly after
|
| + * the previous one.
|
| + */
|
| +function expand(button, valueDiv, delayFactor) {
|
| + button.textContent = loadTimeData.getString('sysinfoPageCollapseBtn');
|
| + // Show the spinner container.
|
| + var valueCell = valueDiv.parentNode;
|
| + valueCell.firstChild.hidden = false;
|
| + // Expanding huge logs can take a very long time, so we do it after a delay
|
| + // to have a chance to render the spinner.
|
| + setTimeout(function() {
|
| + valueCell.className = 'number-expanded';
|
| + // Hide the spinner container.
|
| + valueCell.firstChild.hidden = true;
|
| + }, STANDARD_DELAY_MS * delayFactor);
|
| +}
|
| +
|
| +/**
|
| + * Collapses the multiline table cell that contains the given valueDiv.
|
| + * @param {HTMLElement} button The expand button.
|
| + * @param {HTMLElement} valueDiv The div that contains the multiline logs.
|
| + */
|
| +function collapse(button, valueDiv) {
|
| + button.textContent = loadTimeData.getString('sysinfoPageExpandBtn');
|
| + valueDiv.parentNode.className = 'number-collapsed';
|
| +}
|
| +
|
| +/**
|
| * 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 = loadTimeData.getString('sysinfoPageCollapseBtn');
|
| - } else {
|
| - valueDiv.parentNode.className = 'number-collapsed';
|
| - this.textContent = loadTimeData.getString('sysinfoPageExpandBtn');
|
| - }
|
| + if (valueDiv.parentNode.className == 'number-collapsed')
|
| + expand(this, valueDiv, 1);
|
| + else
|
| + collapse(this, valueDiv);
|
| }
|
|
|
| /**
|
| @@ -35,12 +77,12 @@ function changeCollapsedStatus() {
|
| */
|
| function collapseAll() {
|
| var valueDivs = document.getElementsByClassName('stat-value');
|
| - for (var i = 0; i < valueDivs.length; i++) {
|
| + for (var i = 0; i < valueDivs.length; ++i) {
|
| + if (valueDivs[i].parentNode.className != 'number-expanded')
|
| + continue;
|
| var button = getButtonForValueDiv(valueDivs[i]);
|
| - if (button && button.className != 'button-hidden') {
|
| - button.textContent = loadTimeData.getString('sysinfoPageExpandBtn');
|
| - valueDivs[i].parentNode.className = 'number-collapsed';
|
| - }
|
| + if (button)
|
| + collapse(button, valueDivs[i]);
|
| }
|
| }
|
|
|
| @@ -49,32 +91,12 @@ function collapseAll() {
|
| */
|
| 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 = loadTimeData.getString('sysinfoPageCollapseBtn');
|
| - 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++) {
|
| + for (var i = 0; i < valueDivs.length; ++i) {
|
| + if (valueDivs[i].parentNode.className != 'number-collapsed')
|
| + continue;
|
| var button = getButtonForValueDiv(valueDivs[i]);
|
| - button.onclick = changeCollapsedStatus;
|
| - if (valueDivs[i].scrollHeight > (nameDivs[i].scrollHeight * 2)) {
|
| - button.className = '';
|
| - button.textContent = loadTimeData.getString('sysinfoPageExpandBtn');
|
| - valueDivs[i].parentNode.className = 'number-collapsed';
|
| - } else {
|
| - button.className = 'button-hidden';
|
| - valueDivs[i].parentNode.className = 'number';
|
| - }
|
| + if (button)
|
| + expand(button, valueDivs[i], i + 1);
|
| }
|
| }
|
|
|
| @@ -88,62 +110,107 @@ function createNameCell(key) {
|
| return nameCell;
|
| }
|
|
|
| -function createButtonCell(key) {
|
| +function createButtonCell(key, isMultiLine) {
|
| var buttonCell = document.createElement('td');
|
| buttonCell.setAttribute('class', 'button-cell');
|
| - var button = document.createElement('button');
|
| - button.setAttribute('id', '' + key + '-value-btn');
|
| - buttonCell.appendChild(button);
|
| +
|
| + if (isMultiLine) {
|
| + var button = document.createElement('button');
|
| + button.setAttribute('id', '' + key + '-value-btn');
|
| + button.onclick = changeCollapsedStatus;
|
| + button.textContent = loadTimeData.getString('sysinfoPageExpandBtn');
|
| + buttonCell.appendChild(button);
|
| + }
|
| +
|
| return buttonCell;
|
| }
|
|
|
| -function createValueCell(key, value) {
|
| +function createValueCell(key, value, isMultiLine) {
|
| var valueCell = document.createElement('td');
|
| var valueDiv = document.createElement('div');
|
| valueDiv.setAttribute('class', 'stat-value');
|
| valueDiv.setAttribute('id', '' + key + '-value');
|
| valueDiv.appendChild(document.createTextNode(value));
|
| +
|
| + if (isMultiLine) {
|
| + valueCell.className = 'number-collapsed';
|
| + var loadingContainer = $('spinner-container').cloneNode(true);
|
| + loadingContainer.setAttribute('id', '' + key + '-value-loading');
|
| + loadingContainer.hidden = true;
|
| + valueCell.appendChild(loadingContainer);
|
| + } else {
|
| + valueCell.className = 'number';
|
| + }
|
| +
|
| valueCell.appendChild(valueDiv);
|
| return valueCell;
|
| }
|
|
|
| function createTableRow(key, value) {
|
| var row = document.createElement('tr');
|
| +
|
| + // Avoid using element.scrollHeight as it's very slow. crbug.com/653968.
|
| + var isMultiLine = value.split('\n').length > 2 || value.length > 1000;
|
| +
|
| row.appendChild(createNameCell(key));
|
| - row.appendChild(createButtonCell(key));
|
| - row.appendChild(createValueCell(key, value));
|
| + row.appendChild(createButtonCell(key, isMultiLine));
|
| + row.appendChild(createValueCell(key, value, isMultiLine));
|
| +
|
| return row;
|
| }
|
|
|
| /**
|
| - * Builds the system information table row by row.
|
| - * @param {Element} table The DOM table element to which the newly created rows
|
| - * will be appended.
|
| - * @param {Object} systemInfo The system information that will be used to fill
|
| - * the table.
|
| + * Finalize the page after the content has been loaded.
|
| */
|
| -function createTable(table, systemInfo) {
|
| - for (var key in systemInfo) {
|
| - var item = systemInfo[key];
|
| - table.appendChild(createTableRow(item['key'], item['value']));
|
| +function finishPageLoading() {
|
| + $('collapseAllBtn').onclick = collapseAll;
|
| + $('expandAllBtn').onclick = expandAll;
|
| +
|
| + $('spinner-container').hidden = true;
|
| +}
|
| +
|
| +/**
|
| + * Pops a closure from the front of the queue and executes it.
|
| + */
|
| +function processQueue() {
|
| + var closure = tableCreationClosuresQueue.shift();
|
| + if (closure)
|
| + closure();
|
| +
|
| + if (tableCreationClosuresQueue.length > 0) {
|
| + // Post a task to process the next item in the queue.
|
| + setTimeout(processQueue, STANDARD_DELAY_MS);
|
| }
|
| }
|
|
|
| /**
|
| - * The callback which will be invoked by the parent window, when the system
|
| - * information is ready.
|
| + * Creates a closure that creates a table row for the given key and value.
|
| + * @param {string} key The name of the log.
|
| + * @param {string} value The contents of the log.
|
| + * @return {function():void} A closure that creates a row for the given log.
|
| + */
|
| +function createTableRowWrapper(key, value) {
|
| + return function() {
|
| + $('detailsTable').appendChild(createTableRow(key, value));
|
| + };
|
| +}
|
| +
|
| +/**
|
| + * Creates closures to build the system information table row by row
|
| + * incrementally.
|
| * @param {Object} systemInfo The system information that will be used to fill
|
| * the table.
|
| */
|
| -function onSysInfoReady(systemInfo) {
|
| - createTable($('detailsTable'), systemInfo);
|
| -
|
| - $('collapseAllBtn').onclick = collapseAll;
|
| - $('expandAllBtn').onclick = expandAll;
|
| +function createTable(systemInfo) {
|
| + for (var key in systemInfo) {
|
| + var item = systemInfo[key];
|
| + tableCreationClosuresQueue.push(
|
| + createTableRowWrapper(item['key'], item['value']));
|
| + }
|
|
|
| - collapseMultiLineStrings();
|
| + tableCreationClosuresQueue.push(finishPageLoading);
|
|
|
| - $('status').textContent = '';
|
| + processQueue();
|
| }
|
|
|
| /**
|
| @@ -152,5 +219,5 @@ function onSysInfoReady(systemInfo) {
|
| window.onload = function() {
|
| loadTimeData = getLoadTimeData();
|
| i18nTemplate.process(document, loadTimeData);
|
| - getFullSystemInfo(onSysInfoReady);
|
| + getFullSystemInfo(createTable);
|
| };
|
|
|