Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2052)

Unified Diff: chrome/browser/resources/feedback/js/sys_info.js

Issue 2403503003: Optimize the table creation in the Sys Info page of the feedback app (Closed)
Patch Set: Fix js styles for presubmit Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/resources/feedback/js/feedback.js ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
};
« no previous file with comments | « chrome/browser/resources/feedback/js/feedback.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698