1 /* 2 * Copyright (C) 2011 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 31 /** 32 * @constructor 33 * @extends {WebInspector.VBox} 34 * @implements {WebInspector.TargetManager.Observer} 35 * @param {!WebInspector.ProfilesPanel} profilesPanel 36 */ 37 WebInspector.ProfileLauncherView = function(profilesPanel) 38 { 39 WebInspector.VBox.call(this); 40 41 this._panel = profilesPanel; 42 43 this.element.classList.add("profile-launcher-view"); 44 this.element.classList.add("panel-enabler-view"); 45 46 this._contentElement = this.element.createChild("div", "profile-launcher-view-content"); 47 this._innerContentElement = this._contentElement.createChild("div"); 48 var targetSpan = this._contentElement.createChild("span"); 49 var selectTargetText = targetSpan.createChild("span"); 50 selectTargetText.textContent = WebInspector.UIString("Target:"); 51 var targetsSelect = targetSpan.createChild("select", "chrome-select"); 52 new WebInspector.TargetsComboBoxController(targetsSelect, targetSpan); 53 this._controlButton = this._contentElement.createChild("button", "text-button control-profiling"); 54 this._controlButton.addEventListener("click", this._controlButtonClicked.bind(this), false); 55 this._recordButtonEnabled = true; 56 this._loadButton = this._contentElement.createChild("button", "text-button load-profile"); 57 this._loadButton.textContent = WebInspector.UIString("Load"); 58 this._loadButton.addEventListener("click", this._loadButtonClicked.bind(this), false); 59 WebInspector.targetManager.observeTargets(this); 60 } 61 62 WebInspector.ProfileLauncherView.prototype = { 63 /** 64 * @param {!WebInspector.Target} target 65 */ 66 targetAdded: function(target) 67 { 68 this._updateLoadButtonLayout(); 69 }, 70 71 /** 72 * @param {!WebInspector.Target} target 73 */ 74 targetRemoved: function(target) 75 { 76 this._updateLoadButtonLayout(); 77 }, 78 79 _updateLoadButtonLayout: function() 80 { 81 this._loadButton.classList.toggle("multi-target", WebInspector.targetManager.targets().length > 1); 82 }, 83 84 /** 85 * @param {!WebInspector.ProfileType} profileType 86 */ 87 addProfileType: function(profileType) 88 { 89 var descriptionElement = this._innerContentElement.createChild("h1"); 90 descriptionElement.textContent = profileType.description; 91 var decorationElement = profileType.decorationElement(); 92 if (decorationElement) 93 this._innerContentElement.appendChild(decorationElement); 94 this._isInstantProfile = profileType.isInstantProfile(); 95 this._isEnabled = profileType.isEnabled(); 96 this._profileTypeId = profileType.id; 97 }, 98 99 _controlButtonClicked: function() 100 { 101 this._panel.toggleRecordButton(); 102 }, 103 104 _loadButtonClicked: function() 105 { 106 this._panel.showLoadFromFileDialog(); 107 }, 108 109 _updateControls: function() 110 { 111 if (this._isEnabled && this._recordButtonEnabled) 112 this._controlButton.removeAttribute("disabled"); 113 else 114 this._controlButton.setAttribute("disabled", ""); 115 this._controlButton.title = this._recordButtonEnabled ? "" : WebInspector.anotherProfilerActiveLabel(); 116 if (this._isInstantProfile) { 117 this._controlButton.classList.remove("running"); 118 this._controlButton.textContent = WebInspector.UIString("Take Snapshot"); 119 } else if (this._isProfiling) { 120 this._controlButton.classList.add("running"); 121 this._controlButton.textContent = WebInspector.UIString("Stop"); 122 } else { 123 this._controlButton.classList.remove("running"); 124 this._controlButton.textContent = WebInspector.UIString("Start"); 125 } 126 }, 127 128 profileStarted: function() 129 { 130 this._isProfiling = true; 131 this._updateControls(); 132 }, 133 134 profileFinished: function() 135 { 136 this._isProfiling = false; 137 this._updateControls(); 138 }, 139 140 /** 141 * @param {!WebInspector.ProfileType} profileType 142 * @param {boolean} recordButtonEnabled 143 */ 144 updateProfileType: function(profileType, recordButtonEnabled) 145 { 146 this._isInstantProfile = profileType.isInstantProfile(); 147 this._recordButtonEnabled = recordButtonEnabled; 148 this._isEnabled = profileType.isEnabled(); 149 this._profileTypeId = profileType.id; 150 this._updateControls(); 151 }, 152 153 __proto__: WebInspector.VBox.prototype 154 } 155 156 157 /** 158 * @constructor 159 * @extends {WebInspector.ProfileLauncherView} 160 * @param {!WebInspector.ProfilesPanel} profilesPanel 161 */ 162 WebInspector.MultiProfileLauncherView = function(profilesPanel) 163 { 164 WebInspector.ProfileLauncherView.call(this, profilesPanel); 165 166 WebInspector.settings.selectedProfileType = WebInspector.settings.createSetting("selectedProfileType", "CPU"); 167 168 var header = this._innerContentElement.createChild("h1"); 169 header.textContent = WebInspector.UIString("Select profiling type"); 170 171 this._profileTypeSelectorForm = this._innerContentElement.createChild("form"); 172 173 this._innerContentElement.createChild("div", "flexible-space"); 174 175 this._typeIdToOptionElement = {}; 176 } 177 178 WebInspector.MultiProfileLauncherView.EventTypes = { 179 ProfileTypeSelected: "profile-type-selected" 180 } 181 182 WebInspector.MultiProfileLauncherView.prototype = { 183 /** 184 * @override 185 * @param {!WebInspector.ProfileType} profileType 186 */ 187 addProfileType: function(profileType) 188 { 189 var labelElement = this._profileTypeSelectorForm.createChild("label"); 190 labelElement.textContent = profileType.name; 191 var optionElement = document.createElement("input"); 192 labelElement.insertBefore(optionElement, labelElement.firstChild); 193 this._typeIdToOptionElement[profileType.id] = optionElement; 194 optionElement._profileType = profileType; 195 optionElement.type = "radio"; 196 optionElement.name = "profile-type"; 197 optionElement.style.hidden = true; 198 optionElement.addEventListener("change", this._profileTypeChanged.bind(this, profileType), false); 199 var descriptionElement = labelElement.createChild("p"); 200 descriptionElement.textContent = profileType.description; 201 var decorationElement = profileType.decorationElement(); 202 if (decorationElement) 203 labelElement.appendChild(decorationElement); 204 }, 205 206 restoreSelectedProfileType: function() 207 { 208 var typeId = WebInspector.settings.selectedProfileType.get(); 209 if (!(typeId in this._typeIdToOptionElement)) 210 typeId = Object.keys(this._typeIdToOptionElement)[0]; 211 this._typeIdToOptionElement[typeId].checked = true; 212 var type = this._typeIdToOptionElement[typeId]._profileType; 213 this.dispatchEventToListeners(WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected, type); 214 }, 215 216 _controlButtonClicked: function() 217 { 218 this._panel.toggleRecordButton(); 219 }, 220 221 _updateControls: function() 222 { 223 WebInspector.ProfileLauncherView.prototype._updateControls.call(this); 224 var items = this._profileTypeSelectorForm.elements; 225 for (var i = 0; i < items.length; ++i) { 226 if (items[i].type === "radio") 227 items[i].disabled = this._isProfiling; 228 } 229 }, 230 231 /** 232 * @param {!WebInspector.ProfileType} profileType 233 */ 234 _profileTypeChanged: function(profileType) 235 { 236 this.dispatchEventToListeners(WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected, profileType); 237 this._isInstantProfile = profileType.isInstantProfile(); 238 this._isEnabled = profileType.isEnabled(); 239 this._profileTypeId = profileType.id; 240 this._updateControls(); 241 WebInspector.settings.selectedProfileType.set(profileType.id); 242 }, 243 244 profileStarted: function() 245 { 246 this._isProfiling = true; 247 this._updateControls(); 248 }, 249 250 profileFinished: function() 251 { 252 this._isProfiling = false; 253 this._updateControls(); 254 }, 255 256 __proto__: WebInspector.ProfileLauncherView.prototype 257 } 258 259