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.
31 WebInspector.AuditLauncherView = function(runnerCallback)
33 WebInspector.View.call(this);
34 this._runnerCallback = runnerCallback;
35 this._categoryIdPrefix = "audit-category-item-";
36 this._auditRunning = false;
38 this.element.addStyleClass("audit-launcher-view");
40 this._contentElement = document.createElement("div");
41 this._contentElement.className = "audit-launcher-view-content";
42 this.element.appendChild(this._contentElement);
43 this._boundCategoryClickListener = this._categoryClicked.bind(this);
45 this._resetResourceCount();
47 this._sortedCategories = [];
49 this._headerElement = document.createElement("h1");
50 this._headerElement.className = "no-audits";
51 this._headerElement.textContent = WebInspector.UIString("No audits to run");
52 this._contentElement.appendChild(this._headerElement);
54 WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceStarted, this._onResourceStarted, this);
55 WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceFinished, this._onResourceFinished, this);
58 WebInspector.AuditLauncherView.prototype = {
59 _resetResourceCount: function()
61 this._loadedResources = 0;
62 this._totalResources = 0;
65 _onResourceStarted: function(event)
67 var resource = event.data;
68 // Ignore long-living WebSockets for the sake of progress indicator, as we won't be waiting them anyway.
69 if (resource.type === WebInspector.Resource.Type.WebSocket)
71 ++this._totalResources;
72 this._updateResourceProgress();
75 _onResourceFinished: function(event)
77 var resource = event.data;
78 // See resorceStarted for details.
79 if (resource.type === WebInspector.Resource.Type.WebSocket)
81 ++this._loadedResources;
82 this._updateResourceProgress();
85 addCategory: function(category)
87 if (!this._sortedCategories.length)
88 this._createLauncherUI();
90 var categoryElement = this._createCategoryElement(category.displayName, category.id);
91 category._checkboxElement = categoryElement.firstChild;
92 if (this._selectAllCheckboxElement.checked) {
93 category._checkboxElement.checked = true;
94 ++this._currentCategoriesCount;
97 function compareCategories(a, b)
99 var aTitle = a.displayName || "";
100 var bTitle = b.displayName || "";
101 return aTitle.localeCompare(bTitle);
103 var insertBefore = insertionIndexForObjectInListSortedByFunction(category, this._sortedCategories, compareCategories);
104 this._categoriesElement.insertBefore(categoryElement, this._categoriesElement.children[insertBefore]);
105 this._sortedCategories.splice(insertBefore, 0, category);
106 this._updateButton();
109 _setAuditRunning: function(auditRunning)
111 if (this._auditRunning === auditRunning)
113 this._auditRunning = auditRunning;
114 this._updateButton();
115 this._updateResourceProgress();
118 _launchButtonClicked: function(event)
121 var childNodes = this._categoriesElement.childNodes;
122 for (var category = 0; category < this._sortedCategories.length; ++category) {
123 if (this._sortedCategories[category]._checkboxElement.checked)
124 catIds.push(this._sortedCategories[category].id);
127 this._setAuditRunning(true);
128 this._runnerCallback(catIds, this._auditPresentStateElement.checked, this._setAuditRunning.bind(this, false));
131 _selectAllClicked: function(checkCategories)
133 var childNodes = this._categoriesElement.childNodes;
134 for (var i = 0, length = childNodes.length; i < length; ++i)
135 childNodes[i].firstChild.checked = checkCategories;
136 this._currentCategoriesCount = checkCategories ? this._sortedCategories.length : 0;
137 this._updateButton();
140 _categoryClicked: function(event)
142 this._currentCategoriesCount += event.target.checked ? 1 : -1;
143 this._selectAllCheckboxElement.checked = this._currentCategoriesCount === this._sortedCategories.length;
144 this._updateButton();
147 _createCategoryElement: function(title, id)
149 var labelElement = document.createElement("label");
150 labelElement.id = this._categoryIdPrefix + id;
152 var element = document.createElement("input");
153 element.type = "checkbox";
155 element.addEventListener("click", this._boundCategoryClickListener, false);
156 labelElement.appendChild(element);
157 labelElement.appendChild(document.createTextNode(title));
162 _createLauncherUI: function()
164 this._headerElement = document.createElement("h1");
165 this._headerElement.textContent = WebInspector.UIString("Select audits to run");
167 for (var child = 0; child < this._contentElement.children.length; ++child)
168 this._contentElement.removeChild(this._contentElement.children[child]);
170 this._contentElement.appendChild(this._headerElement);
172 function handleSelectAllClick(event)
174 this._selectAllClicked(event.target.checked);
176 var categoryElement = this._createCategoryElement(WebInspector.UIString("Select All"), "");
177 categoryElement.id = "audit-launcher-selectall";
178 this._selectAllCheckboxElement = categoryElement.firstChild;
179 this._selectAllCheckboxElement.checked = true;
180 this._selectAllCheckboxElement.addEventListener("click", handleSelectAllClick.bind(this), false);
181 this._contentElement.appendChild(categoryElement);
183 this._categoriesElement = document.createElement("div");
184 this._categoriesElement.className = "audit-categories-container";
185 this._contentElement.appendChild(this._categoriesElement);
187 this._currentCategoriesCount = 0;
189 var flexibleSpaceElement = document.createElement("div");
190 flexibleSpaceElement.className = "flexible-space";
191 this._contentElement.appendChild(flexibleSpaceElement);
193 this._buttonContainerElement = document.createElement("div");
194 this._buttonContainerElement.className = "button-container";
196 var labelElement = document.createElement("label");
197 this._auditPresentStateElement = document.createElement("input");
198 this._auditPresentStateElement.name = "audit-mode";
199 this._auditPresentStateElement.type = "radio";
200 this._auditPresentStateElement.checked = true;
201 this._auditPresentStateLabelElement = document.createTextNode(WebInspector.UIString("Audit Present State"));
202 labelElement.appendChild(this._auditPresentStateElement);
203 labelElement.appendChild(this._auditPresentStateLabelElement);
204 this._buttonContainerElement.appendChild(labelElement);
206 labelElement = document.createElement("label");
207 this.auditReloadedStateElement = document.createElement("input");
208 this.auditReloadedStateElement.name = "audit-mode";
209 this.auditReloadedStateElement.type = "radio";
210 labelElement.appendChild(this.auditReloadedStateElement);
211 labelElement.appendChild(document.createTextNode("Reload Page and Audit on Load"));
212 this._buttonContainerElement.appendChild(labelElement);
214 this._launchButton = document.createElement("button");
215 this._launchButton.type = "button";
216 this._launchButton.textContent = WebInspector.UIString("Run");
217 this._launchButton.addEventListener("click", this._launchButtonClicked.bind(this), false);
218 this._buttonContainerElement.appendChild(this._launchButton);
220 this._resourceProgressContainer = document.createElement("span");
221 this._resourceProgressContainer.className = "resource-progress";
222 var resourceProgressImage = document.createElement("img");
223 this._resourceProgressContainer.appendChild(resourceProgressImage);
224 this._resourceProgressTextElement = document.createElement("span");
225 this._resourceProgressContainer.appendChild(this._resourceProgressTextElement);
226 this._buttonContainerElement.appendChild(this._resourceProgressContainer);
228 this._contentElement.appendChild(this._buttonContainerElement);
230 this._selectAllClicked(this._selectAllCheckboxElement.checked);
231 this._updateButton();
232 this._updateResourceProgress();
235 _updateResourceProgress: function()
237 if (!this._resourceProgressContainer)
240 if (!this._auditRunning) {
241 this._resetResourceCount();
242 this._resourceProgressContainer.addStyleClass("hidden");
244 this._resourceProgressContainer.removeStyleClass("hidden");
245 this._resourceProgressTextElement.textContent = WebInspector.UIString("Loading (%d of %d)", this._loadedResources, this._totalResources);
248 _updateButton: function()
250 this._launchButton.disabled = !this._currentCategoriesCount || this._auditRunning;
254 WebInspector.AuditLauncherView.prototype.__proto__ = WebInspector.View.prototype;