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
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
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.
33 * @extends {WebInspector.View}
35 WebInspector.AuditLauncherView = function(runnerCallback)
37 WebInspector.View.call(this);
38 this._runnerCallback = runnerCallback;
39 this._categoryIdPrefix = "audit-category-item-";
40 this._auditRunning = false;
42 this.element.addStyleClass("audit-launcher-view");
44 this._contentElement = document.createElement("div");
45 this._contentElement.className = "audit-launcher-view-content";
46 this.element.appendChild(this._contentElement);
47 this._boundCategoryClickListener = this._categoryClicked.bind(this);
49 this._resetResourceCount();
51 this._sortedCategories = [];
53 this._headerElement = document.createElement("h1");
54 this._headerElement.className = "no-audits";
55 this._headerElement.textContent = WebInspector.UIString("No audits to run");
56 this._contentElement.appendChild(this._headerElement);
58 WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceStarted, this._onResourceStarted, this);
59 WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceFinished, this._onResourceFinished, this);
62 WebInspector.AuditLauncherView.prototype = {
63 _resetResourceCount: function()
65 this._loadedResources = 0;
66 this._totalResources = 0;
69 _onResourceStarted: function(event)
71 var resource = event.data;
72 // Ignore long-living WebSockets for the sake of progress indicator, as we won't be waiting them anyway.
73 if (resource.type === WebInspector.Resource.Type.WebSocket)
75 ++this._totalResources;
76 this._updateResourceProgress();
79 _onResourceFinished: function(event)
81 var resource = event.data;
82 // See resorceStarted for details.
83 if (resource.type === WebInspector.Resource.Type.WebSocket)
85 ++this._loadedResources;
86 this._updateResourceProgress();
89 addCategory: function(category)
91 if (!this._sortedCategories.length)
92 this._createLauncherUI();
94 var categoryElement = this._createCategoryElement(category.displayName, category.id);
95 category._checkboxElement = categoryElement.firstChild;
96 if (this._selectAllCheckboxElement.checked) {
97 category._checkboxElement.checked = true;
98 ++this._currentCategoriesCount;
101 function compareCategories(a, b)
103 var aTitle = a.displayName || "";
104 var bTitle = b.displayName || "";
105 return aTitle.localeCompare(bTitle);
107 var insertBefore = insertionIndexForObjectInListSortedByFunction(category, this._sortedCategories, compareCategories);
108 this._categoriesElement.insertBefore(categoryElement, this._categoriesElement.children[insertBefore]);
109 this._sortedCategories.splice(insertBefore, 0, category);
110 this._updateButton();
113 _setAuditRunning: function(auditRunning)
115 if (this._auditRunning === auditRunning)
117 this._auditRunning = auditRunning;
118 this._updateButton();
119 this._updateResourceProgress();
122 _launchButtonClicked: function(event)
125 var childNodes = this._categoriesElement.childNodes;
126 for (var category = 0; category < this._sortedCategories.length; ++category) {
127 if (this._sortedCategories[category]._checkboxElement.checked)
128 catIds.push(this._sortedCategories[category].id);
131 this._setAuditRunning(true);
132 this._runnerCallback(catIds, this._auditPresentStateElement.checked, this._setAuditRunning.bind(this, false));
135 _selectAllClicked: function(checkCategories)
137 var childNodes = this._categoriesElement.childNodes;
138 for (var i = 0, length = childNodes.length; i < length; ++i)
139 childNodes[i].firstChild.checked = checkCategories;
140 this._currentCategoriesCount = checkCategories ? this._sortedCategories.length : 0;
141 this._updateButton();
144 _categoryClicked: function(event)
146 this._currentCategoriesCount += event.target.checked ? 1 : -1;
147 this._selectAllCheckboxElement.checked = this._currentCategoriesCount === this._sortedCategories.length;
148 this._updateButton();
151 _createCategoryElement: function(title, id)
153 var labelElement = document.createElement("label");
154 labelElement.id = this._categoryIdPrefix + id;
156 var element = document.createElement("input");
157 element.type = "checkbox";
159 element.addEventListener("click", this._boundCategoryClickListener, false);
160 labelElement.appendChild(element);
161 labelElement.appendChild(document.createTextNode(title));
166 _createLauncherUI: function()
168 this._headerElement = document.createElement("h1");
169 this._headerElement.textContent = WebInspector.UIString("Select audits to run");
171 for (var child = 0; child < this._contentElement.children.length; ++child)
172 this._contentElement.removeChild(this._contentElement.children[child]);
174 this._contentElement.appendChild(this._headerElement);
176 function handleSelectAllClick(event)
178 this._selectAllClicked(event.target.checked);
180 var categoryElement = this._createCategoryElement(WebInspector.UIString("Select All"), "");
181 categoryElement.id = "audit-launcher-selectall";
182 this._selectAllCheckboxElement = categoryElement.firstChild;
183 this._selectAllCheckboxElement.checked = true;
184 this._selectAllCheckboxElement.addEventListener("click", handleSelectAllClick.bind(this), false);
185 this._contentElement.appendChild(categoryElement);
187 this._categoriesElement = document.createElement("div");
188 this._categoriesElement.className = "audit-categories-container";
189 this._contentElement.appendChild(this._categoriesElement);
191 this._currentCategoriesCount = 0;
193 var flexibleSpaceElement = document.createElement("div");
194 flexibleSpaceElement.className = "flexible-space";
195 this._contentElement.appendChild(flexibleSpaceElement);
197 this._buttonContainerElement = document.createElement("div");
198 this._buttonContainerElement.className = "button-container";
200 var labelElement = document.createElement("label");
201 this._auditPresentStateElement = document.createElement("input");
202 this._auditPresentStateElement.name = "audit-mode";
203 this._auditPresentStateElement.type = "radio";
204 this._auditPresentStateElement.checked = true;
205 this._auditPresentStateLabelElement = document.createTextNode(WebInspector.UIString("Audit Present State"));
206 labelElement.appendChild(this._auditPresentStateElement);
207 labelElement.appendChild(this._auditPresentStateLabelElement);
208 this._buttonContainerElement.appendChild(labelElement);
210 labelElement = document.createElement("label");
211 this.auditReloadedStateElement = document.createElement("input");
212 this.auditReloadedStateElement.name = "audit-mode";
213 this.auditReloadedStateElement.type = "radio";
214 labelElement.appendChild(this.auditReloadedStateElement);
215 labelElement.appendChild(document.createTextNode("Reload Page and Audit on Load"));
216 this._buttonContainerElement.appendChild(labelElement);
218 this._launchButton = document.createElement("button");
219 this._launchButton.type = "button";
220 this._launchButton.textContent = WebInspector.UIString("Run");
221 this._launchButton.addEventListener("click", this._launchButtonClicked.bind(this), false);
222 this._buttonContainerElement.appendChild(this._launchButton);
224 this._resourceProgressContainer = document.createElement("span");
225 this._resourceProgressContainer.className = "resource-progress";
226 var resourceProgressImage = document.createElement("img");
227 this._resourceProgressContainer.appendChild(resourceProgressImage);
228 this._resourceProgressTextElement = document.createElement("span");
229 this._resourceProgressContainer.appendChild(this._resourceProgressTextElement);
230 this._buttonContainerElement.appendChild(this._resourceProgressContainer);
232 this._contentElement.appendChild(this._buttonContainerElement);
234 this._selectAllClicked(this._selectAllCheckboxElement.checked);
235 this._updateButton();
236 this._updateResourceProgress();
239 _updateResourceProgress: function()
241 if (!this._resourceProgressContainer)
244 if (!this._auditRunning) {
245 this._resetResourceCount();
246 this._resourceProgressContainer.addStyleClass("hidden");
248 this._resourceProgressContainer.removeStyleClass("hidden");
249 this._resourceProgressTextElement.textContent = WebInspector.UIString("Loading (%d of %d)", this._loadedResources, this._totalResources);
252 _updateButton: function()
254 this._launchButton.disabled = !this._currentCategoriesCount || this._auditRunning;
258 WebInspector.AuditLauncherView.prototype.__proto__ = WebInspector.View.prototype;