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

Side by Side Diff: chrome_frame/tools/test/reference_build/chrome/resources/inspector/ProfilesPanel.js

Issue 218019: Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 11 years, 3 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
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.ProfilesPanel = function()
29 {
30 WebInspector.Panel.call(this);
31
32 this.element.addStyleClass("profiles");
33
34 var panelEnablerHeading = WebInspector.UIString("You need to enable profilin g before you can use the Profiles panel.");
35 var panelEnablerDisclaimer = WebInspector.UIString("Enabling profiling will make scripts run slower.");
36 var panelEnablerButton = WebInspector.UIString("Enable Profiling");
37 this.panelEnablerView = new WebInspector.PanelEnablerView("profiles", panelE nablerHeading, panelEnablerDisclaimer, panelEnablerButton);
38 this.panelEnablerView.addEventListener("enable clicked", this._enableProfili ng, this);
39
40 this.element.appendChild(this.panelEnablerView.element);
41
42 this.sidebarElement = document.createElement("div");
43 this.sidebarElement.id = "profiles-sidebar";
44 this.sidebarElement.className = "sidebar";
45 this.element.appendChild(this.sidebarElement);
46
47 this.sidebarResizeElement = document.createElement("div");
48 this.sidebarResizeElement.className = "sidebar-resizer-vertical";
49 this.sidebarResizeElement.addEventListener("mousedown", this._startSidebarDr agging.bind(this), false);
50 this.element.appendChild(this.sidebarResizeElement);
51
52 this.sidebarTreeElement = document.createElement("ol");
53 this.sidebarTreeElement.className = "sidebar-tree";
54 this.sidebarElement.appendChild(this.sidebarTreeElement);
55
56 this.sidebarTree = new TreeOutline(this.sidebarTreeElement);
57
58 this.profilesListTreeElement = new WebInspector.SidebarSectionTreeElement(We bInspector.UIString("CPU PROFILES"), null, true);
59 this.sidebarTree.appendChild(this.profilesListTreeElement);
60 this.profilesListTreeElement.expand();
61
62 this.snapshotsListTreeElement = new WebInspector.SidebarSectionTreeElement(W ebInspector.UIString("HEAP SNAPSHOTS"), null, true);
63 if (Preferences.heapProfilerPresent) {
64 this.sidebarTree.appendChild(this.snapshotsListTreeElement);
65 this.snapshotsListTreeElement.expand();
66 }
67
68 this.profileViews = document.createElement("div");
69 this.profileViews.id = "profile-views";
70 this.element.appendChild(this.profileViews);
71
72 this.enableToggleButton = new WebInspector.StatusBarButton("", "enable-toggl e-status-bar-item");
73 this.enableToggleButton.addEventListener("click", this._toggleProfiling.bind (this), false);
74
75 this.recordButton = new WebInspector.StatusBarButton(WebInspector.UIString(" Start profiling."), "record-profile-status-bar-item");
76 this.recordButton.addEventListener("click", this._recordClicked.bind(this), false);
77
78 this.recording = false;
79
80 this.snapshotButton = new WebInspector.StatusBarButton(WebInspector.UIString ("Take heap snapshot."), "heap-snapshot-status-bar-item");
81 this.snapshotButton.visible = Preferences.heapProfilerPresent;
82 this.snapshotButton.addEventListener("click", this._snapshotClicked.bind(thi s), false);
83
84 this.profileViewStatusBarItemsContainer = document.createElement("div");
85 this.profileViewStatusBarItemsContainer.id = "profile-view-status-bar-items" ;
86
87 this.reset();
88 }
89
90 WebInspector.ProfilesPanel.prototype = {
91 toolbarItemClass: "profiles",
92
93 get toolbarItemLabel()
94 {
95 return WebInspector.UIString("Profiles");
96 },
97
98 get statusBarItems()
99 {
100 return [this.enableToggleButton.element, this.recordButton.element, this .snapshotButton.element, this.profileViewStatusBarItemsContainer];
101 },
102
103 show: function()
104 {
105 WebInspector.Panel.prototype.show.call(this);
106 this._updateSidebarWidth();
107 if (this._shouldPopulateProfiles)
108 this._populateProfiles();
109 },
110
111 populateInterface: function()
112 {
113 if (this.visible)
114 this._populateProfiles();
115 else
116 this._shouldPopulateProfiles = true;
117 },
118
119 profilerWasEnabled: function()
120 {
121 this.reset();
122 this.populateInterface();
123 },
124
125 profilerWasDisabled: function()
126 {
127 this.reset();
128 },
129
130 reset: function()
131 {
132 if (this._profiles) {
133 var profiledLength = this._profiles.length;
134 for (var i = 0; i < profiledLength; ++i) {
135 var profile = this._profiles[i];
136 delete profile._profileView;
137 }
138 }
139
140 delete this.currentQuery;
141 this.searchCanceled();
142
143 this._profiles = [];
144 this._profilesIdMap = {};
145 this._profileGroups = {};
146 this._profileGroupsForLinks = {}
147
148 this.sidebarTreeElement.removeStyleClass("some-expandable");
149
150 this.profilesListTreeElement.removeChildren();
151 this.snapshotsListTreeElement.removeChildren();
152 this.profileViews.removeChildren();
153
154 this.profileViewStatusBarItemsContainer.removeChildren();
155
156 this._updateInterface();
157 },
158
159 handleKeyEvent: function(event)
160 {
161 this.sidebarTree.handleKeyEvent(event);
162 },
163
164 addProfile: function(profile)
165 {
166 this._profiles.push(profile);
167 this._profilesIdMap[profile.uid] = profile;
168
169 var sidebarParent = this.profilesListTreeElement;
170 var small = false;
171 var alternateTitle;
172
173 if (profile.title.indexOf(UserInitiatedProfileName) !== 0) {
174 if (!(profile.title in this._profileGroups))
175 this._profileGroups[profile.title] = [];
176
177 var group = this._profileGroups[profile.title];
178 group.push(profile);
179
180 if (group.length === 2) {
181 // Make a group TreeElement now that there are 2 profiles.
182 group._profilesTreeElement = new WebInspector.ProfileGroupSideba rTreeElement(profile.title);
183
184 // Insert at the same index for the first profile of the group.
185 var index = this.sidebarTree.children.indexOf(group[0]._profiles TreeElement);
186 this.sidebarTree.insertChild(group._profilesTreeElement, index);
187
188 // Move the first profile to the group.
189 var selected = group[0]._profilesTreeElement.selected;
190 this.sidebarTree.removeChild(group[0]._profilesTreeElement);
191 group._profilesTreeElement.appendChild(group[0]._profilesTreeEle ment);
192 if (selected) {
193 group[0]._profilesTreeElement.select();
194 group[0]._profilesTreeElement.reveal();
195 }
196
197 group[0]._profilesTreeElement.small = true;
198 group[0]._profilesTreeElement.mainTitle = WebInspector.UIString( "Run %d", 1);
199
200 this.sidebarTreeElement.addStyleClass("some-expandable");
201 }
202
203 if (group.length >= 2) {
204 sidebarParent = group._profilesTreeElement;
205 alternateTitle = WebInspector.UIString("Run %d", group.length);
206 small = true;
207 }
208 }
209
210 var profileTreeElement = new WebInspector.ProfileSidebarTreeElement(prof ile);
211 profileTreeElement.small = small;
212 if (alternateTitle)
213 profileTreeElement.mainTitle = alternateTitle;
214 profile._profilesTreeElement = profileTreeElement;
215
216 sidebarParent.appendChild(profileTreeElement);
217 },
218
219 showProfile: function(profile)
220 {
221 if (!profile)
222 return;
223
224 if (this.visibleView)
225 this.visibleView.hide();
226
227 var view = this.profileViewForProfile(profile);
228
229 view.show(this.profileViews);
230
231 profile._profilesTreeElement.select(true);
232 profile._profilesTreeElement.reveal();
233
234 this.visibleView = view;
235
236 this.profileViewStatusBarItemsContainer.removeChildren();
237
238 var statusBarItems = view.statusBarItems;
239 for (var i = 0; i < statusBarItems.length; ++i)
240 this.profileViewStatusBarItemsContainer.appendChild(statusBarItems[i ]);
241 },
242
243 showView: function(view)
244 {
245 this.showProfile(view.profile);
246 },
247
248 profileViewForProfile: function(profile)
249 {
250 if (!profile)
251 return null;
252 if (!profile._profileView)
253 profile._profileView = new WebInspector.ProfileView(profile);
254 return profile._profileView;
255 },
256
257 showProfileById: function(uid)
258 {
259 this.showProfile(this._profilesIdMap[uid]);
260 },
261
262 closeVisibleView: function()
263 {
264 if (this.visibleView)
265 this.visibleView.hide();
266 delete this.visibleView;
267 },
268
269 displayTitleForProfileLink: function(title)
270 {
271 title = unescape(title);
272 if (title.indexOf(UserInitiatedProfileName) === 0) {
273 title = WebInspector.UIString("Profile %d", title.substring(UserInit iatedProfileName.length + 1));
274 } else {
275 if (!(title in this._profileGroupsForLinks))
276 this._profileGroupsForLinks[title] = 0;
277
278 groupNumber = ++this._profileGroupsForLinks[title];
279
280 if (groupNumber > 2)
281 // The title is used in the console message announcing that a pr ofile has started so it gets
282 // incremented twice as often as it's displayed
283 title += " " + WebInspector.UIString("Run %d", groupNumber / 2);
284 }
285
286 return title;
287 },
288
289 get searchableViews()
290 {
291 var views = [];
292
293 const visibleView = this.visibleView;
294 if (visibleView && visibleView.performSearch)
295 views.push(visibleView);
296
297 var profilesLength = this._profiles.length;
298 for (var i = 0; i < profilesLength; ++i) {
299 var view = this.profileViewForProfile(this._profiles[i]);
300 if (!view.performSearch || view === visibleView)
301 continue;
302 views.push(view);
303 }
304
305 return views;
306 },
307
308 searchMatchFound: function(view, matches)
309 {
310 view.profile._profilesTreeElement.searchMatches = matches;
311 },
312
313 searchCanceled: function(startingNewSearch)
314 {
315 WebInspector.Panel.prototype.searchCanceled.call(this, startingNewSearch );
316
317 if (!this._profiles)
318 return;
319
320 for (var i = 0; i < this._profiles.length; ++i) {
321 var profile = this._profiles[i];
322 profile._profilesTreeElement.searchMatches = 0;
323 }
324 },
325
326 setRecordingProfile: function(isProfiling)
327 {
328 this.recording = isProfiling;
329
330 if (isProfiling) {
331 this.recordButton.toggled = true;
332 this.recordButton.title = WebInspector.UIString("Stop profiling.");
333 } else {
334 this.recordButton.toggled = false;
335 this.recordButton.title = WebInspector.UIString("Start profiling.");
336 }
337 },
338
339 resize: function()
340 {
341 var visibleView = this.visibleView;
342 if (visibleView && "resize" in visibleView)
343 visibleView.resize();
344 },
345
346 _updateInterface: function()
347 {
348 if (InspectorController.profilerEnabled()) {
349 this.enableToggleButton.title = WebInspector.UIString("Profiling ena bled. Click to disable.");
350 this.enableToggleButton.toggled = true;
351 this.recordButton.visible = true;
352 if (Preferences.heapProfilerPresent)
353 this.snapshotButton.visible = true;
354 this.profileViewStatusBarItemsContainer.removeStyleClass("hidden");
355 this.panelEnablerView.visible = false;
356 } else {
357 this.enableToggleButton.title = WebInspector.UIString("Profiling dis abled. Click to enable.");
358 this.enableToggleButton.toggled = false;
359 this.recordButton.visible = false;
360 this.snapshotButton.visible = false;
361 this.profileViewStatusBarItemsContainer.addStyleClass("hidden");
362 this.panelEnablerView.visible = true;
363 }
364 },
365
366 _recordClicked: function()
367 {
368 this.recording = !this.recording;
369
370 if (this.recording)
371 InspectorController.startProfiling();
372 else
373 InspectorController.stopProfiling();
374 },
375
376 _snapshotClicked: function()
377 {
378 InspectorController.takeHeapSnapshot();
379 },
380
381 _enableProfiling: function()
382 {
383 if (InspectorController.profilerEnabled())
384 return;
385 this._toggleProfiling(this.panelEnablerView.alwaysEnabled);
386 },
387
388 _toggleProfiling: function(optionalAlways)
389 {
390 if (InspectorController.profilerEnabled())
391 InspectorController.disableProfiler(true);
392 else
393 InspectorController.enableProfiler(!!optionalAlways);
394 },
395
396 _populateProfiles: function()
397 {
398 if (this.sidebarTree.children.length)
399 return;
400
401 var profiles = InspectorController.profiles();
402 var profilesLength = profiles.length;
403 for (var i = 0; i < profilesLength; ++i) {
404 var profile = profiles[i];
405 this.addProfile(profile);
406 }
407
408 if (this.sidebarTree.children[0])
409 this.sidebarTree.children[0].select();
410
411 delete this._shouldPopulateProfiles;
412 },
413
414 _startSidebarDragging: function(event)
415 {
416 WebInspector.elementDragStart(this.sidebarResizeElement, this._sidebarDr agging.bind(this), this._endSidebarDragging.bind(this), event, "col-resize");
417 },
418
419 _sidebarDragging: function(event)
420 {
421 this._updateSidebarWidth(event.pageX);
422
423 event.preventDefault();
424 },
425
426 _endSidebarDragging: function(event)
427 {
428 WebInspector.elementDragEnd(event);
429 },
430
431 _updateSidebarWidth: function(width)
432 {
433 if (this.sidebarElement.offsetWidth <= 0) {
434 // The stylesheet hasn't loaded yet or the window is closed,
435 // so we can't calculate what is need. Return early.
436 return;
437 }
438
439 if (!("_currentSidebarWidth" in this))
440 this._currentSidebarWidth = this.sidebarElement.offsetWidth;
441
442 if (typeof width === "undefined")
443 width = this._currentSidebarWidth;
444
445 width = Number.constrain(width, Preferences.minSidebarWidth, window.inne rWidth / 2);
446
447 this._currentSidebarWidth = width;
448
449 this.sidebarElement.style.width = width + "px";
450 this.profileViews.style.left = width + "px";
451 this.profileViewStatusBarItemsContainer.style.left = width + "px";
452 this.sidebarResizeElement.style.left = (width - 3) + "px";
453
454 var visibleView = this.visibleView;
455 if (visibleView && "resize" in visibleView)
456 visibleView.resize();
457 }
458 }
459
460 WebInspector.ProfilesPanel.prototype.__proto__ = WebInspector.Panel.prototype;
461
462 WebInspector.ProfileSidebarTreeElement = function(profile)
463 {
464 this.profile = profile;
465
466 if (this.profile.title.indexOf(UserInitiatedProfileName) === 0)
467 this._profileNumber = this.profile.title.substring(UserInitiatedProfileN ame.length + 1);
468
469 WebInspector.SidebarTreeElement.call(this, "profile-sidebar-tree-item", "", "", profile, false);
470
471 this.refreshTitles();
472 }
473
474 WebInspector.ProfileSidebarTreeElement.prototype = {
475 onselect: function()
476 {
477 WebInspector.panels.profiles.showProfile(this.profile);
478 },
479
480 get mainTitle()
481 {
482 if (this._mainTitle)
483 return this._mainTitle;
484 if (this.profile.title.indexOf(UserInitiatedProfileName) === 0)
485 return WebInspector.UIString("Profile %d", this._profileNumber);
486 return this.profile.title;
487 },
488
489 set mainTitle(x)
490 {
491 this._mainTitle = x;
492 this.refreshTitles();
493 },
494
495 get subtitle()
496 {
497 // There is no subtitle.
498 },
499
500 set subtitle(x)
501 {
502 // Can't change subtitle.
503 },
504
505 set searchMatches(matches)
506 {
507 if (!matches) {
508 if (!this.bubbleElement)
509 return;
510 this.bubbleElement.removeStyleClass("search-matches");
511 this.bubbleText = "";
512 return;
513 }
514
515 this.bubbleText = matches;
516 this.bubbleElement.addStyleClass("search-matches");
517 }
518 }
519
520 WebInspector.ProfileSidebarTreeElement.prototype.__proto__ = WebInspector.Sideba rTreeElement.prototype;
521
522 WebInspector.ProfileGroupSidebarTreeElement = function(title, subtitle)
523 {
524 WebInspector.SidebarTreeElement.call(this, "profile-group-sidebar-tree-item" , title, subtitle, null, true);
525 }
526
527 WebInspector.ProfileGroupSidebarTreeElement.prototype = {
528 onselect: function()
529 {
530 WebInspector.panels.profiles.showProfile(this.children[this.children.len gth - 1].profile);
531 }
532 }
533
534 WebInspector.ProfileGroupSidebarTreeElement.prototype.__proto__ = WebInspector.S idebarTreeElement.prototype;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698