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

Side by Side Diff: resources/inspector/ProfilesPanel.js

Issue 853002: Updating the Chromium reference build for Windows. The continuous... (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/reference_builds/chrome/
Patch Set: Added the symbol files back. Created 10 years, 9 months 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 | Annotate | Revision Log
« no previous file with comments | « resources/inspector/ProfileView.js ('k') | resources/inspector/PropertiesSection.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2008 Apple 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
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
24 */
25
26 const UserInitiatedProfileName = "org.webkit.profiles.user-initiated";
27
28 WebInspector.ProfileType = function(id, name)
29 {
30 this._id = id;
31 this._name = name;
32 }
33
34 WebInspector.ProfileType.URLRegExp = /webkit-profile:\/\/(.+)\/(.+)#([0-9]+)/;
35
36 WebInspector.ProfileType.prototype = {
37 get buttonTooltip()
38 {
39 return "";
40 },
41
42 get buttonStyle()
43 {
44 return undefined;
45 },
46
47 get buttonCaption()
48 {
49 return this.name;
50 },
51
52 get id()
53 {
54 return this._id;
55 },
56
57 get name()
58 {
59 return this._name;
60 },
61
62 buttonClicked: function()
63 {
64 },
65
66 viewForProfile: function(profile)
67 {
68 if (!profile._profileView)
69 profile._profileView = this.createView(profile);
70 return profile._profileView;
71 },
72
73 // Must be implemented by subclasses.
74 createView: function(profile)
75 {
76 throw new Error("Needs implemented.");
77 },
78
79 // Must be implemented by subclasses.
80 createSidebarTreeElementForProfile: function(profile)
81 {
82 throw new Error("Needs implemented.");
83 }
84 }
85
86 WebInspector.ProfilesPanel = function()
87 {
88 WebInspector.Panel.call(this, true);
89
90 this.element.addStyleClass("profiles");
91 this._profileTypesByIdMap = {};
92 this._profileTypeButtonsByIdMap = {};
93
94 var panelEnablerHeading = WebInspector.UIString("You need to enable profilin g before you can use the Profiles panel.");
95 var panelEnablerDisclaimer = WebInspector.UIString("Enabling profiling will make scripts run slower.");
96 var panelEnablerButton = WebInspector.UIString("Enable Profiling");
97 this.panelEnablerView = new WebInspector.PanelEnablerView("profiles", panelE nablerHeading, panelEnablerDisclaimer, panelEnablerButton);
98 this.panelEnablerView.addEventListener("enable clicked", this._enableProfili ng, this);
99
100 this.element.appendChild(this.panelEnablerView.element);
101
102 this.profileViews = document.createElement("div");
103 this.profileViews.id = "profile-views";
104 this.element.appendChild(this.profileViews);
105
106 this.enableToggleButton = new WebInspector.StatusBarButton("", "enable-toggl e-status-bar-item");
107 this.enableToggleButton.addEventListener("click", this._toggleProfiling.bind (this), false);
108
109 this.profileViewStatusBarItemsContainer = document.createElement("div");
110 this.profileViewStatusBarItemsContainer.id = "profile-view-status-bar-items" ;
111
112 this._profiles = [];
113 this.reset();
114 }
115
116 WebInspector.ProfilesPanel.prototype = {
117 toolbarItemClass: "profiles",
118
119 get toolbarItemLabel()
120 {
121 return WebInspector.UIString("Profiles");
122 },
123
124 get statusBarItems()
125 {
126 function clickHandler(profileType, buttonElement)
127 {
128 profileType.buttonClicked.call(profileType);
129 this.updateProfileTypeButtons();
130 }
131
132 var items = [this.enableToggleButton.element];
133 // FIXME: Generate a single "combo-button".
134 for (var typeId in this._profileTypesByIdMap) {
135 var profileType = this.getProfileType(typeId);
136 if (profileType.buttonStyle) {
137 var button = new WebInspector.StatusBarButton(profileType.button Tooltip, profileType.buttonStyle, profileType.buttonCaption);
138 this._profileTypeButtonsByIdMap[typeId] = button.element;
139 button.element.addEventListener("click", clickHandler.bind(this, profileType, button.element), false);
140 items.push(button.element);
141 }
142 }
143 items.push(this.profileViewStatusBarItemsContainer);
144 return items;
145 },
146
147 show: function()
148 {
149 WebInspector.Panel.prototype.show.call(this);
150 if (this._shouldPopulateProfiles)
151 this._populateProfiles();
152 },
153
154 populateInterface: function()
155 {
156 if (this.visible)
157 this._populateProfiles();
158 else
159 this._shouldPopulateProfiles = true;
160 },
161
162 profilerWasEnabled: function()
163 {
164 this.reset();
165 this.populateInterface();
166 },
167
168 profilerWasDisabled: function()
169 {
170 this.reset();
171 },
172
173 reset: function()
174 {
175 for (var i = 0; i < this._profiles.length; ++i)
176 delete this._profiles[i]._profileView;
177
178 delete this.currentQuery;
179 this.searchCanceled();
180
181 this._profiles = [];
182 this._profilesIdMap = {};
183 this._profileGroups = {};
184 this._profileGroupsForLinks = {}
185
186 this.sidebarTreeElement.removeStyleClass("some-expandable");
187
188 for (var typeId in this._profileTypesByIdMap)
189 this.getProfileType(typeId).treeElement.removeChildren();
190
191 this.profileViews.removeChildren();
192
193 this.profileViewStatusBarItemsContainer.removeChildren();
194
195 this._updateInterface();
196 },
197
198 registerProfileType: function(profileType)
199 {
200 this._profileTypesByIdMap[profileType.id] = profileType;
201 profileType.treeElement = new WebInspector.SidebarSectionTreeElement(pro fileType.name, null, true);
202 this.sidebarTree.appendChild(profileType.treeElement);
203 profileType.treeElement.expand();
204 },
205
206 _makeKey: function(text, profileTypeId)
207 {
208 return escape(text) + '/' + escape(profileTypeId);
209 },
210
211 addProfileHeader: function(typeId, profile)
212 {
213 var profileType = this.getProfileType(typeId);
214 var sidebarParent = profileType.treeElement;
215 var small = false;
216 var alternateTitle;
217
218 profile.__profilesPanelProfileType = profileType;
219 this._profiles.push(profile);
220 this._profilesIdMap[this._makeKey(profile.uid, typeId)] = profile;
221
222 if (profile.title.indexOf(UserInitiatedProfileName) !== 0) {
223 var profileTitleKey = this._makeKey(profile.title, typeId);
224 if (!(profileTitleKey in this._profileGroups))
225 this._profileGroups[profileTitleKey] = [];
226
227 var group = this._profileGroups[profileTitleKey];
228 group.push(profile);
229
230 if (group.length === 2) {
231 // Make a group TreeElement now that there are 2 profiles.
232 group._profilesTreeElement = new WebInspector.ProfileGroupSideba rTreeElement(profile.title);
233
234 // Insert at the same index for the first profile of the group.
235 var index = sidebarParent.children.indexOf(group[0]._profilesTre eElement);
236 sidebarParent.insertChild(group._profilesTreeElement, index);
237
238 // Move the first profile to the group.
239 var selected = group[0]._profilesTreeElement.selected;
240 sidebarParent.removeChild(group[0]._profilesTreeElement);
241 group._profilesTreeElement.appendChild(group[0]._profilesTreeEle ment);
242 if (selected) {
243 group[0]._profilesTreeElement.select();
244 group[0]._profilesTreeElement.reveal();
245 }
246
247 group[0]._profilesTreeElement.small = true;
248 group[0]._profilesTreeElement.mainTitle = WebInspector.UIString( "Run %d", 1);
249
250 this.sidebarTreeElement.addStyleClass("some-expandable");
251 }
252
253 if (group.length >= 2) {
254 sidebarParent = group._profilesTreeElement;
255 alternateTitle = WebInspector.UIString("Run %d", group.length);
256 small = true;
257 }
258 }
259
260 var profileTreeElement = profileType.createSidebarTreeElementForProfile( profile);
261 profileTreeElement.small = small;
262 if (alternateTitle)
263 profileTreeElement.mainTitle = alternateTitle;
264 profile._profilesTreeElement = profileTreeElement;
265
266 sidebarParent.appendChild(profileTreeElement);
267 if (!this.visibleView)
268 this.showProfile(profile);
269 },
270
271 showProfile: function(profile)
272 {
273 if (!profile)
274 return;
275
276 if (this.visibleView)
277 this.visibleView.hide();
278
279 var view = profile.__profilesPanelProfileType.viewForProfile(profile);
280
281 view.show(this.profileViews);
282
283 profile._profilesTreeElement.select(true);
284 profile._profilesTreeElement.reveal();
285
286 this.visibleView = view;
287
288 this.profileViewStatusBarItemsContainer.removeChildren();
289
290 var statusBarItems = view.statusBarItems;
291 for (var i = 0; i < statusBarItems.length; ++i)
292 this.profileViewStatusBarItemsContainer.appendChild(statusBarItems[i ]);
293 },
294
295 showView: function(view)
296 {
297 this.showProfile(view.profile);
298 },
299
300 getProfileType: function(typeId)
301 {
302 return this._profileTypesByIdMap[typeId];
303 },
304
305 showProfileForURL: function(url)
306 {
307 var match = url.match(WebInspector.ProfileType.URLRegExp);
308 if (!match)
309 return;
310 this.showProfile(this._profilesIdMap[this._makeKey(match[3], match[1])]) ;
311 },
312
313 updateProfileTypeButtons: function()
314 {
315 for (var typeId in this._profileTypeButtonsByIdMap) {
316 var buttonElement = this._profileTypeButtonsByIdMap[typeId];
317 var profileType = this.getProfileType(typeId);
318 buttonElement.className = profileType.buttonStyle;
319 buttonElement.title = profileType.buttonTooltip;
320 // FIXME: Apply profileType.buttonCaption once captions are added to button controls.
321 }
322 },
323
324 closeVisibleView: function()
325 {
326 if (this.visibleView)
327 this.visibleView.hide();
328 delete this.visibleView;
329 },
330
331 displayTitleForProfileLink: function(title, typeId)
332 {
333 title = unescape(title);
334 if (title.indexOf(UserInitiatedProfileName) === 0) {
335 title = WebInspector.UIString("Profile %d", title.substring(UserInit iatedProfileName.length + 1));
336 } else {
337 var titleKey = this._makeKey(title, typeId);
338 if (!(titleKey in this._profileGroupsForLinks))
339 this._profileGroupsForLinks[titleKey] = 0;
340
341 groupNumber = ++this._profileGroupsForLinks[titleKey];
342
343 if (groupNumber > 2)
344 // The title is used in the console message announcing that a pr ofile has started so it gets
345 // incremented twice as often as it's displayed
346 title += " " + WebInspector.UIString("Run %d", groupNumber / 2);
347 }
348
349 return title;
350 },
351
352 get searchableViews()
353 {
354 var views = [];
355
356 const visibleView = this.visibleView;
357 if (visibleView && visibleView.performSearch)
358 views.push(visibleView);
359
360 var profilesLength = this._profiles.length;
361 for (var i = 0; i < profilesLength; ++i) {
362 var view = this._profiles[i].viewForProfile();
363 if (!view.performSearch || view === visibleView)
364 continue;
365 views.push(view);
366 }
367
368 return views;
369 },
370
371 searchMatchFound: function(view, matches)
372 {
373 view.profile._profilesTreeElement.searchMatches = matches;
374 },
375
376 searchCanceled: function(startingNewSearch)
377 {
378 WebInspector.Panel.prototype.searchCanceled.call(this, startingNewSearch );
379
380 if (!this._profiles)
381 return;
382
383 for (var i = 0; i < this._profiles.length; ++i) {
384 var profile = this._profiles[i];
385 profile._profilesTreeElement.searchMatches = 0;
386 }
387 },
388
389 resize: function()
390 {
391 var visibleView = this.visibleView;
392 if (visibleView && "resize" in visibleView)
393 visibleView.resize();
394 },
395
396 _updateInterface: function()
397 {
398 // FIXME: Replace ProfileType-specific button visibility changes by a si ngle ProfileType-agnostic "combo-button" visibility change.
399 if (InspectorController.profilerEnabled()) {
400 this.enableToggleButton.title = WebInspector.UIString("Profiling ena bled. Click to disable.");
401 this.enableToggleButton.toggled = true;
402 for (var typeId in this._profileTypeButtonsByIdMap)
403 this._profileTypeButtonsByIdMap[typeId].removeStyleClass("hidden ");
404 this.profileViewStatusBarItemsContainer.removeStyleClass("hidden");
405 this.panelEnablerView.visible = false;
406 } else {
407 this.enableToggleButton.title = WebInspector.UIString("Profiling dis abled. Click to enable.");
408 this.enableToggleButton.toggled = false;
409 for (var typeId in this._profileTypeButtonsByIdMap)
410 this._profileTypeButtonsByIdMap[typeId].addStyleClass("hidden");
411 this.profileViewStatusBarItemsContainer.addStyleClass("hidden");
412 this.panelEnablerView.visible = true;
413 }
414 },
415
416 _enableProfiling: function()
417 {
418 if (InspectorController.profilerEnabled())
419 return;
420 this._toggleProfiling(this.panelEnablerView.alwaysEnabled);
421 },
422
423 _toggleProfiling: function(optionalAlways)
424 {
425 if (InspectorController.profilerEnabled())
426 InspectorController.disableProfiler(true);
427 else
428 InspectorController.enableProfiler(!!optionalAlways);
429 },
430
431 _populateProfiles: function()
432 {
433 // FIXME: This code needs to be adjusted when more profiling types are a dded.
434 // Currently defaults to CPU profiles.
435 var cpuProfiles = this.getProfileType(WebInspector.CPUProfileType.TypeId ).treeElement;
436 if (cpuProfiles.children.length)
437 return;
438
439 function populateCallback(profileHeaders) {
440 profileHeaders.sort(function(a, b) { return a.uid - b.uid; });
441 var profileHeadersLength = profileHeaders.length;
442 for (var i = 0; i < profileHeadersLength; ++i)
443 WebInspector.addProfileHeader(profileHeaders[i]);
444 }
445
446 var callId = WebInspector.Callback.wrap(populateCallback);
447 InspectorController.getProfileHeaders(callId);
448
449 delete this._shouldPopulateProfiles;
450 },
451
452 setMainViewWidth: function(width)
453 {
454 this.profileViews.style.left = width + "px";
455 this.profileViewStatusBarItemsContainer.style.left = width + "px";
456 }
457 }
458
459 WebInspector.ProfilesPanel.prototype.__proto__ = WebInspector.Panel.prototype;
460
461 WebInspector.ProfileSidebarTreeElement = function(profile)
462 {
463 this.profile = profile;
464
465 if (this.profile.title.indexOf(UserInitiatedProfileName) === 0)
466 this._profileNumber = this.profile.title.substring(UserInitiatedProfileN ame.length + 1);
467
468 WebInspector.SidebarTreeElement.call(this, "profile-sidebar-tree-item", "", "", profile, false);
469
470 this.refreshTitles();
471 }
472
473 WebInspector.ProfileSidebarTreeElement.prototype = {
474 onselect: function()
475 {
476 WebInspector.panels.profiles.showProfile(this.profile);
477 },
478
479 get mainTitle()
480 {
481 if (this._mainTitle)
482 return this._mainTitle;
483 if (this.profile.title.indexOf(UserInitiatedProfileName) === 0)
484 return WebInspector.UIString("Profile %d", this._profileNumber);
485 return this.profile.title;
486 },
487
488 set mainTitle(x)
489 {
490 this._mainTitle = x;
491 this.refreshTitles();
492 },
493
494 get subtitle()
495 {
496 // There is no subtitle.
497 },
498
499 set subtitle(x)
500 {
501 // Can't change subtitle.
502 },
503
504 set searchMatches(matches)
505 {
506 if (!matches) {
507 if (!this.bubbleElement)
508 return;
509 this.bubbleElement.removeStyleClass("search-matches");
510 this.bubbleText = "";
511 return;
512 }
513
514 this.bubbleText = matches;
515 this.bubbleElement.addStyleClass("search-matches");
516 }
517 }
518
519 WebInspector.ProfileSidebarTreeElement.prototype.__proto__ = WebInspector.Sideba rTreeElement.prototype;
520
521 WebInspector.ProfileGroupSidebarTreeElement = function(title, subtitle)
522 {
523 WebInspector.SidebarTreeElement.call(this, "profile-group-sidebar-tree-item" , title, subtitle, null, true);
524 }
525
526 WebInspector.ProfileGroupSidebarTreeElement.prototype = {
527 onselect: function()
528 {
529 WebInspector.panels.profiles.showProfile(this.children[this.children.len gth - 1].profile);
530 }
531 }
532
533 WebInspector.ProfileGroupSidebarTreeElement.prototype.__proto__ = WebInspector.S idebarTreeElement.prototype;
534
535 WebInspector.didGetProfileHeaders = WebInspector.Callback.processCallback;
536 WebInspector.didGetProfile = WebInspector.Callback.processCallback;
OLDNEW
« no previous file with comments | « resources/inspector/ProfileView.js ('k') | resources/inspector/PropertiesSection.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698