1/* 2 * Copyright (C) 2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 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. 17 * 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. 29 */ 30 31WebInspector.AuditLauncherView = function(categoriesById, runnerCallback) 32{ 33 WebInspector.View.call(this); 34 this._categoriesById = categoriesById; 35 this._runnerCallback = runnerCallback; 36 this._categoryIdPrefix = "audit-category-item-"; 37 this._auditRunning = false; 38 39 this.element.addStyleClass("audit-launcher-view"); 40 41 this._contentElement = document.createElement("div"); 42 this._contentElement.className = "audit-launcher-view-content"; 43 this.element.appendChild(this._contentElement); 44 45 function categorySortFunction(a, b) 46 { 47 var aTitle = a.displayName || ""; 48 var bTitle = b.displayName || ""; 49 return aTitle.localeCompare(bTitle); 50 } 51 var sortedCategories = []; 52 for (var id in this._categoriesById) 53 sortedCategories.push(this._categoriesById[id]); 54 sortedCategories.sort(categorySortFunction); 55 56 if (!sortedCategories.length) { 57 this._headerElement = document.createElement("h1"); 58 this._headerElement.className = "no-audits"; 59 this._headerElement.textContent = WebInspector.UIString("No audits to run"); 60 this._contentElement.appendChild(this._headerElement); 61 } else 62 this._createLauncherUI(sortedCategories); 63} 64 65WebInspector.AuditLauncherView.prototype = { 66 updateResourceTrackingState: function(isTracking) 67 { 68 if (!this._auditPresentStateLabelElement) 69 return; 70 if (isTracking) { 71 this._auditPresentStateLabelElement.nodeValue = WebInspector.UIString("Audit Present State"); 72 this._auditPresentStateElement.disabled = false; 73 this._auditPresentStateElement.parentElement.removeStyleClass("disabled"); 74 } else { 75 this._auditPresentStateLabelElement.nodeValue = WebInspector.UIString("Audit Present State (Resource Tracking must be enabled)"); 76 this._auditPresentStateElement.disabled = true; 77 this._auditPresentStateElement.parentElement.addStyleClass("disabled"); 78 this.auditReloadedStateElement.checked = true; 79 } 80 }, 81 82 _setAuditRunning: function(auditRunning) 83 { 84 if (this._auditRunning === auditRunning) 85 return; 86 this._auditRunning = auditRunning; 87 this._updateButton(); 88 }, 89 90 _launchButtonClicked: function(event) 91 { 92 var catIds = []; 93 var childNodes = this._categoriesElement.childNodes; 94 for (var id in this._categoriesById) { 95 if (this._categoriesById[id]._checkboxElement.checked) 96 catIds.push(id); 97 } 98 function profilingFinishedCallback() 99 { 100 this._setAuditRunning(false); 101 } 102 this._setAuditRunning(true); 103 this._runnerCallback(catIds, this._auditPresentStateElement.checked, profilingFinishedCallback.bind(this)); 104 }, 105 106 _selectAllClicked: function(checkCategories) 107 { 108 var childNodes = this._categoriesElement.childNodes; 109 for (var i = 0, length = childNodes.length; i < length; ++i) 110 childNodes[i].firstChild.checked = checkCategories; 111 this._currentCategoriesCount = checkCategories ? this._totalCategoriesCount : 0; 112 this._updateButton(); 113 }, 114 115 _categoryClicked: function(event) 116 { 117 this._currentCategoriesCount += event.target.checked ? 1 : -1; 118 this._selectAllCheckboxElement.checked = this._currentCategoriesCount === this._totalCategoriesCount; 119 this._updateButton(); 120 }, 121 122 _createCategoryElement: function(title, id) 123 { 124 var element; 125 var labelElement = document.createElement("label"); 126 labelElement.id = this._categoryIdPrefix + id; 127 128 element = document.createElement("input"); 129 element.type = "checkbox"; 130 labelElement.appendChild(element); 131 labelElement.appendChild(document.createTextNode(title)); 132 133 return labelElement; 134 }, 135 136 _createLauncherUI: function(sortedCategories) 137 { 138 this._headerElement = document.createElement("h1"); 139 this._headerElement.textContent = WebInspector.UIString("Select audits to run"); 140 this._contentElement.appendChild(this._headerElement); 141 142 function handleSelectAllClick(event) 143 { 144 this._selectAllClicked(event.target.checked); 145 } 146 var categoryElement = this._createCategoryElement(WebInspector.UIString("Select All"), ""); 147 categoryElement.id = "audit-launcher-selectall"; 148 this._selectAllCheckboxElement = categoryElement.firstChild; 149 this._selectAllCheckboxElement.checked = true; 150 this._selectAllCheckboxElement.addEventListener("click", handleSelectAllClick.bind(this), false); 151 this._contentElement.appendChild(categoryElement); 152 153 this._categoriesElement = document.createElement("div"); 154 this._categoriesElement.className = "audit-categories-container"; 155 this._contentElement.appendChild(this._categoriesElement); 156 157 var boundCategoryClickListener = this._categoryClicked.bind(this); 158 159 for (var i = 0; i < sortedCategories.length; ++i) { 160 categoryElement = this._createCategoryElement(sortedCategories[i].displayName, sortedCategories[i].id); 161 categoryElement.firstChild.addEventListener("click", boundCategoryClickListener, false); 162 sortedCategories[i]._checkboxElement = categoryElement.firstChild; 163 this._categoriesElement.appendChild(categoryElement); 164 } 165 166 this._totalCategoriesCount = this._categoriesElement.childNodes.length; 167 this._currentCategoriesCount = 0; 168 169 this._buttonContainerElement = document.createElement("div"); 170 this._buttonContainerElement.className = "button-container"; 171 172 var labelElement = document.createElement("label"); 173 this._auditPresentStateElement = document.createElement("input"); 174 this._auditPresentStateElement.name = "audit-mode"; 175 this._auditPresentStateElement.type = "radio"; 176 this._auditPresentStateElement.checked = true; 177 this._auditPresentStateLabelElement = document.createTextNode(""); 178 labelElement.appendChild(this._auditPresentStateElement); 179 labelElement.appendChild(this._auditPresentStateLabelElement); 180 this._buttonContainerElement.appendChild(labelElement); 181 182 labelElement = document.createElement("label"); 183 this.auditReloadedStateElement = document.createElement("input"); 184 this.auditReloadedStateElement.name = "audit-mode"; 185 this.auditReloadedStateElement.type = "radio"; 186 labelElement.appendChild(this.auditReloadedStateElement); 187 labelElement.appendChild(document.createTextNode("Reload Page and Audit on Load")); 188 this._buttonContainerElement.appendChild(labelElement); 189 190 this._launchButton = document.createElement("button"); 191 this._launchButton.setAttribute("type", "button"); 192 this._launchButton.addEventListener("click", this._launchButtonClicked.bind(this), false); 193 this._buttonContainerElement.appendChild(this._launchButton); 194 195 this._contentElement.appendChild(this._buttonContainerElement); 196 197 this._selectAllClicked(this._selectAllCheckboxElement.checked); 198 this.updateResourceTrackingState(); 199 this._updateButton(); 200 }, 201 202 _updateButton: function() 203 { 204 this._launchButton.disabled = !this._currentCategoriesCount || this._auditRunning; 205 if (this._auditRunning) 206 this._launchButton.textContent = WebInspector.UIString("Running..."); 207 else 208 this._launchButton.textContent = WebInspector.UIString("Run"); 209 }, 210 211 show: function(parentElement) 212 { 213 WebInspector.View.prototype.show.call(this, parentElement); 214 setTimeout(this.resize(), 0); 215 }, 216 217 resize: function() 218 { 219 if (this._categoriesElement) 220 this._categoriesElement.style.height = (this._buttonContainerElement.totalOffsetTop - this._categoriesElement.totalOffsetTop) + "px"; 221 } 222} 223 224WebInspector.AuditLauncherView.prototype.__proto__ = WebInspector.View.prototype; 225