Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / devtools / front_end / audits / AuditLauncherView.js
blobe67375dbaa0883380a7378518e6696dd124a0f4e
1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 /**
32 * @constructor
33 * @param {!WebInspector.AuditController} auditController
34 * @extends {WebInspector.VBox}
36 WebInspector.AuditLauncherView = function(auditController)
38 WebInspector.VBox.call(this);
39 this.setMinimumSize(100, 25);
41 this._auditController = auditController;
43 this._categoryIdPrefix = "audit-category-item-";
44 this._auditRunning = false;
46 this.element.classList.add("audit-launcher-view");
47 this.element.classList.add("panel-enabler-view");
49 this._contentElement = createElement("div");
50 this._contentElement.className = "audit-launcher-view-content";
51 this.element.appendChild(this._contentElement);
52 this._boundCategoryClickListener = this._categoryClicked.bind(this);
54 this._resetResourceCount();
56 this._sortedCategories = [];
58 this._headerElement = createElement("h1");
59 this._headerElement.className = "no-audits";
60 this._headerElement.textContent = WebInspector.UIString("No audits to run");
61 this._contentElement.appendChild(this._headerElement);
63 WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
64 WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
66 var defaultSelectedAuditCategory = {};
67 defaultSelectedAuditCategory[WebInspector.AuditLauncherView.AllCategoriesKey] = true;
68 this._selectedCategoriesSetting = WebInspector.settings.createSetting("selectedAuditCategories", defaultSelectedAuditCategory);
71 WebInspector.AuditLauncherView.AllCategoriesKey = "__AllCategories";
73 WebInspector.AuditLauncherView.prototype = {
74 _resetResourceCount: function()
76 this._loadedResources = 0;
77 this._totalResources = 0;
80 _onRequestStarted: function(event)
82 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
83 // Ignore long-living WebSockets for the sake of progress indicator, as we won't be waiting them anyway.
84 if (request.resourceType() === WebInspector.resourceTypes.WebSocket)
85 return;
86 ++this._totalResources;
87 this._updateResourceProgress();
90 _onRequestFinished: function(event)
92 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
93 // See resorceStarted for details.
94 if (request.resourceType() === WebInspector.resourceTypes.WebSocket)
95 return;
96 ++this._loadedResources;
97 this._updateResourceProgress();
101 * @param {!WebInspector.AuditCategory} category
103 addCategory: function(category)
105 if (!this._sortedCategories.length)
106 this._createLauncherUI();
108 var selectedCategories = this._selectedCategoriesSetting.get();
109 var categoryElement = this._createCategoryElement(category.displayName, category.id);
110 category._checkboxElement = categoryElement.checkboxElement;
111 if (this._selectAllCheckboxElement.checked || selectedCategories[category.displayName]) {
112 category._checkboxElement.checked = true;
113 ++this._currentCategoriesCount;
117 * @param {!WebInspector.AuditCategory} a
118 * @param {!WebInspector.AuditCategory} b
119 * @return {number}
121 function compareCategories(a, b)
123 var aTitle = a.displayName || "";
124 var bTitle = b.displayName || "";
125 return aTitle.localeCompare(bTitle);
127 var insertBefore = insertionIndexForObjectInListSortedByFunction(category, this._sortedCategories, compareCategories);
128 this._categoriesElement.insertBefore(categoryElement, this._categoriesElement.children[insertBefore]);
129 this._sortedCategories.splice(insertBefore, 0, category);
130 this._selectedCategoriesUpdated();
133 _startAudit: function()
135 this._auditRunning = true;
136 this._updateButton();
137 this._toggleUIComponents(this._auditRunning);
139 var catIds = [];
140 for (var category = 0; category < this._sortedCategories.length; ++category) {
141 if (this._sortedCategories[category]._checkboxElement.checked)
142 catIds.push(this._sortedCategories[category].id);
145 this._resetResourceCount();
146 this._progressIndicator = new WebInspector.ProgressIndicator();
147 this._buttonContainerElement.appendChild(this._progressIndicator.element);
148 this._displayResourceLoadingProgress = true;
151 * @this {WebInspector.AuditLauncherView}
153 function onAuditStarted()
155 this._displayResourceLoadingProgress = false;
157 this._auditController.initiateAudit(catIds, new WebInspector.ProgressProxy(this._progressIndicator, this._auditsDone.bind(this)), this._auditPresentStateElement.checked, onAuditStarted.bind(this));
160 _auditsDone: function()
162 this._displayResourceLoadingProgress = false;
163 delete this._progressIndicator;
164 this._launchButton.disabled = false;
165 this._auditRunning = false;
166 this._updateButton();
167 this._toggleUIComponents(this._auditRunning);
171 * @param {boolean} disable
173 _toggleUIComponents: function(disable)
175 this._selectAllCheckboxElement.disabled = disable;
176 for (var child = this._categoriesElement.firstChild; child; child = child.nextSibling)
177 child.checkboxElement.disabled = disable;
178 this._auditPresentStateElement.disabled = disable;
179 this._auditReloadedStateElement.disabled = disable;
182 _launchButtonClicked: function(event)
184 if (this._auditRunning) {
185 this._launchButton.disabled = true;
186 this._progressIndicator.cancel();
187 return;
189 this._startAudit();
192 _clearButtonClicked: function()
194 this._auditController.clearResults();
198 * @param {boolean} checkCategories
199 * @param {boolean=} userGesture
201 _selectAllClicked: function(checkCategories, userGesture)
203 var childNodes = this._categoriesElement.childNodes;
204 for (var i = 0, length = childNodes.length; i < length; ++i)
205 childNodes[i].checkboxElement.checked = checkCategories;
206 this._currentCategoriesCount = checkCategories ? this._sortedCategories.length : 0;
207 this._selectedCategoriesUpdated(userGesture);
210 _categoryClicked: function(event)
212 this._currentCategoriesCount += event.target.checked ? 1 : -1;
213 this._selectAllCheckboxElement.checked = this._currentCategoriesCount === this._sortedCategories.length;
214 this._selectedCategoriesUpdated(true);
218 * @param {string} title
219 * @param {string=} id
221 _createCategoryElement: function(title, id)
223 var labelElement = createCheckboxLabel(title);
224 if (id) {
225 labelElement.id = this._categoryIdPrefix + id;
226 labelElement.checkboxElement.addEventListener("click", this._boundCategoryClickListener, false);
228 labelElement.__displayName = title;
230 return labelElement;
233 _createLauncherUI: function()
235 this._headerElement = createElement("h1");
236 this._headerElement.textContent = WebInspector.UIString("Select audits to run");
238 this._contentElement.removeChildren();
239 this._contentElement.appendChild(this._headerElement);
242 * @param {!Event} event
243 * @this {WebInspector.AuditLauncherView}
245 function handleSelectAllClick(event)
247 this._selectAllClicked(event.target.checked, true);
249 var categoryElement = this._createCategoryElement(WebInspector.UIString("Select All"), "");
250 categoryElement.id = "audit-launcher-selectall";
251 this._selectAllCheckboxElement = categoryElement.checkboxElement;
252 this._selectAllCheckboxElement.checked = this._selectedCategoriesSetting.get()[WebInspector.AuditLauncherView.AllCategoriesKey];
253 this._selectAllCheckboxElement.addEventListener("click", handleSelectAllClick.bind(this), false);
254 this._contentElement.appendChild(categoryElement);
256 this._categoriesElement = this._contentElement.createChild("fieldset", "audit-categories-container");
257 this._currentCategoriesCount = 0;
259 this._contentElement.createChild("div", "flexible-space");
261 this._buttonContainerElement = this._contentElement.createChild("div", "button-container");
263 var radio = createRadioLabel("audit-mode", WebInspector.UIString("Audit Present State"), true);
264 this._buttonContainerElement.appendChild(radio);
265 this._auditPresentStateElement = radio.radioElement;
267 radio = createRadioLabel("audit-mode", WebInspector.UIString("Reload Page and Audit on Load"));
268 this._buttonContainerElement.appendChild(radio);
269 this._auditReloadedStateElement = radio.radioElement;
271 this._launchButton = createTextButton(WebInspector.UIString("Run"), this._launchButtonClicked.bind(this));
272 this._buttonContainerElement.appendChild(this._launchButton);
274 this._clearButton = createTextButton(WebInspector.UIString("Clear"), this._clearButtonClicked.bind(this));
275 this._buttonContainerElement.appendChild(this._clearButton);
277 this._selectAllClicked(this._selectAllCheckboxElement.checked);
280 _updateResourceProgress: function()
282 if (this._displayResourceLoadingProgress)
283 this._progressIndicator.setTitle(WebInspector.UIString("Loading (%d of %d)", this._loadedResources, this._totalResources));
287 * @param {boolean=} userGesture
289 _selectedCategoriesUpdated: function(userGesture)
291 // Save present categories only upon user gesture to clean up junk from past versions and removed extensions.
292 // Do not remove old categories if not handling a user gesture, as there's chance categories will be added
293 // later during start-up.
294 var selectedCategories = userGesture ? {} : this._selectedCategoriesSetting.get();
295 var childNodes = this._categoriesElement.childNodes;
296 for (var i = 0, length = childNodes.length; i < length; ++i)
297 selectedCategories[childNodes[i].__displayName] = childNodes[i].checkboxElement.checked;
298 selectedCategories[WebInspector.AuditLauncherView.AllCategoriesKey] = this._selectAllCheckboxElement.checked;
299 this._selectedCategoriesSetting.set(selectedCategories);
300 this._updateButton();
303 _updateButton: function()
305 this._launchButton.textContent = this._auditRunning ? WebInspector.UIString("Stop") : WebInspector.UIString("Run");
306 this._launchButton.disabled = !this._currentCategoriesCount;
309 __proto__: WebInspector.VBox.prototype