Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25
26 /** 25 /**
27 * @constructor 26 * @unrestricted
28 * @extends {WebInspector.Object}
29 * @param {string} id
30 * @param {string} name
31 * @suppressGlobalPropertiesCheck
32 */ 27 */
33 WebInspector.ProfileType = function(id, name) 28 WebInspector.ProfileType = class extends WebInspector.Object {
34 { 29 /**
35 WebInspector.Object.call(this); 30 * @param {string} id
31 * @param {string} name
32 * @suppressGlobalPropertiesCheck
33 */
34 constructor(id, name) {
35 super();
36 this._id = id; 36 this._id = id;
37 this._name = name; 37 this._name = name;
38 /** @type {!Array.<!WebInspector.ProfileHeader>} */ 38 /** @type {!Array.<!WebInspector.ProfileHeader>} */
39 this._profiles = []; 39 this._profiles = [];
40 /** @type {?WebInspector.ProfileHeader} */ 40 /** @type {?WebInspector.ProfileHeader} */
41 this._profileBeingRecorded = null; 41 this._profileBeingRecorded = null;
42 this._nextProfileUid = 1; 42 this._nextProfileUid = 1;
43 43
44 if (!window.opener) 44 if (!window.opener)
45 window.addEventListener("unload", this._clearTempStorage.bind(this), fal se); 45 window.addEventListener('unload', this._clearTempStorage.bind(this), false );
46 }
47
48 /**
49 * @return {string}
50 */
51 typeName() {
52 return '';
53 }
54
55 /**
56 * @return {number}
57 */
58 nextProfileUid() {
59 return this._nextProfileUid;
60 }
61
62 /**
63 * @return {boolean}
64 */
65 hasTemporaryView() {
66 return false;
67 }
68
69 /**
70 * @return {?string}
71 */
72 fileExtension() {
73 return null;
74 }
75
76 /**
77 * @return {!Array.<!WebInspector.ToolbarItem>}
78 */
79 toolbarItems() {
80 return [];
81 }
82
83 get buttonTooltip() {
84 return '';
85 }
86
87 get id() {
88 return this._id;
89 }
90
91 get treeItemTitle() {
92 return this._name;
93 }
94
95 get name() {
96 return this._name;
97 }
98
99 /**
100 * @return {boolean}
101 */
102 buttonClicked() {
103 return false;
104 }
105
106 get description() {
107 return '';
108 }
109
110 /**
111 * @return {boolean}
112 */
113 isInstantProfile() {
114 return false;
115 }
116
117 /**
118 * @return {boolean}
119 */
120 isEnabled() {
121 return true;
122 }
123
124 /**
125 * @return {!Array.<!WebInspector.ProfileHeader>}
126 */
127 getProfiles() {
128 /**
129 * @param {!WebInspector.ProfileHeader} profile
130 * @return {boolean}
131 * @this {WebInspector.ProfileType}
132 */
133 function isFinished(profile) {
134 return this._profileBeingRecorded !== profile;
135 }
136 return this._profiles.filter(isFinished.bind(this));
137 }
138
139 /**
140 * @return {?Element}
141 */
142 decorationElement() {
143 return null;
144 }
145
146 /**
147 * @param {number} uid
148 * @return {?WebInspector.ProfileHeader}
149 */
150 getProfile(uid) {
151 for (var i = 0; i < this._profiles.length; ++i) {
152 if (this._profiles[i].uid === uid)
153 return this._profiles[i];
154 }
155 return null;
156 }
157
158 /**
159 * @param {!File} file
160 */
161 loadFromFile(file) {
162 var name = file.name;
163 var fileExtension = this.fileExtension();
164 if (fileExtension && name.endsWith(fileExtension))
165 name = name.substr(0, name.length - fileExtension.length);
166 var profile = this.createProfileLoadedFromFile(name);
167 profile.setFromFile();
168 this.setProfileBeingRecorded(profile);
169 this.addProfile(profile);
170 profile.loadFromFile(file);
171 }
172
173 /**
174 * @param {string} title
175 * @return {!WebInspector.ProfileHeader}
176 */
177 createProfileLoadedFromFile(title) {
178 throw new Error('Needs implemented.');
179 }
180
181 /**
182 * @param {!WebInspector.ProfileHeader} profile
183 */
184 addProfile(profile) {
185 this._profiles.push(profile);
186 this.dispatchEventToListeners(WebInspector.ProfileType.Events.AddProfileHead er, profile);
187 }
188
189 /**
190 * @param {!WebInspector.ProfileHeader} profile
191 */
192 removeProfile(profile) {
193 var index = this._profiles.indexOf(profile);
194 if (index === -1)
195 return;
196 this._profiles.splice(index, 1);
197 this._disposeProfile(profile);
198 }
199
200 _clearTempStorage() {
201 for (var i = 0; i < this._profiles.length; ++i)
202 this._profiles[i].removeTempFile();
203 }
204
205 /**
206 * @return {?WebInspector.ProfileHeader}
207 */
208 profileBeingRecorded() {
209 return this._profileBeingRecorded;
210 }
211
212 /**
213 * @param {?WebInspector.ProfileHeader} profile
214 */
215 setProfileBeingRecorded(profile) {
216 this._profileBeingRecorded = profile;
217 }
218
219 profileBeingRecordedRemoved() {
220 }
221
222 _reset() {
223 var profiles = this._profiles.slice(0);
224 for (var i = 0; i < profiles.length; ++i)
225 this._disposeProfile(profiles[i]);
226 this._profiles = [];
227
228 this._nextProfileUid = 1;
229 }
230
231 /**
232 * @param {!WebInspector.ProfileHeader} profile
233 */
234 _disposeProfile(profile) {
235 this.dispatchEventToListeners(WebInspector.ProfileType.Events.RemoveProfileH eader, profile);
236 profile.dispose();
237 if (this._profileBeingRecorded === profile) {
238 this.profileBeingRecordedRemoved();
239 this.setProfileBeingRecorded(null);
240 }
241 }
46 }; 242 };
47 243
48 /** @enum {symbol} */ 244 /** @enum {symbol} */
49 WebInspector.ProfileType.Events = { 245 WebInspector.ProfileType.Events = {
50 AddProfileHeader: Symbol("add-profile-header"), 246 AddProfileHeader: Symbol('add-profile-header'),
51 ProfileComplete: Symbol("profile-complete"), 247 ProfileComplete: Symbol('profile-complete'),
52 RemoveProfileHeader: Symbol("remove-profile-header"), 248 RemoveProfileHeader: Symbol('remove-profile-header'),
53 ViewUpdated: Symbol("view-updated") 249 ViewUpdated: Symbol('view-updated')
54 };
55
56 WebInspector.ProfileType.prototype = {
57 /**
58 * @return {string}
59 */
60 typeName: function()
61 {
62 return "";
63 },
64
65 /**
66 * @return {number}
67 */
68 nextProfileUid: function()
69 {
70 return this._nextProfileUid;
71 },
72
73 /**
74 * @return {boolean}
75 */
76 hasTemporaryView: function()
77 {
78 return false;
79 },
80
81 /**
82 * @return {?string}
83 */
84 fileExtension: function()
85 {
86 return null;
87 },
88
89 /**
90 * @return {!Array.<!WebInspector.ToolbarItem>}
91 */
92 toolbarItems: function()
93 {
94 return [];
95 },
96
97 get buttonTooltip()
98 {
99 return "";
100 },
101
102 get id()
103 {
104 return this._id;
105 },
106
107 get treeItemTitle()
108 {
109 return this._name;
110 },
111
112 get name()
113 {
114 return this._name;
115 },
116
117 /**
118 * @return {boolean}
119 */
120 buttonClicked: function()
121 {
122 return false;
123 },
124
125 get description()
126 {
127 return "";
128 },
129
130 /**
131 * @return {boolean}
132 */
133 isInstantProfile: function()
134 {
135 return false;
136 },
137
138 /**
139 * @return {boolean}
140 */
141 isEnabled: function()
142 {
143 return true;
144 },
145
146 /**
147 * @return {!Array.<!WebInspector.ProfileHeader>}
148 */
149 getProfiles: function()
150 {
151 /**
152 * @param {!WebInspector.ProfileHeader} profile
153 * @return {boolean}
154 * @this {WebInspector.ProfileType}
155 */
156 function isFinished(profile)
157 {
158 return this._profileBeingRecorded !== profile;
159 }
160 return this._profiles.filter(isFinished.bind(this));
161 },
162
163 /**
164 * @return {?Element}
165 */
166 decorationElement: function()
167 {
168 return null;
169 },
170
171 /**
172 * @param {number} uid
173 * @return {?WebInspector.ProfileHeader}
174 */
175 getProfile: function(uid)
176 {
177 for (var i = 0; i < this._profiles.length; ++i) {
178 if (this._profiles[i].uid === uid)
179 return this._profiles[i];
180 }
181 return null;
182 },
183
184 /**
185 * @param {!File} file
186 */
187 loadFromFile: function(file)
188 {
189 var name = file.name;
190 var fileExtension = this.fileExtension();
191 if (fileExtension && name.endsWith(fileExtension))
192 name = name.substr(0, name.length - fileExtension.length);
193 var profile = this.createProfileLoadedFromFile(name);
194 profile.setFromFile();
195 this.setProfileBeingRecorded(profile);
196 this.addProfile(profile);
197 profile.loadFromFile(file);
198 },
199
200 /**
201 * @param {string} title
202 * @return {!WebInspector.ProfileHeader}
203 */
204 createProfileLoadedFromFile: function(title)
205 {
206 throw new Error("Needs implemented.");
207 },
208
209 /**
210 * @param {!WebInspector.ProfileHeader} profile
211 */
212 addProfile: function(profile)
213 {
214 this._profiles.push(profile);
215 this.dispatchEventToListeners(WebInspector.ProfileType.Events.AddProfile Header, profile);
216 },
217
218 /**
219 * @param {!WebInspector.ProfileHeader} profile
220 */
221 removeProfile: function(profile)
222 {
223 var index = this._profiles.indexOf(profile);
224 if (index === -1)
225 return;
226 this._profiles.splice(index, 1);
227 this._disposeProfile(profile);
228 },
229
230 _clearTempStorage: function()
231 {
232 for (var i = 0; i < this._profiles.length; ++i)
233 this._profiles[i].removeTempFile();
234 },
235
236 /**
237 * @return {?WebInspector.ProfileHeader}
238 */
239 profileBeingRecorded: function()
240 {
241 return this._profileBeingRecorded;
242 },
243
244 /**
245 * @param {?WebInspector.ProfileHeader} profile
246 */
247 setProfileBeingRecorded: function(profile)
248 {
249 this._profileBeingRecorded = profile;
250 },
251
252 profileBeingRecordedRemoved: function()
253 {
254 },
255
256 _reset: function()
257 {
258 var profiles = this._profiles.slice(0);
259 for (var i = 0; i < profiles.length; ++i)
260 this._disposeProfile(profiles[i]);
261 this._profiles = [];
262
263 this._nextProfileUid = 1;
264 },
265
266 /**
267 * @param {!WebInspector.ProfileHeader} profile
268 */
269 _disposeProfile: function(profile)
270 {
271 this.dispatchEventToListeners(WebInspector.ProfileType.Events.RemoveProf ileHeader, profile);
272 profile.dispose();
273 if (this._profileBeingRecorded === profile) {
274 this.profileBeingRecordedRemoved();
275 this.setProfileBeingRecorded(null);
276 }
277 },
278
279 __proto__: WebInspector.Object.prototype
280 }; 250 };
281 251
282 /** 252 /**
283 * @interface 253 * @interface
284 */ 254 */
285 WebInspector.ProfileType.DataDisplayDelegate = function() 255 WebInspector.ProfileType.DataDisplayDelegate = function() {};
286 {
287 };
288 256
289 WebInspector.ProfileType.DataDisplayDelegate.prototype = { 257 WebInspector.ProfileType.DataDisplayDelegate.prototype = {
290 /** 258 /**
291 * @param {?WebInspector.ProfileHeader} profile 259 * @param {?WebInspector.ProfileHeader} profile
292 * @return {?WebInspector.Widget} 260 * @return {?WebInspector.Widget}
293 */ 261 */
294 showProfile: function(profile) { }, 262 showProfile: function(profile) {},
295 263
296 /** 264 /**
297 * @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId 265 * @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId
298 * @param {string} perspectiveName 266 * @param {string} perspectiveName
299 */ 267 */
300 showObject: function(snapshotObjectId, perspectiveName) { } 268 showObject: function(snapshotObjectId, perspectiveName) {}
301 }; 269 };
302 270
303 /** 271 /**
304 * @constructor 272 * @unrestricted
305 * @extends {WebInspector.Object}
306 * @param {?WebInspector.Target} target
307 * @param {!WebInspector.ProfileType} profileType
308 * @param {string} title
309 */ 273 */
310 WebInspector.ProfileHeader = function(target, profileType, title) 274 WebInspector.ProfileHeader = class extends WebInspector.Object {
311 { 275 /**
276 * @param {?WebInspector.Target} target
277 * @param {!WebInspector.ProfileType} profileType
278 * @param {string} title
279 */
280 constructor(target, profileType, title) {
281 super();
312 this._target = target; 282 this._target = target;
313 this._profileType = profileType; 283 this._profileType = profileType;
314 this.title = title; 284 this.title = title;
315 this.uid = profileType._nextProfileUid++; 285 this.uid = profileType._nextProfileUid++;
316 this._fromFile = false; 286 this._fromFile = false;
287 }
288
289 /**
290 * @return {?WebInspector.Target}
291 */
292 target() {
293 return this._target;
294 }
295
296 /**
297 * @return {!WebInspector.ProfileType}
298 */
299 profileType() {
300 return this._profileType;
301 }
302
303 /**
304 * @param {?string} subtitle
305 * @param {boolean=} wait
306 */
307 updateStatus(subtitle, wait) {
308 this.dispatchEventToListeners(
309 WebInspector.ProfileHeader.Events.UpdateStatus, new WebInspector.Profile Header.StatusUpdate(subtitle, wait));
310 }
311
312 /**
313 * Must be implemented by subclasses.
314 * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
315 * @return {!WebInspector.ProfileSidebarTreeElement}
316 */
317 createSidebarTreeElement(dataDisplayDelegate) {
318 throw new Error('Needs implemented.');
319 }
320
321 /**
322 * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
323 * @return {!WebInspector.Widget}
324 */
325 createView(dataDisplayDelegate) {
326 throw new Error('Not implemented.');
327 }
328
329 removeTempFile() {
330 if (this._tempFile)
331 this._tempFile.remove();
332 }
333
334 dispose() {
335 }
336
337 /**
338 * @return {boolean}
339 */
340 canSaveToFile() {
341 return false;
342 }
343
344 saveToFile() {
345 throw new Error('Needs implemented');
346 }
347
348 /**
349 * @param {!File} file
350 */
351 loadFromFile(file) {
352 throw new Error('Needs implemented');
353 }
354
355 /**
356 * @return {boolean}
357 */
358 fromFile() {
359 return this._fromFile;
360 }
361
362 setFromFile() {
363 this._fromFile = true;
364 }
317 }; 365 };
318 366
319 /** 367 /**
320 * @constructor 368 * @unrestricted
321 * @param {?string} subtitle
322 * @param {boolean|undefined} wait
323 */ 369 */
324 WebInspector.ProfileHeader.StatusUpdate = function(subtitle, wait) 370 WebInspector.ProfileHeader.StatusUpdate = class {
325 { 371 /**
372 * @param {?string} subtitle
373 * @param {boolean|undefined} wait
374 */
375 constructor(subtitle, wait) {
326 /** @type {?string} */ 376 /** @type {?string} */
327 this.subtitle = subtitle; 377 this.subtitle = subtitle;
328 /** @type {boolean|undefined} */ 378 /** @type {boolean|undefined} */
329 this.wait = wait; 379 this.wait = wait;
380 }
330 }; 381 };
331 382
332 /** @enum {symbol} */ 383 /** @enum {symbol} */
333 WebInspector.ProfileHeader.Events = { 384 WebInspector.ProfileHeader.Events = {
334 UpdateStatus: Symbol("UpdateStatus"), 385 UpdateStatus: Symbol('UpdateStatus'),
335 ProfileReceived: Symbol("ProfileReceived") 386 ProfileReceived: Symbol('ProfileReceived')
336 };
337
338 WebInspector.ProfileHeader.prototype = {
339 /**
340 * @return {?WebInspector.Target}
341 */
342 target: function()
343 {
344 return this._target;
345 },
346
347 /**
348 * @return {!WebInspector.ProfileType}
349 */
350 profileType: function()
351 {
352 return this._profileType;
353 },
354
355 /**
356 * @param {?string} subtitle
357 * @param {boolean=} wait
358 */
359 updateStatus: function(subtitle, wait)
360 {
361 this.dispatchEventToListeners(WebInspector.ProfileHeader.Events.UpdateSt atus, new WebInspector.ProfileHeader.StatusUpdate(subtitle, wait));
362 },
363
364 /**
365 * Must be implemented by subclasses.
366 * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegat e
367 * @return {!WebInspector.ProfileSidebarTreeElement}
368 */
369 createSidebarTreeElement: function(dataDisplayDelegate)
370 {
371 throw new Error("Needs implemented.");
372 },
373
374 /**
375 * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegat e
376 * @return {!WebInspector.Widget}
377 */
378 createView: function(dataDisplayDelegate)
379 {
380 throw new Error("Not implemented.");
381 },
382
383 removeTempFile: function()
384 {
385 if (this._tempFile)
386 this._tempFile.remove();
387 },
388
389 dispose: function()
390 {
391 },
392
393 /**
394 * @return {boolean}
395 */
396 canSaveToFile: function()
397 {
398 return false;
399 },
400
401 saveToFile: function()
402 {
403 throw new Error("Needs implemented");
404 },
405
406 /**
407 * @param {!File} file
408 */
409 loadFromFile: function(file)
410 {
411 throw new Error("Needs implemented");
412 },
413
414 /**
415 * @return {boolean}
416 */
417 fromFile: function()
418 {
419 return this._fromFile;
420 },
421
422 setFromFile: function()
423 {
424 this._fromFile = true;
425 },
426
427 __proto__: WebInspector.Object.prototype
428 }; 387 };
429 388
430 /** 389 /**
431 * @constructor
432 * @implements {WebInspector.ProfileType.DataDisplayDelegate} 390 * @implements {WebInspector.ProfileType.DataDisplayDelegate}
433 * @extends {WebInspector.PanelWithSidebar} 391 * @unrestricted
434 */ 392 */
435 WebInspector.ProfilesPanel = function() 393 WebInspector.ProfilesPanel = class extends WebInspector.PanelWithSidebar {
436 { 394 constructor() {
437 WebInspector.PanelWithSidebar.call(this, "profiles"); 395 super('profiles');
438 this.registerRequiredCSS("ui/panelEnablerView.css"); 396 this.registerRequiredCSS('ui/panelEnablerView.css');
439 this.registerRequiredCSS("profiler/heapProfiler.css"); 397 this.registerRequiredCSS('profiler/heapProfiler.css');
440 this.registerRequiredCSS("profiler/profilesPanel.css"); 398 this.registerRequiredCSS('profiler/profilesPanel.css');
441 this.registerRequiredCSS("components/objectValue.css"); 399 this.registerRequiredCSS('components/objectValue.css');
442 400
443 var mainContainer = new WebInspector.VBox(); 401 var mainContainer = new WebInspector.VBox();
444 this.splitWidget().setMainWidget(mainContainer); 402 this.splitWidget().setMainWidget(mainContainer);
445 403
446 this.profilesItemTreeElement = new WebInspector.ProfilesSidebarTreeElement(t his); 404 this.profilesItemTreeElement = new WebInspector.ProfilesSidebarTreeElement(t his);
447 405
448 this._sidebarTree = new TreeOutlineInShadow(); 406 this._sidebarTree = new TreeOutlineInShadow();
449 this._sidebarTree.registerRequiredCSS("profiler/profilesSidebarTree.css"); 407 this._sidebarTree.registerRequiredCSS('profiler/profilesSidebarTree.css');
450 this.panelSidebarElement().appendChild(this._sidebarTree.element); 408 this.panelSidebarElement().appendChild(this._sidebarTree.element);
451 409
452 this._sidebarTree.appendChild(this.profilesItemTreeElement); 410 this._sidebarTree.appendChild(this.profilesItemTreeElement);
453 411
454 this.profileViews = createElement("div"); 412 this.profileViews = createElement('div');
455 this.profileViews.id = "profile-views"; 413 this.profileViews.id = 'profile-views';
456 this.profileViews.classList.add("vbox"); 414 this.profileViews.classList.add('vbox');
457 mainContainer.element.appendChild(this.profileViews); 415 mainContainer.element.appendChild(this.profileViews);
458 416
459 this._toolbarElement = createElementWithClass("div", "profiles-toolbar"); 417 this._toolbarElement = createElementWithClass('div', 'profiles-toolbar');
460 mainContainer.element.insertBefore(this._toolbarElement, mainContainer.eleme nt.firstChild); 418 mainContainer.element.insertBefore(this._toolbarElement, mainContainer.eleme nt.firstChild);
461 419
462 this.panelSidebarElement().classList.add("profiles-sidebar-tree-box"); 420 this.panelSidebarElement().classList.add('profiles-sidebar-tree-box');
463 var toolbarContainerLeft = createElementWithClass("div", "profiles-toolbar") ; 421 var toolbarContainerLeft = createElementWithClass('div', 'profiles-toolbar') ;
464 this.panelSidebarElement().insertBefore(toolbarContainerLeft, this.panelSide barElement().firstChild); 422 this.panelSidebarElement().insertBefore(toolbarContainerLeft, this.panelSide barElement().firstChild);
465 var toolbar = new WebInspector.Toolbar("", toolbarContainerLeft); 423 var toolbar = new WebInspector.Toolbar('', toolbarContainerLeft);
466 424
467 this._toggleRecordAction = /** @type {!WebInspector.Action }*/ (WebInspector .actionRegistry.action("profiler.toggle-recording")); 425 this._toggleRecordAction =
426 /** @type {!WebInspector.Action }*/ (WebInspector.actionRegistry.action( 'profiler.toggle-recording'));
468 this._toggleRecordButton = WebInspector.Toolbar.createActionButton(this._tog gleRecordAction); 427 this._toggleRecordButton = WebInspector.Toolbar.createActionButton(this._tog gleRecordAction);
469 toolbar.appendToolbarItem(this._toggleRecordButton); 428 toolbar.appendToolbarItem(this._toggleRecordButton);
470 429
471 this.clearResultsButton = new WebInspector.ToolbarButton(WebInspector.UIStri ng("Clear all profiles"), "clear-toolbar-item"); 430 this.clearResultsButton =
472 this.clearResultsButton.addEventListener("click", this._reset, this); 431 new WebInspector.ToolbarButton(WebInspector.UIString('Clear all profiles '), 'clear-toolbar-item');
432 this.clearResultsButton.addEventListener('click', this._reset, this);
473 toolbar.appendToolbarItem(this.clearResultsButton); 433 toolbar.appendToolbarItem(this.clearResultsButton);
474 434
475 this._profileTypeToolbar = new WebInspector.Toolbar("", this._toolbarElement ); 435 this._profileTypeToolbar = new WebInspector.Toolbar('', this._toolbarElement );
476 this._profileViewToolbar = new WebInspector.Toolbar("", this._toolbarElement ); 436 this._profileViewToolbar = new WebInspector.Toolbar('', this._toolbarElement );
477 437
478 this._profileGroups = {}; 438 this._profileGroups = {};
479 this._launcherView = new WebInspector.MultiProfileLauncherView(this); 439 this._launcherView = new WebInspector.MultiProfileLauncherView(this);
480 this._launcherView.addEventListener(WebInspector.MultiProfileLauncherView.Ev ents.ProfileTypeSelected, this._onProfileTypeSelected, this); 440 this._launcherView.addEventListener(
441 WebInspector.MultiProfileLauncherView.Events.ProfileTypeSelected, this._ onProfileTypeSelected, this);
481 442
482 this._profileToView = []; 443 this._profileToView = [];
483 this._typeIdToSidebarSection = {}; 444 this._typeIdToSidebarSection = {};
484 var types = WebInspector.ProfileTypeRegistry.instance.profileTypes(); 445 var types = WebInspector.ProfileTypeRegistry.instance.profileTypes();
485 for (var i = 0; i < types.length; i++) 446 for (var i = 0; i < types.length; i++)
486 this._registerProfileType(types[i]); 447 this._registerProfileType(types[i]);
487 this._launcherView.restoreSelectedProfileType(); 448 this._launcherView.restoreSelectedProfileType();
488 this.profilesItemTreeElement.select(); 449 this.profilesItemTreeElement.select();
489 this._showLauncherView(); 450 this._showLauncherView();
490 451
491 this._createFileSelectorElement(); 452 this._createFileSelectorElement();
492 this.element.addEventListener("contextmenu", this._handleContextMenuEvent.bi nd(this), false); 453 this.element.addEventListener('contextmenu', this._handleContextMenuEvent.bi nd(this), false);
493 454
494 this.contentElement.addEventListener("keydown", this._onKeyDown.bind(this), false); 455 this.contentElement.addEventListener('keydown', this._onKeyDown.bind(this), false);
495 456
496 WebInspector.targetManager.addEventListener(WebInspector.TargetManager.Event s.SuspendStateChanged, this._onSuspendStateChanged, this); 457 WebInspector.targetManager.addEventListener(
497 }; 458 WebInspector.TargetManager.Events.SuspendStateChanged, this._onSuspendSt ateChanged, this);
498 459 }
499 WebInspector.ProfilesPanel.prototype = { 460
500 /** 461 /**
501 * @param {!Event} event 462 * @return {!WebInspector.ProfilesPanel}
502 */ 463 */
503 _onKeyDown: function(event) 464 static _instance() {
504 { 465 return /** @type {!WebInspector.ProfilesPanel} */ (self.runtime.sharedInstan ce(WebInspector.ProfilesPanel));
505 var handled = false; 466 }
506 if (event.key === "ArrowDown" && !event.altKey) 467
507 handled = this._sidebarTree.selectNext(); 468 /**
508 else if (event.key === "ArrowUp" && !event.altKey) 469 * @param {!Event} event
509 handled = this._sidebarTree.selectPrevious(); 470 */
510 if (handled) 471 _onKeyDown(event) {
511 event.consume(true); 472 var handled = false;
512 }, 473 if (event.key === 'ArrowDown' && !event.altKey)
513 474 handled = this._sidebarTree.selectNext();
514 /** 475 else if (event.key === 'ArrowUp' && !event.altKey)
515 * @override 476 handled = this._sidebarTree.selectPrevious();
516 * @return {?WebInspector.SearchableView} 477 if (handled)
517 */ 478 event.consume(true);
518 searchableView: function() 479 }
519 { 480
520 return this.visibleView && this.visibleView.searchableView ? this.visibl eView.searchableView() : null; 481 /**
521 }, 482 * @override
522 483 * @return {?WebInspector.SearchableView}
523 _createFileSelectorElement: function() 484 */
524 { 485 searchableView() {
525 if (this._fileSelectorElement) 486 return this.visibleView && this.visibleView.searchableView ? this.visibleVie w.searchableView() : null;
526 this.element.removeChild(this._fileSelectorElement); 487 }
527 this._fileSelectorElement = WebInspector.createFileSelectorElement(this. _loadFromFile.bind(this)); 488
528 WebInspector.ProfilesPanel._fileSelectorElement = this._fileSelectorElem ent; 489 _createFileSelectorElement() {
529 this.element.appendChild(this._fileSelectorElement); 490 if (this._fileSelectorElement)
530 }, 491 this.element.removeChild(this._fileSelectorElement);
531 492 this._fileSelectorElement = WebInspector.createFileSelectorElement(this._loa dFromFile.bind(this));
532 _findProfileTypeByExtension: function(fileName) 493 WebInspector.ProfilesPanel._fileSelectorElement = this._fileSelectorElement;
533 { 494 this.element.appendChild(this._fileSelectorElement);
534 var types = WebInspector.ProfileTypeRegistry.instance.profileTypes(); 495 }
535 for (var i = 0; i < types.length; i++) { 496
536 var type = types[i]; 497 _findProfileTypeByExtension(fileName) {
537 var extension = type.fileExtension(); 498 var types = WebInspector.ProfileTypeRegistry.instance.profileTypes();
538 if (!extension) 499 for (var i = 0; i < types.length; i++) {
539 continue; 500 var type = types[i];
540 if (fileName.endsWith(type.fileExtension())) 501 var extension = type.fileExtension();
541 return type; 502 if (!extension)
542 } 503 continue;
543 return null; 504 if (fileName.endsWith(type.fileExtension()))
544 }, 505 return type;
545 506 }
546 /** 507 return null;
547 * @param {!File} file 508 }
548 */ 509
549 _loadFromFile: function(file) 510 /**
550 { 511 * @param {!File} file
551 this._createFileSelectorElement(); 512 */
552 513 _loadFromFile(file) {
553 var profileType = this._findProfileTypeByExtension(file.name); 514 this._createFileSelectorElement();
554 if (!profileType) { 515
555 var extensions = []; 516 var profileType = this._findProfileTypeByExtension(file.name);
556 var types = WebInspector.ProfileTypeRegistry.instance.profileTypes() ; 517 if (!profileType) {
557 for (var i = 0; i < types.length; i++) { 518 var extensions = [];
558 var extension = types[i].fileExtension(); 519 var types = WebInspector.ProfileTypeRegistry.instance.profileTypes();
559 if (!extension || extensions.indexOf(extension) !== -1) 520 for (var i = 0; i < types.length; i++) {
560 continue; 521 var extension = types[i].fileExtension();
561 extensions.push(extension); 522 if (!extension || extensions.indexOf(extension) !== -1)
562 } 523 continue;
563 WebInspector.console.error(WebInspector.UIString("Can't load file. O nly files with extensions '%s' can be loaded.", extensions.join("', '"))); 524 extensions.push(extension);
564 return; 525 }
565 } 526 WebInspector.console.error(WebInspector.UIString(
566 527 'Can\'t load file. Only files with extensions \'%s\' can be loaded.', extensions.join('\', \'')));
567 if (!!profileType.profileBeingRecorded()) { 528 return;
568 WebInspector.console.error(WebInspector.UIString("Can't load profile while another profile is recording.")); 529 }
569 return; 530
570 } 531 if (!!profileType.profileBeingRecorded()) {
571 532 WebInspector.console.error(WebInspector.UIString('Can\'t load profile whil e another profile is recording.'));
572 profileType.loadFromFile(file); 533 return;
573 }, 534 }
574 535
575 /** 536 profileType.loadFromFile(file);
576 * @return {boolean} 537 }
577 */ 538
578 toggleRecord: function() 539 /**
579 { 540 * @return {boolean}
580 if (!this._toggleRecordAction.enabled()) 541 */
581 return true; 542 toggleRecord() {
582 var type = this._selectedProfileType; 543 if (!this._toggleRecordAction.enabled())
583 var isProfiling = type.buttonClicked(); 544 return true;
584 this._updateToggleRecordAction(isProfiling); 545 var type = this._selectedProfileType;
585 if (isProfiling) { 546 var isProfiling = type.buttonClicked();
586 this._launcherView.profileStarted(); 547 this._updateToggleRecordAction(isProfiling);
587 if (type.hasTemporaryView()) 548 if (isProfiling) {
588 this.showProfile(type.profileBeingRecorded()); 549 this._launcherView.profileStarted();
589 } else { 550 if (type.hasTemporaryView())
590 this._launcherView.profileFinished(); 551 this.showProfile(type.profileBeingRecorded());
591 } 552 } else {
592 return true; 553 this._launcherView.profileFinished();
593 }, 554 }
594 555 return true;
595 _onSuspendStateChanged: function() 556 }
596 { 557
597 this._updateToggleRecordAction(this._toggleRecordAction.toggled()); 558 _onSuspendStateChanged() {
598 }, 559 this._updateToggleRecordAction(this._toggleRecordAction.toggled());
599 560 }
600 /** 561
601 * @param {boolean} toggled 562 /**
602 */ 563 * @param {boolean} toggled
603 _updateToggleRecordAction: function(toggled) 564 */
604 { 565 _updateToggleRecordAction(toggled) {
605 var enable = toggled || !WebInspector.targetManager.allTargetsSuspended( ); 566 var enable = toggled || !WebInspector.targetManager.allTargetsSuspended();
606 this._toggleRecordAction.setEnabled(enable); 567 this._toggleRecordAction.setEnabled(enable);
607 this._toggleRecordAction.setToggled(toggled); 568 this._toggleRecordAction.setToggled(toggled);
608 if (enable) 569 if (enable)
609 this._toggleRecordButton.setTitle(this._selectedProfileType ? this._ selectedProfileType.buttonTooltip : ""); 570 this._toggleRecordButton.setTitle(this._selectedProfileType ? this._select edProfileType.buttonTooltip : '');
610 else 571 else
611 this._toggleRecordButton.setTitle(WebInspector.anotherProfilerActive Label()); 572 this._toggleRecordButton.setTitle(WebInspector.anotherProfilerActiveLabel( ));
612 if (this._selectedProfileType) 573 if (this._selectedProfileType)
613 this._launcherView.updateProfileType(this._selectedProfileType, enab le); 574 this._launcherView.updateProfileType(this._selectedProfileType, enable);
614 }, 575 }
615 576
616 _profileBeingRecordedRemoved: function() 577 _profileBeingRecordedRemoved() {
617 { 578 this._updateToggleRecordAction(false);
618 this._updateToggleRecordAction(false); 579 this._launcherView.profileFinished();
619 this._launcherView.profileFinished(); 580 }
620 }, 581
582 /**
583 * @param {!WebInspector.Event} event
584 */
585 _onProfileTypeSelected(event) {
586 this._selectedProfileType = /** @type {!WebInspector.ProfileType} */ (event. data);
587 this._updateProfileTypeSpecificUI();
588 }
589
590 _updateProfileTypeSpecificUI() {
591 this._updateToggleRecordAction(this._toggleRecordAction.toggled());
592 this._profileTypeToolbar.removeToolbarItems();
593 var toolbarItems = this._selectedProfileType.toolbarItems();
594 for (var i = 0; i < toolbarItems.length; ++i)
595 this._profileTypeToolbar.appendToolbarItem(toolbarItems[i]);
596 }
597
598 _reset() {
599 var types = WebInspector.ProfileTypeRegistry.instance.profileTypes();
600 for (var i = 0; i < types.length; i++)
601 types[i]._reset();
602
603 delete this.visibleView;
604
605 this._profileGroups = {};
606 this._updateToggleRecordAction(false);
607 this._launcherView.profileFinished();
608
609 this._sidebarTree.element.classList.remove('some-expandable');
610
611 this._launcherView.detach();
612 this.profileViews.removeChildren();
613 this._profileViewToolbar.removeToolbarItems();
614
615 this.removeAllListeners();
616
617 this._profileViewToolbar.element.classList.remove('hidden');
618 this.clearResultsButton.element.classList.remove('hidden');
619 this.profilesItemTreeElement.select();
620 this._showLauncherView();
621 }
622
623 _showLauncherView() {
624 this.closeVisibleView();
625 this._profileViewToolbar.removeToolbarItems();
626 this._launcherView.show(this.profileViews);
627 this.visibleView = this._launcherView;
628 }
629
630 /**
631 * @param {!WebInspector.ProfileType} profileType
632 */
633 _registerProfileType(profileType) {
634 this._launcherView.addProfileType(profileType);
635 var profileTypeSection = new WebInspector.ProfileTypeSidebarSection(this, pr ofileType);
636 this._typeIdToSidebarSection[profileType.id] = profileTypeSection;
637 this._sidebarTree.appendChild(profileTypeSection);
638 profileTypeSection.childrenListElement.addEventListener(
639 'contextmenu', this._handleContextMenuEvent.bind(this), false);
621 640
622 /** 641 /**
623 * @param {!WebInspector.Event} event 642 * @param {!WebInspector.Event} event
643 * @this {WebInspector.ProfilesPanel}
624 */ 644 */
625 _onProfileTypeSelected: function(event) 645 function onAddProfileHeader(event) {
626 { 646 this._addProfileHeader(/** @type {!WebInspector.ProfileHeader} */ (event.d ata));
627 this._selectedProfileType = /** @type {!WebInspector.ProfileType} */ (ev ent.data); 647 }
628 this._updateProfileTypeSpecificUI();
629 },
630
631 _updateProfileTypeSpecificUI: function()
632 {
633 this._updateToggleRecordAction(this._toggleRecordAction.toggled());
634 this._profileTypeToolbar.removeToolbarItems();
635 var toolbarItems = this._selectedProfileType.toolbarItems();
636 for (var i = 0; i < toolbarItems.length; ++i)
637 this._profileTypeToolbar.appendToolbarItem(toolbarItems[i]);
638 },
639
640 _reset: function()
641 {
642 var types = WebInspector.ProfileTypeRegistry.instance.profileTypes();
643 for (var i = 0; i < types.length; i++)
644 types[i]._reset();
645
646 delete this.visibleView;
647
648 this._profileGroups = {};
649 this._updateToggleRecordAction(false);
650 this._launcherView.profileFinished();
651
652 this._sidebarTree.element.classList.remove("some-expandable");
653
654 this._launcherView.detach();
655 this.profileViews.removeChildren();
656 this._profileViewToolbar.removeToolbarItems();
657
658 this.removeAllListeners();
659
660 this._profileViewToolbar.element.classList.remove("hidden");
661 this.clearResultsButton.element.classList.remove("hidden");
662 this.profilesItemTreeElement.select();
663 this._showLauncherView();
664 },
665
666 _showLauncherView: function()
667 {
668 this.closeVisibleView();
669 this._profileViewToolbar.removeToolbarItems();
670 this._launcherView.show(this.profileViews);
671 this.visibleView = this._launcherView;
672 },
673 648
674 /** 649 /**
675 * @param {!WebInspector.ProfileType} profileType 650 * @param {!WebInspector.Event} event
651 * @this {WebInspector.ProfilesPanel}
676 */ 652 */
677 _registerProfileType: function(profileType) 653 function onRemoveProfileHeader(event) {
678 { 654 this._removeProfileHeader(/** @type {!WebInspector.ProfileHeader} */ (even t.data));
679 this._launcherView.addProfileType(profileType); 655 }
680 var profileTypeSection = new WebInspector.ProfileTypeSidebarSection(this , profileType);
681 this._typeIdToSidebarSection[profileType.id] = profileTypeSection;
682 this._sidebarTree.appendChild(profileTypeSection);
683 profileTypeSection.childrenListElement.addEventListener("contextmenu", t his._handleContextMenuEvent.bind(this), false);
684
685 /**
686 * @param {!WebInspector.Event} event
687 * @this {WebInspector.ProfilesPanel}
688 */
689 function onAddProfileHeader(event)
690 {
691 this._addProfileHeader(/** @type {!WebInspector.ProfileHeader} */ (e vent.data));
692 }
693
694 /**
695 * @param {!WebInspector.Event} event
696 * @this {WebInspector.ProfilesPanel}
697 */
698 function onRemoveProfileHeader(event)
699 {
700 this._removeProfileHeader(/** @type {!WebInspector.ProfileHeader} */ (event.data));
701 }
702
703 /**
704 * @param {!WebInspector.Event} event
705 * @this {WebInspector.ProfilesPanel}
706 */
707 function profileComplete(event)
708 {
709 this.showProfile(/** @type {!WebInspector.ProfileHeader} */ (event.d ata));
710 }
711
712 profileType.addEventListener(WebInspector.ProfileType.Events.ViewUpdated , this._updateProfileTypeSpecificUI, this);
713 profileType.addEventListener(WebInspector.ProfileType.Events.AddProfileH eader, onAddProfileHeader, this);
714 profileType.addEventListener(WebInspector.ProfileType.Events.RemoveProfi leHeader, onRemoveProfileHeader, this);
715 profileType.addEventListener(WebInspector.ProfileType.Events.ProfileComp lete, profileComplete, this);
716
717 var profiles = profileType.getProfiles();
718 for (var i = 0; i < profiles.length; i++)
719 this._addProfileHeader(profiles[i]);
720 },
721 656
722 /** 657 /**
723 * @param {!Event} event 658 * @param {!WebInspector.Event} event
659 * @this {WebInspector.ProfilesPanel}
724 */ 660 */
725 _handleContextMenuEvent: function(event) 661 function profileComplete(event) {
726 { 662 this.showProfile(/** @type {!WebInspector.ProfileHeader} */ (event.data));
727 var contextMenu = new WebInspector.ContextMenu(event); 663 }
728 if (this.visibleView instanceof WebInspector.HeapSnapshotView) { 664
729 this.visibleView.populateContextMenu(contextMenu, event); 665 profileType.addEventListener(WebInspector.ProfileType.Events.ViewUpdated, th is._updateProfileTypeSpecificUI, this);
730 } 666 profileType.addEventListener(WebInspector.ProfileType.Events.AddProfileHeade r, onAddProfileHeader, this);
731 if (this.panelSidebarElement().isSelfOrAncestor(event.srcElement)) 667 profileType.addEventListener(WebInspector.ProfileType.Events.RemoveProfileHe ader, onRemoveProfileHeader, this);
732 contextMenu.appendItem(WebInspector.UIString("Load\u2026"), this._fi leSelectorElement.click.bind(this._fileSelectorElement)); 668 profileType.addEventListener(WebInspector.ProfileType.Events.ProfileComplete , profileComplete, this);
733 contextMenu.show(); 669
734 }, 670 var profiles = profileType.getProfiles();
735 671 for (var i = 0; i < profiles.length; i++)
736 showLoadFromFileDialog: function() 672 this._addProfileHeader(profiles[i]);
737 { 673 }
738 this._fileSelectorElement.click(); 674
739 }, 675 /**
676 * @param {!Event} event
677 */
678 _handleContextMenuEvent(event) {
679 var contextMenu = new WebInspector.ContextMenu(event);
680 if (this.visibleView instanceof WebInspector.HeapSnapshotView) {
681 this.visibleView.populateContextMenu(contextMenu, event);
682 }
683 if (this.panelSidebarElement().isSelfOrAncestor(event.srcElement))
684 contextMenu.appendItem(
685 WebInspector.UIString('Load\u2026'), this._fileSelectorElement.click.b ind(this._fileSelectorElement));
686 contextMenu.show();
687 }
688
689 showLoadFromFileDialog() {
690 this._fileSelectorElement.click();
691 }
692
693 /**
694 * @param {!WebInspector.ProfileHeader} profile
695 */
696 _addProfileHeader(profile) {
697 var profileType = profile.profileType();
698 var typeId = profileType.id;
699 this._typeIdToSidebarSection[typeId].addProfileHeader(profile);
700 if (!this.visibleView || this.visibleView === this._launcherView)
701 this.showProfile(profile);
702 }
703
704 /**
705 * @param {!WebInspector.ProfileHeader} profile
706 */
707 _removeProfileHeader(profile) {
708 if (profile.profileType()._profileBeingRecorded === profile)
709 this._profileBeingRecordedRemoved();
710
711 var i = this._indexOfViewForProfile(profile);
712 if (i !== -1)
713 this._profileToView.splice(i, 1);
714
715 var profileType = profile.profileType();
716 var typeId = profileType.id;
717 var sectionIsEmpty = this._typeIdToSidebarSection[typeId].removeProfileHeade r(profile);
718
719 // No other item will be selected if there aren't any other profiles, so
720 // make sure that view gets cleared when the last profile is removed.
721 if (sectionIsEmpty) {
722 this.profilesItemTreeElement.select();
723 this._showLauncherView();
724 }
725 }
726
727 /**
728 * @override
729 * @param {?WebInspector.ProfileHeader} profile
730 * @return {?WebInspector.Widget}
731 */
732 showProfile(profile) {
733 if (!profile ||
734 (profile.profileType().profileBeingRecorded() === profile) && !profile.p rofileType().hasTemporaryView())
735 return null;
736
737 var view = this._viewForProfile(profile);
738 if (view === this.visibleView)
739 return view;
740
741 this.closeVisibleView();
742
743 view.show(this.profileViews);
744 view.focus();
745
746 this.visibleView = view;
747
748 var profileTypeSection = this._typeIdToSidebarSection[profile.profileType(). id];
749 var sidebarElement = profileTypeSection.sidebarElementForProfile(profile);
750 sidebarElement.revealAndSelect();
751
752 this._profileViewToolbar.removeToolbarItems();
753
754 var toolbarItems = view.syncToolbarItems();
755 for (var i = 0; i < toolbarItems.length; ++i)
756 this._profileViewToolbar.appendToolbarItem(toolbarItems[i]);
757
758 return view;
759 }
760
761 /**
762 * @override
763 * @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId
764 * @param {string} perspectiveName
765 */
766 showObject(snapshotObjectId, perspectiveName) {
767 var heapProfiles = WebInspector.ProfileTypeRegistry.instance.heapSnapshotPro fileType.getProfiles();
768 for (var i = 0; i < heapProfiles.length; i++) {
769 var profile = heapProfiles[i];
770 // FIXME: allow to choose snapshot if there are several options.
771 if (profile.maxJSObjectId >= snapshotObjectId) {
772 this.showProfile(profile);
773 var view = this._viewForProfile(profile);
774 view.selectLiveObject(perspectiveName, snapshotObjectId);
775 break;
776 }
777 }
778 }
779
780 /**
781 * @param {!WebInspector.ProfileHeader} profile
782 * @return {!WebInspector.Widget}
783 */
784 _viewForProfile(profile) {
785 var index = this._indexOfViewForProfile(profile);
786 if (index !== -1)
787 return this._profileToView[index].view;
788 var view = profile.createView(this);
789 view.element.classList.add('profile-view');
790 this._profileToView.push({profile: profile, view: view});
791 return view;
792 }
793
794 /**
795 * @param {!WebInspector.ProfileHeader} profile
796 * @return {number}
797 */
798 _indexOfViewForProfile(profile) {
799 for (var i = 0; i < this._profileToView.length; i++) {
800 if (this._profileToView[i].profile === profile)
801 return i;
802 }
803 return -1;
804 }
805
806 closeVisibleView() {
807 if (this.visibleView)
808 this.visibleView.detach();
809 delete this.visibleView;
810 }
811
812 /**
813 * @param {!Event} event
814 * @param {!WebInspector.ContextMenu} contextMenu
815 * @param {!Object} target
816 */
817 appendApplicableItems(event, contextMenu, target) {
818 if (!(target instanceof WebInspector.RemoteObject))
819 return;
820
821 if (!this.isShowing())
822 return;
823
824 var object = /** @type {!WebInspector.RemoteObject} */ (target);
825 var objectId = object.objectId;
826 if (!objectId)
827 return;
828
829 var heapProfiles = WebInspector.ProfileTypeRegistry.instance.heapSnapshotPro fileType.getProfiles();
830 if (!heapProfiles.length)
831 return;
740 832
741 /** 833 /**
742 * @param {!WebInspector.ProfileHeader} profile 834 * @this {WebInspector.ProfilesPanel}
743 */ 835 */
744 _addProfileHeader: function(profile) 836 function revealInView(viewName) {
745 { 837 object.target().heapProfilerAgent().getHeapObjectId(objectId, didReceiveHe apObjectId.bind(this, viewName));
746 var profileType = profile.profileType(); 838 }
747 var typeId = profileType.id;
748 this._typeIdToSidebarSection[typeId].addProfileHeader(profile);
749 if (!this.visibleView || this.visibleView === this._launcherView)
750 this.showProfile(profile);
751 },
752 839
753 /** 840 /**
754 * @param {!WebInspector.ProfileHeader} profile 841 * @this {WebInspector.ProfilesPanel}
755 */ 842 */
756 _removeProfileHeader: function(profile) 843 function didReceiveHeapObjectId(viewName, error, result) {
757 { 844 if (!this.isShowing())
758 if (profile.profileType()._profileBeingRecorded === profile) 845 return;
759 this._profileBeingRecordedRemoved(); 846 if (!error)
760 847 this.showObject(result, viewName);
761 var i = this._indexOfViewForProfile(profile); 848 }
762 if (i !== -1) 849
763 this._profileToView.splice(i, 1); 850 contextMenu.appendItem(
764 851 WebInspector.UIString.capitalize('Reveal in Summary ^view'), revealInVie w.bind(this, 'Summary'));
765 var profileType = profile.profileType(); 852 }
766 var typeId = profileType.id; 853
767 var sectionIsEmpty = this._typeIdToSidebarSection[typeId].removeProfileH eader(profile); 854 /**
768 855 * @override
769 // No other item will be selected if there aren't any other profiles, so 856 */
770 // make sure that view gets cleared when the last profile is removed. 857 wasShown() {
771 if (sectionIsEmpty) { 858 WebInspector.context.setFlavor(WebInspector.ProfilesPanel, this);
772 this.profilesItemTreeElement.select(); 859 }
773 this._showLauncherView(); 860
774 } 861 /**
775 }, 862 * @override
776 863 */
777 /** 864 focus() {
778 * @override 865 this._sidebarTree.focus();
779 * @param {?WebInspector.ProfileHeader} profile 866 }
780 * @return {?WebInspector.Widget} 867
781 */ 868 /**
782 showProfile: function(profile) 869 * @override
783 { 870 */
784 if (!profile || (profile.profileType().profileBeingRecorded() === profil e) && !profile.profileType().hasTemporaryView()) 871 willHide() {
785 return null; 872 WebInspector.context.setFlavor(WebInspector.ProfilesPanel, null);
786 873 }
787 var view = this._viewForProfile(profile);
788 if (view === this.visibleView)
789 return view;
790
791 this.closeVisibleView();
792
793 view.show(this.profileViews);
794 view.focus();
795
796 this.visibleView = view;
797
798 var profileTypeSection = this._typeIdToSidebarSection[profile.profileTyp e().id];
799 var sidebarElement = profileTypeSection.sidebarElementForProfile(profile );
800 sidebarElement.revealAndSelect();
801
802 this._profileViewToolbar.removeToolbarItems();
803
804 var toolbarItems = view.syncToolbarItems();
805 for (var i = 0; i < toolbarItems.length; ++i)
806 this._profileViewToolbar.appendToolbarItem(toolbarItems[i]);
807
808 return view;
809 },
810
811 /**
812 * @override
813 * @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId
814 * @param {string} perspectiveName
815 */
816 showObject: function(snapshotObjectId, perspectiveName)
817 {
818 var heapProfiles = WebInspector.ProfileTypeRegistry.instance.heapSnapsho tProfileType.getProfiles();
819 for (var i = 0; i < heapProfiles.length; i++) {
820 var profile = heapProfiles[i];
821 // FIXME: allow to choose snapshot if there are several options.
822 if (profile.maxJSObjectId >= snapshotObjectId) {
823 this.showProfile(profile);
824 var view = this._viewForProfile(profile);
825 view.selectLiveObject(perspectiveName, snapshotObjectId);
826 break;
827 }
828 }
829 },
830
831 /**
832 * @param {!WebInspector.ProfileHeader} profile
833 * @return {!WebInspector.Widget}
834 */
835 _viewForProfile: function(profile)
836 {
837 var index = this._indexOfViewForProfile(profile);
838 if (index !== -1)
839 return this._profileToView[index].view;
840 var view = profile.createView(this);
841 view.element.classList.add("profile-view");
842 this._profileToView.push({ profile: profile, view: view});
843 return view;
844 },
845
846 /**
847 * @param {!WebInspector.ProfileHeader} profile
848 * @return {number}
849 */
850 _indexOfViewForProfile: function(profile)
851 {
852 for (var i = 0; i < this._profileToView.length; i++) {
853 if (this._profileToView[i].profile === profile)
854 return i;
855 }
856 return -1;
857 },
858
859 closeVisibleView: function()
860 {
861 if (this.visibleView)
862 this.visibleView.detach();
863 delete this.visibleView;
864 },
865
866 /**
867 * @param {!Event} event
868 * @param {!WebInspector.ContextMenu} contextMenu
869 * @param {!Object} target
870 */
871 appendApplicableItems: function(event, contextMenu, target)
872 {
873 if (!(target instanceof WebInspector.RemoteObject))
874 return;
875
876 if (!this.isShowing())
877 return;
878
879 var object = /** @type {!WebInspector.RemoteObject} */ (target);
880 var objectId = object.objectId;
881 if (!objectId)
882 return;
883
884 var heapProfiles = WebInspector.ProfileTypeRegistry.instance.heapSnapsho tProfileType.getProfiles();
885 if (!heapProfiles.length)
886 return;
887
888 /**
889 * @this {WebInspector.ProfilesPanel}
890 */
891 function revealInView(viewName)
892 {
893 object.target().heapProfilerAgent().getHeapObjectId(objectId, didRec eiveHeapObjectId.bind(this, viewName));
894 }
895
896 /**
897 * @this {WebInspector.ProfilesPanel}
898 */
899 function didReceiveHeapObjectId(viewName, error, result)
900 {
901 if (!this.isShowing())
902 return;
903 if (!error)
904 this.showObject(result, viewName);
905 }
906
907 contextMenu.appendItem(WebInspector.UIString.capitalize("Reveal in Summa ry ^view"), revealInView.bind(this, "Summary"));
908 },
909
910 wasShown: function()
911 {
912 WebInspector.context.setFlavor(WebInspector.ProfilesPanel, this);
913 },
914
915 /**
916 * @override
917 */
918 focus: function()
919 {
920 this._sidebarTree.focus();
921 },
922
923 willHide: function()
924 {
925 WebInspector.context.setFlavor(WebInspector.ProfilesPanel, null);
926 },
927
928 __proto__: WebInspector.PanelWithSidebar.prototype
929 }; 874 };
930 875
931
932 /** 876 /**
933 * @constructor 877 * @unrestricted
934 * @extends {TreeElement}
935 * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
936 * @param {!WebInspector.ProfileType} profileType
937 */ 878 */
938 WebInspector.ProfileTypeSidebarSection = function(dataDisplayDelegate, profileTy pe) 879 WebInspector.ProfileTypeSidebarSection = class extends TreeElement {
939 { 880 /**
940 TreeElement.call(this, profileType.treeItemTitle.escapeHTML(), true); 881 * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
882 * @param {!WebInspector.ProfileType} profileType
883 */
884 constructor(dataDisplayDelegate, profileType) {
885 super(profileType.treeItemTitle.escapeHTML(), true);
941 this.selectable = false; 886 this.selectable = false;
942 this._dataDisplayDelegate = dataDisplayDelegate; 887 this._dataDisplayDelegate = dataDisplayDelegate;
943 /** @type {!Array<!WebInspector.ProfileSidebarTreeElement>} */ 888 /** @type {!Array<!WebInspector.ProfileSidebarTreeElement>} */
944 this._profileTreeElements = []; 889 this._profileTreeElements = [];
945 /** @type {!Object<string, !WebInspector.ProfileTypeSidebarSection.ProfileGr oup>} */ 890 /** @type {!Object<string, !WebInspector.ProfileTypeSidebarSection.ProfileGr oup>} */
946 this._profileGroups = {}; 891 this._profileGroups = {};
947 this.expand(); 892 this.expand();
948 this.hidden = true; 893 this.hidden = true;
894 }
895
896 /**
897 * @param {!WebInspector.ProfileHeader} profile
898 */
899 addProfileHeader(profile) {
900 this.hidden = false;
901 var profileType = profile.profileType();
902 var sidebarParent = this;
903 var profileTreeElement = profile.createSidebarTreeElement(this._dataDisplayD elegate);
904 this._profileTreeElements.push(profileTreeElement);
905
906 if (!profile.fromFile() && profileType.profileBeingRecorded() !== profile) {
907 var profileTitle = profile.title;
908 var group = this._profileGroups[profileTitle];
909 if (!group) {
910 group = new WebInspector.ProfileTypeSidebarSection.ProfileGroup();
911 this._profileGroups[profileTitle] = group;
912 }
913 group.profileSidebarTreeElements.push(profileTreeElement);
914
915 var groupSize = group.profileSidebarTreeElements.length;
916 if (groupSize === 2) {
917 // Make a group TreeElement now that there are 2 profiles.
918 group.sidebarTreeElement =
919 new WebInspector.ProfileGroupSidebarTreeElement(this._dataDisplayDel egate, profile.title);
920
921 var firstProfileTreeElement = group.profileSidebarTreeElements[0];
922 // Insert at the same index for the first profile of the group.
923 var index = this.children().indexOf(firstProfileTreeElement);
924 this.insertChild(group.sidebarTreeElement, index);
925
926 // Move the first profile to the group.
927 var selected = firstProfileTreeElement.selected;
928 this.removeChild(firstProfileTreeElement);
929 group.sidebarTreeElement.appendChild(firstProfileTreeElement);
930 if (selected)
931 firstProfileTreeElement.revealAndSelect();
932
933 firstProfileTreeElement.setSmall(true);
934 firstProfileTreeElement.setMainTitle(WebInspector.UIString('Run %d', 1)) ;
935
936 this.treeOutline.element.classList.add('some-expandable');
937 }
938
939 if (groupSize >= 2) {
940 sidebarParent = group.sidebarTreeElement;
941 profileTreeElement.setSmall(true);
942 profileTreeElement.setMainTitle(WebInspector.UIString('Run %d', groupSiz e));
943 }
944 }
945
946 sidebarParent.appendChild(profileTreeElement);
947 }
948
949 /**
950 * @param {!WebInspector.ProfileHeader} profile
951 * @return {boolean}
952 */
953 removeProfileHeader(profile) {
954 var index = this._sidebarElementIndex(profile);
955 if (index === -1)
956 return false;
957 var profileTreeElement = this._profileTreeElements[index];
958 this._profileTreeElements.splice(index, 1);
959
960 var sidebarParent = this;
961 var group = this._profileGroups[profile.title];
962 if (group) {
963 var groupElements = group.profileSidebarTreeElements;
964 groupElements.splice(groupElements.indexOf(profileTreeElement), 1);
965 if (groupElements.length === 1) {
966 // Move the last profile out of its group and remove the group.
967 var pos = sidebarParent.children().indexOf(
968 /** @type {!WebInspector.ProfileGroupSidebarTreeElement} */ (group.s idebarTreeElement));
969 group.sidebarTreeElement.removeChild(groupElements[0]);
970 this.insertChild(groupElements[0], pos);
971 groupElements[0].setSmall(false);
972 groupElements[0].setMainTitle(profile.title);
973 this.removeChild(group.sidebarTreeElement);
974 }
975 if (groupElements.length !== 0)
976 sidebarParent = group.sidebarTreeElement;
977 }
978 sidebarParent.removeChild(profileTreeElement);
979 profileTreeElement.dispose();
980
981 if (this.childCount())
982 return false;
983 this.hidden = true;
984 return true;
985 }
986
987 /**
988 * @param {!WebInspector.ProfileHeader} profile
989 * @return {?WebInspector.ProfileSidebarTreeElement}
990 */
991 sidebarElementForProfile(profile) {
992 var index = this._sidebarElementIndex(profile);
993 return index === -1 ? null : this._profileTreeElements[index];
994 }
995
996 /**
997 * @param {!WebInspector.ProfileHeader} profile
998 * @return {number}
999 */
1000 _sidebarElementIndex(profile) {
1001 var elements = this._profileTreeElements;
1002 for (var i = 0; i < elements.length; i++) {
1003 if (elements[i].profile === profile)
1004 return i;
1005 }
1006 return -1;
1007 }
1008
1009 /**
1010 * @override
1011 */
1012 onattach() {
1013 this.listItemElement.classList.add('profiles-tree-section');
1014 }
949 }; 1015 };
950 1016
951 /** 1017 /**
952 * @constructor 1018 * @unrestricted
953 */ 1019 */
954 WebInspector.ProfileTypeSidebarSection.ProfileGroup = function() 1020 WebInspector.ProfileTypeSidebarSection.ProfileGroup = class {
955 { 1021 constructor() {
956 /** @type {!Array<!WebInspector.ProfileSidebarTreeElement>} */ 1022 /** @type {!Array<!WebInspector.ProfileSidebarTreeElement>} */
957 this.profileSidebarTreeElements = []; 1023 this.profileSidebarTreeElements = [];
958 /** @type {?WebInspector.ProfileGroupSidebarTreeElement} */ 1024 /** @type {?WebInspector.ProfileGroupSidebarTreeElement} */
959 this.sidebarTreeElement = null; 1025 this.sidebarTreeElement = null;
960 }; 1026 }
961
962 WebInspector.ProfileTypeSidebarSection.prototype = {
963 /**
964 * @param {!WebInspector.ProfileHeader} profile
965 */
966 addProfileHeader: function(profile)
967 {
968 this.hidden = false;
969 var profileType = profile.profileType();
970 var sidebarParent = this;
971 var profileTreeElement = profile.createSidebarTreeElement(this._dataDisp layDelegate);
972 this._profileTreeElements.push(profileTreeElement);
973
974 if (!profile.fromFile() && profileType.profileBeingRecorded() !== profil e) {
975 var profileTitle = profile.title;
976 var group = this._profileGroups[profileTitle];
977 if (!group) {
978 group = new WebInspector.ProfileTypeSidebarSection.ProfileGroup( );
979 this._profileGroups[profileTitle] = group;
980 }
981 group.profileSidebarTreeElements.push(profileTreeElement);
982
983 var groupSize = group.profileSidebarTreeElements.length;
984 if (groupSize === 2) {
985 // Make a group TreeElement now that there are 2 profiles.
986 group.sidebarTreeElement = new WebInspector.ProfileGroupSidebarT reeElement(this._dataDisplayDelegate, profile.title);
987
988 var firstProfileTreeElement = group.profileSidebarTreeElements[0 ];
989 // Insert at the same index for the first profile of the group.
990 var index = this.children().indexOf(firstProfileTreeElement);
991 this.insertChild(group.sidebarTreeElement, index);
992
993 // Move the first profile to the group.
994 var selected = firstProfileTreeElement.selected;
995 this.removeChild(firstProfileTreeElement);
996 group.sidebarTreeElement.appendChild(firstProfileTreeElement);
997 if (selected)
998 firstProfileTreeElement.revealAndSelect();
999
1000 firstProfileTreeElement.setSmall(true);
1001 firstProfileTreeElement.setMainTitle(WebInspector.UIString("Run %d", 1));
1002
1003 this.treeOutline.element.classList.add("some-expandable");
1004 }
1005
1006 if (groupSize >= 2) {
1007 sidebarParent = group.sidebarTreeElement;
1008 profileTreeElement.setSmall(true);
1009 profileTreeElement.setMainTitle(WebInspector.UIString("Run %d", groupSize));
1010 }
1011 }
1012
1013 sidebarParent.appendChild(profileTreeElement);
1014 },
1015
1016 /**
1017 * @param {!WebInspector.ProfileHeader} profile
1018 * @return {boolean}
1019 */
1020 removeProfileHeader: function(profile)
1021 {
1022 var index = this._sidebarElementIndex(profile);
1023 if (index === -1)
1024 return false;
1025 var profileTreeElement = this._profileTreeElements[index];
1026 this._profileTreeElements.splice(index, 1);
1027
1028 var sidebarParent = this;
1029 var group = this._profileGroups[profile.title];
1030 if (group) {
1031 var groupElements = group.profileSidebarTreeElements;
1032 groupElements.splice(groupElements.indexOf(profileTreeElement), 1);
1033 if (groupElements.length === 1) {
1034 // Move the last profile out of its group and remove the group.
1035 var pos = sidebarParent.children().indexOf(/** @type {!WebInspec tor.ProfileGroupSidebarTreeElement} */ (group.sidebarTreeElement));
1036 group.sidebarTreeElement.removeChild(groupElements[0]);
1037 this.insertChild(groupElements[0], pos);
1038 groupElements[0].setSmall(false);
1039 groupElements[0].setMainTitle(profile.title);
1040 this.removeChild(group.sidebarTreeElement);
1041 }
1042 if (groupElements.length !== 0)
1043 sidebarParent = group.sidebarTreeElement;
1044 }
1045 sidebarParent.removeChild(profileTreeElement);
1046 profileTreeElement.dispose();
1047
1048 if (this.childCount())
1049 return false;
1050 this.hidden = true;
1051 return true;
1052 },
1053
1054 /**
1055 * @param {!WebInspector.ProfileHeader} profile
1056 * @return {?WebInspector.ProfileSidebarTreeElement}
1057 */
1058 sidebarElementForProfile: function(profile)
1059 {
1060 var index = this._sidebarElementIndex(profile);
1061 return index === -1 ? null : this._profileTreeElements[index];
1062 },
1063
1064 /**
1065 * @param {!WebInspector.ProfileHeader} profile
1066 * @return {number}
1067 */
1068 _sidebarElementIndex: function(profile)
1069 {
1070 var elements = this._profileTreeElements;
1071 for (var i = 0; i < elements.length; i++) {
1072 if (elements[i].profile === profile)
1073 return i;
1074 }
1075 return -1;
1076 },
1077
1078 /**
1079 * @override
1080 */
1081 onattach: function()
1082 {
1083 this.listItemElement.classList.add("profiles-tree-section");
1084 },
1085
1086 __proto__: TreeElement.prototype
1087 };
1088
1089
1090 /**
1091 * @constructor
1092 * @implements {WebInspector.ContextMenu.Provider}
1093 */
1094 WebInspector.ProfilesPanel.ContextMenuProvider = function()
1095 {
1096 };
1097
1098 WebInspector.ProfilesPanel.ContextMenuProvider.prototype = {
1099 /**
1100 * @override
1101 * @param {!Event} event
1102 * @param {!WebInspector.ContextMenu} contextMenu
1103 * @param {!Object} target
1104 */
1105 appendApplicableItems: function(event, contextMenu, target)
1106 {
1107 WebInspector.ProfilesPanel._instance().appendApplicableItems(event, cont extMenu, target);
1108 }
1109 }; 1027 };
1110 1028
1111 /** 1029 /**
1112 * @constructor 1030 * @implements {WebInspector.ContextMenu.Provider}
1113 * @extends {TreeElement} 1031 * @unrestricted
1114 * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
1115 * @param {!WebInspector.ProfileHeader} profile
1116 * @param {string} className
1117 */ 1032 */
1118 WebInspector.ProfileSidebarTreeElement = function(dataDisplayDelegate, profile, className) 1033 WebInspector.ProfilesPanel.ContextMenuProvider = class {
1119 { 1034 /**
1120 TreeElement.call(this, "", false); 1035 * @override
1121 this._iconElement = createElementWithClass("div", "icon"); 1036 * @param {!Event} event
1122 this._titlesElement = createElementWithClass("div", "titles no-subtitle"); 1037 * @param {!WebInspector.ContextMenu} contextMenu
1123 this._titleContainer = this._titlesElement.createChild("span", "title-contai ner"); 1038 * @param {!Object} target
1124 this._titleElement = this._titleContainer.createChild("span", "title"); 1039 */
1125 this._subtitleElement = this._titlesElement.createChild("span", "subtitle"); 1040 appendApplicableItems(event, contextMenu, target) {
1041 WebInspector.ProfilesPanel._instance().appendApplicableItems(event, contextM enu, target);
1042 }
1043 };
1044
1045 /**
1046 * @unrestricted
1047 */
1048 WebInspector.ProfileSidebarTreeElement = class extends TreeElement {
1049 /**
1050 * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
1051 * @param {!WebInspector.ProfileHeader} profile
1052 * @param {string} className
1053 */
1054 constructor(dataDisplayDelegate, profile, className) {
1055 super('', false);
1056 this._iconElement = createElementWithClass('div', 'icon');
1057 this._titlesElement = createElementWithClass('div', 'titles no-subtitle');
1058 this._titleContainer = this._titlesElement.createChild('span', 'title-contai ner');
1059 this._titleElement = this._titleContainer.createChild('span', 'title');
1060 this._subtitleElement = this._titlesElement.createChild('span', 'subtitle');
1126 1061
1127 this._titleElement.textContent = profile.title; 1062 this._titleElement.textContent = profile.title;
1128 this._className = className; 1063 this._className = className;
1129 this._small = false; 1064 this._small = false;
1130 this._dataDisplayDelegate = dataDisplayDelegate; 1065 this._dataDisplayDelegate = dataDisplayDelegate;
1131 this.profile = profile; 1066 this.profile = profile;
1132 profile.addEventListener(WebInspector.ProfileHeader.Events.UpdateStatus, thi s._updateStatus, this); 1067 profile.addEventListener(WebInspector.ProfileHeader.Events.UpdateStatus, thi s._updateStatus, this);
1133 if (profile.canSaveToFile()) 1068 if (profile.canSaveToFile())
1134 this._createSaveLink(); 1069 this._createSaveLink();
1135 else 1070 else
1136 profile.addEventListener(WebInspector.ProfileHeader.Events.ProfileReceiv ed, this._onProfileReceived, this); 1071 profile.addEventListener(WebInspector.ProfileHeader.Events.ProfileReceived , this._onProfileReceived, this);
1137 }; 1072 }
1138 1073
1139 WebInspector.ProfileSidebarTreeElement.prototype = { 1074 _createSaveLink() {
1140 _createSaveLink: function() 1075 this._saveLinkElement = this._titleContainer.createChild('span', 'save-link' );
1141 { 1076 this._saveLinkElement.textContent = WebInspector.UIString('Save');
1142 this._saveLinkElement = this._titleContainer.createChild("span", "save-l ink"); 1077 this._saveLinkElement.addEventListener('click', this._saveProfile.bind(this) , false);
1143 this._saveLinkElement.textContent = WebInspector.UIString("Save"); 1078 }
1144 this._saveLinkElement.addEventListener("click", this._saveProfile.bind(t his), false);
1145 },
1146 1079
1147 _onProfileReceived: function(event) 1080 _onProfileReceived(event) {
1148 { 1081 this._createSaveLink();
1149 this._createSaveLink(); 1082 }
1150 },
1151 1083
1152 /** 1084 /**
1153 * @param {!WebInspector.Event} event 1085 * @param {!WebInspector.Event} event
1154 */ 1086 */
1155 _updateStatus: function(event) 1087 _updateStatus(event) {
1156 { 1088 var statusUpdate = event.data;
1157 var statusUpdate = event.data; 1089 if (statusUpdate.subtitle !== null) {
1158 if (statusUpdate.subtitle !== null) { 1090 this._subtitleElement.textContent = statusUpdate.subtitle || '';
1159 this._subtitleElement.textContent = statusUpdate.subtitle || ""; 1091 this._titlesElement.classList.toggle('no-subtitle', !statusUpdate.subtitle );
1160 this._titlesElement.classList.toggle("no-subtitle", !statusUpdate.su btitle); 1092 }
1161 } 1093 if (typeof statusUpdate.wait === 'boolean' && this.listItemElement)
1162 if (typeof statusUpdate.wait === "boolean" && this.listItemElement) 1094 this.listItemElement.classList.toggle('wait', statusUpdate.wait);
1163 this.listItemElement.classList.toggle("wait", statusUpdate.wait); 1095 }
1164 },
1165 1096
1166 dispose: function() 1097 dispose() {
1167 { 1098 this.profile.removeEventListener(WebInspector.ProfileHeader.Events.UpdateSta tus, this._updateStatus, this);
1168 this.profile.removeEventListener(WebInspector.ProfileHeader.Events.Updat eStatus, this._updateStatus, this); 1099 this.profile.removeEventListener(WebInspector.ProfileHeader.Events.ProfileRe ceived, this._onProfileReceived, this);
1169 this.profile.removeEventListener(WebInspector.ProfileHeader.Events.Profi leReceived, this._onProfileReceived, this); 1100 }
1170 },
1171 1101
1172 /** 1102 /**
1173 * @override 1103 * @override
1174 * @return {boolean} 1104 * @return {boolean}
1175 */ 1105 */
1176 onselect: function() 1106 onselect() {
1177 { 1107 this._dataDisplayDelegate.showProfile(this.profile);
1178 this._dataDisplayDelegate.showProfile(this.profile); 1108 return true;
1179 return true; 1109 }
1180 },
1181 1110
1182 /** 1111 /**
1183 * @override 1112 * @override
1184 * @return {boolean} 1113 * @return {boolean}
1185 */ 1114 */
1186 ondelete: function() 1115 ondelete() {
1187 { 1116 this.profile.profileType().removeProfile(this.profile);
1188 this.profile.profileType().removeProfile(this.profile); 1117 return true;
1189 return true; 1118 }
1190 },
1191 1119
1192 /** 1120 /**
1193 * @override 1121 * @override
1194 */ 1122 */
1195 onattach: function() 1123 onattach() {
1196 { 1124 if (this._className)
1197 if (this._className) 1125 this.listItemElement.classList.add(this._className);
1198 this.listItemElement.classList.add(this._className); 1126 if (this._small)
1199 if (this._small) 1127 this.listItemElement.classList.add('small');
1200 this.listItemElement.classList.add("small"); 1128 this.listItemElement.appendChildren(this._iconElement, this._titlesElement);
1201 this.listItemElement.appendChildren(this._iconElement, this._titlesEleme nt); 1129 this.listItemElement.addEventListener('contextmenu', this._handleContextMenu Event.bind(this), true);
1202 this.listItemElement.addEventListener("contextmenu", this._handleContext MenuEvent.bind(this), true); 1130 }
1203 },
1204 1131
1205 /** 1132 /**
1206 * @param {!Event} event 1133 * @param {!Event} event
1207 */ 1134 */
1208 _handleContextMenuEvent: function(event) 1135 _handleContextMenuEvent(event) {
1209 { 1136 var profile = this.profile;
1210 var profile = this.profile; 1137 var contextMenu = new WebInspector.ContextMenu(event);
1211 var contextMenu = new WebInspector.ContextMenu(event); 1138 // FIXME: use context menu provider
1212 // FIXME: use context menu provider 1139 contextMenu.appendItem(
1213 contextMenu.appendItem(WebInspector.UIString("Load\u2026"), WebInspector .ProfilesPanel._fileSelectorElement.click.bind(WebInspector.ProfilesPanel._fileS electorElement)); 1140 WebInspector.UIString('Load\u2026'),
1214 if (profile.canSaveToFile()) 1141 WebInspector.ProfilesPanel._fileSelectorElement.click.bind(WebInspector. ProfilesPanel._fileSelectorElement));
1215 contextMenu.appendItem(WebInspector.UIString("Save\u2026"), profile. saveToFile.bind(profile)); 1142 if (profile.canSaveToFile())
1216 contextMenu.appendItem(WebInspector.UIString("Delete"), this.ondelete.bi nd(this)); 1143 contextMenu.appendItem(WebInspector.UIString('Save\u2026'), profile.saveTo File.bind(profile));
1217 contextMenu.show(); 1144 contextMenu.appendItem(WebInspector.UIString('Delete'), this.ondelete.bind(t his));
1218 }, 1145 contextMenu.show();
1146 }
1219 1147
1220 _saveProfile: function(event) 1148 _saveProfile(event) {
1221 { 1149 this.profile.saveToFile();
1222 this.profile.saveToFile(); 1150 }
1223 },
1224 1151
1225 /** 1152 /**
1226 * @param {boolean} small 1153 * @param {boolean} small
1227 */ 1154 */
1228 setSmall: function(small) 1155 setSmall(small) {
1229 { 1156 this._small = small;
1230 this._small = small; 1157 if (this.listItemElement)
1231 if (this.listItemElement) 1158 this.listItemElement.classList.toggle('small', this._small);
1232 this.listItemElement.classList.toggle("small", this._small); 1159 }
1233 },
1234 1160
1235 /** 1161 /**
1236 * @param {string} title 1162 * @param {string} title
1237 */ 1163 */
1238 setMainTitle: function(title) 1164 setMainTitle(title) {
1239 { 1165 this._titleElement.textContent = title;
1240 this._titleElement.textContent = title; 1166 }
1241 },
1242
1243 __proto__: TreeElement.prototype
1244 }; 1167 };
1245 1168
1246 /** 1169 /**
1247 * @constructor 1170 * @unrestricted
1248 * @extends {TreeElement}
1249 * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
1250 * @param {string} title
1251 */ 1171 */
1252 WebInspector.ProfileGroupSidebarTreeElement = function(dataDisplayDelegate, titl e) 1172 WebInspector.ProfileGroupSidebarTreeElement = class extends TreeElement {
1253 { 1173 /**
1254 TreeElement.call(this, "", true); 1174 * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
1175 * @param {string} title
1176 */
1177 constructor(dataDisplayDelegate, title) {
1178 super('', true);
1255 this.selectable = false; 1179 this.selectable = false;
1256 this._dataDisplayDelegate = dataDisplayDelegate; 1180 this._dataDisplayDelegate = dataDisplayDelegate;
1257 this._title = title; 1181 this._title = title;
1258 this.expand(); 1182 this.expand();
1259 this.toggleOnClick = true; 1183 this.toggleOnClick = true;
1260 }; 1184 }
1261 1185
1262 WebInspector.ProfileGroupSidebarTreeElement.prototype = { 1186 /**
1263 /** 1187 * @override
1264 * @override 1188 * @return {boolean}
1265 * @return {boolean} 1189 */
1266 */ 1190 onselect() {
1267 onselect: function() 1191 var hasChildren = this.childCount() > 0;
1268 { 1192 if (hasChildren)
1269 var hasChildren = this.childCount() > 0; 1193 this._dataDisplayDelegate.showProfile(this.lastChild().profile);
1270 if (hasChildren) 1194 return hasChildren;
1271 this._dataDisplayDelegate.showProfile(this.lastChild().profile); 1195 }
1272 return hasChildren;
1273 },
1274 1196
1275 /** 1197 /**
1276 * @override 1198 * @override
1277 */ 1199 */
1278 onattach: function() 1200 onattach() {
1279 { 1201 this.listItemElement.classList.add('profile-group-sidebar-tree-item');
1280 this.listItemElement.classList.add("profile-group-sidebar-tree-item"); 1202 this.listItemElement.createChild('div', 'icon');
1281 this.listItemElement.createChild("div", "icon"); 1203 this.listItemElement.createChild('div', 'titles no-subtitle')
1282 this.listItemElement.createChild("div", "titles no-subtitle").createChil d("span", "title-container").createChild("span", "title").textContent = this._ti tle; 1204 .createChild('span', 'title-container')
1283 }, 1205 .createChild('span', 'title')
1284 1206 .textContent = this._title;
1285 __proto__: TreeElement.prototype 1207 }
1286 }; 1208 };
1287 1209
1288 /** 1210 /**
1289 * @constructor 1211 * @unrestricted
1290 * @extends {TreeElement}
1291 * @param {!WebInspector.ProfilesPanel} panel
1292 */ 1212 */
1293 WebInspector.ProfilesSidebarTreeElement = function(panel) 1213 WebInspector.ProfilesSidebarTreeElement = class extends TreeElement {
1294 { 1214 /**
1295 TreeElement.call(this, "", false); 1215 * @param {!WebInspector.ProfilesPanel} panel
1216 */
1217 constructor(panel) {
1218 super('', false);
1296 this.selectable = true; 1219 this.selectable = true;
1297 this._panel = panel; 1220 this._panel = panel;
1221 }
1222
1223 /**
1224 * @override
1225 * @return {boolean}
1226 */
1227 onselect() {
1228 this._panel._showLauncherView();
1229 return true;
1230 }
1231
1232 /**
1233 * @override
1234 */
1235 onattach() {
1236 this.listItemElement.classList.add('profile-launcher-view-tree-item');
1237 this.listItemElement.createChild('div', 'icon');
1238 this.listItemElement.createChild('div', 'titles no-subtitle')
1239 .createChild('span', 'title-container')
1240 .createChild('span', 'title')
1241 .textContent = WebInspector.UIString('Profiles');
1242 }
1298 }; 1243 };
1299 1244
1300 WebInspector.ProfilesSidebarTreeElement.prototype = {
1301 /**
1302 * @override
1303 * @return {boolean}
1304 */
1305 onselect: function()
1306 {
1307 this._panel._showLauncherView();
1308 return true;
1309 },
1310
1311 /**
1312 * @override
1313 */
1314 onattach: function()
1315 {
1316 this.listItemElement.classList.add("profile-launcher-view-tree-item");
1317 this.listItemElement.createChild("div", "icon");
1318 this.listItemElement.createChild("div", "titles no-subtitle").createChil d("span", "title-container").createChild("span", "title").textContent = WebInspe ctor.UIString("Profiles");
1319 },
1320
1321 __proto__: TreeElement.prototype
1322 };
1323 1245
1324 /** 1246 /**
1325 * @return {!WebInspector.ProfilesPanel} 1247 * @implements {WebInspector.ActionDelegate}
1248 * @unrestricted
1326 */ 1249 */
1327 WebInspector.ProfilesPanel._instance = function() 1250 WebInspector.ProfilesPanel.RecordActionDelegate = class {
1328 { 1251 /**
1329 return /** @type {!WebInspector.ProfilesPanel} */ (self.runtime.sharedInstan ce(WebInspector.ProfilesPanel)); 1252 * @override
1253 * @param {!WebInspector.Context} context
1254 * @param {string} actionId
1255 * @return {boolean}
1256 */
1257 handleAction(context, actionId) {
1258 var panel = WebInspector.context.flavor(WebInspector.ProfilesPanel);
1259 console.assert(panel && panel instanceof WebInspector.ProfilesPanel);
1260 panel.toggleRecord();
1261 return true;
1262 }
1330 }; 1263 };
1331
1332 /**
1333 * @constructor
1334 * @implements {WebInspector.ActionDelegate}
1335 */
1336 WebInspector.ProfilesPanel.RecordActionDelegate = function()
1337 {
1338 };
1339
1340 WebInspector.ProfilesPanel.RecordActionDelegate.prototype = {
1341 /**
1342 * @override
1343 * @param {!WebInspector.Context} context
1344 * @param {string} actionId
1345 * @return {boolean}
1346 */
1347 handleAction: function(context, actionId)
1348 {
1349 var panel = WebInspector.context.flavor(WebInspector.ProfilesPanel);
1350 console.assert(panel && panel instanceof WebInspector.ProfilesPanel);
1351 panel.toggleRecord();
1352 return true;
1353 }
1354 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698