blob: ecb6c8078a4224ec4ca7b550c701cb068a882f3f [file] [log] [blame]
joepeck@webkit.org56d9f282016-03-06 00:28:39 +00001/*
2 * Copyright (C) 2016 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. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
drousso@apple.com0b21e4c2017-08-02 03:09:57 +000026WI.ScriptProfileTimelineView = class ScriptProfileTimelineView extends WI.TimelineView
joepeck@webkit.org56d9f282016-03-06 00:28:39 +000027{
28 constructor(timeline, extraArguments)
29 {
30 super(timeline, extraArguments);
31
drousso@apple.com0b21e4c2017-08-02 03:09:57 +000032 console.assert(timeline.type === WI.TimelineRecord.Type.Script);
joepeck@webkit.org56d9f282016-03-06 00:28:39 +000033
34 this.element.classList.add("script");
35
36 this._recording = extraArguments.recording;
37
38 this._forceNextLayout = false;
39 this._lastLayoutStartTime = undefined;
40 this._lastLayoutEndTime = undefined;
41
commit-queue@webkit.org66635fc2016-07-14 21:42:42 +000042 this._sharedProfileViewData = {
43 selectedNodeHash: null,
44 };
45
drousso@apple.com0b21e4c2017-08-02 03:09:57 +000046 if (!WI.ScriptProfileTimelineView.profileOrientationSetting)
47 WI.ScriptProfileTimelineView.profileOrientationSetting = new WI.Setting("script-profile-timeline-view-profile-orientation-setting", WI.ScriptProfileTimelineView.ProfileOrientation.TopDown);
48 if (!WI.ScriptProfileTimelineView.profileTypeSetting)
49 WI.ScriptProfileTimelineView.profileTypeSetting = new WI.Setting("script-profile-timeline-view-profile-type-setting", WI.ScriptProfileTimelineView.ProfileViewType.Hierarchy);
joepeck@webkit.org56d9f282016-03-06 00:28:39 +000050
drousso@apple.com0b21e4c2017-08-02 03:09:57 +000051 this._showProfileViewForOrientation(WI.ScriptProfileTimelineView.profileOrientationSetting.value, WI.ScriptProfileTimelineView.profileTypeSetting.value);
joepeck@webkit.org56d9f282016-03-06 00:28:39 +000052
drousso@apple.com0b21e4c2017-08-02 03:09:57 +000053 let clearTooltip = WI.UIString("Clear focus");
54 this._clearFocusNodesButtonItem = new WI.ButtonNavigationItem("clear-profile-focus", clearTooltip, "Images/Close.svg", 16, 16);
55 this._clearFocusNodesButtonItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._clearFocusNodes, this);
joepeck@webkit.org56d9f282016-03-06 00:28:39 +000056 this._updateClearFocusNodesButtonItem();
57
drousso@apple.com0b21e4c2017-08-02 03:09:57 +000058 this._profileOrientationButton = new WI.TextToggleButtonNavigationItem("profile-orientation", WI.UIString("Inverted"));
59 this._profileOrientationButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._profileOrientationButtonClicked, this);
60 if (WI.ScriptProfileTimelineView.profileOrientationSetting.value === WI.ScriptProfileTimelineView.ProfileOrientation.TopDown)
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +000061 this._profileOrientationButton.activated = false;
62 else
63 this._profileOrientationButton.activated = true;
64
drousso@apple.com0b21e4c2017-08-02 03:09:57 +000065 this._topFunctionsButton = new WI.TextToggleButtonNavigationItem("top-functions", WI.UIString("Top Functions"));
66 this._topFunctionsButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._topFunctionsButtonClicked, this);
67 if (WI.ScriptProfileTimelineView.profileTypeSetting.value === WI.ScriptProfileTimelineView.ProfileViewType.Hierarchy)
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +000068 this._topFunctionsButton.activated = false;
69 else
70 this._topFunctionsButton.activated = true;
71
drousso@apple.com0b21e4c2017-08-02 03:09:57 +000072 timeline.addEventListener(WI.Timeline.Event.Refreshed, this._scriptTimelineRecordRefreshed, this);
joepeck@webkit.org56d9f282016-03-06 00:28:39 +000073 }
74
mattbaker@apple.comc1b3dbfd2016-05-09 14:52:19 +000075 // Public
76
timothy@apple.come00ac502016-05-16 17:41:41 +000077 get scrollableElements() { return this._profileView.scrollableElements; }
78
mattbaker@apple.comc1b3dbfd2016-05-09 14:52:19 +000079 get showsLiveRecordingData() { return false; }
80
joepeck@webkit.org56d9f282016-03-06 00:28:39 +000081 // Protected
82
83 closed()
84 {
drousso@apple.com0b21e4c2017-08-02 03:09:57 +000085 console.assert(this.representedObject instanceof WI.Timeline);
joepeck@webkit.org56d9f282016-03-06 00:28:39 +000086 this.representedObject.removeEventListener(null, null, this);
87 }
88
89 get navigationItems()
90 {
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +000091 return [this._clearFocusNodesButtonItem, this._profileOrientationButton, this._topFunctionsButton];
joepeck@webkit.org56d9f282016-03-06 00:28:39 +000092 }
93
94 get selectionPathComponents()
95 {
96 return this._profileView.selectionPathComponents;
97 }
98
99 layout()
100 {
101 if (!this._forceNextLayout && (this._lastLayoutStartTime === this.startTime && this._lastLayoutEndTime === this.endTime))
102 return;
103
104 this._forceNextLayout = false;
105 this._lastLayoutStartTime = this.startTime;
106 this._lastLayoutEndTime = this.endTime;
107
108 this._profileView.setStartAndEndTime(this.startTime, this.endTime);
109 }
110
111 // Private
112
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000113 _callingContextTreeForOrientation(profileOrientation, profileViewType)
joepeck@webkit.org56d9f282016-03-06 00:28:39 +0000114 {
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000115 switch (profileOrientation) {
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000116 case WI.ScriptProfileTimelineView.ProfileOrientation.TopDown:
117 return profileViewType === WI.ScriptProfileTimelineView.ProfileViewType.Hierarchy ? this._recording.topDownCallingContextTree : this._recording.topFunctionsTopDownCallingContextTree;
118 case WI.ScriptProfileTimelineView.ProfileOrientation.BottomUp:
119 return profileViewType === WI.ScriptProfileTimelineView.ProfileViewType.Hierarchy ? this._recording.bottomUpCallingContextTree : this._recording.topFunctionsBottomUpCallingContextTree;
joepeck@webkit.org56d9f282016-03-06 00:28:39 +0000120 }
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000121
122 console.assert(false, "Should not be reached.");
123 return this._recording.topDownCallingContextTree;
joepeck@webkit.org56d9f282016-03-06 00:28:39 +0000124 }
125
126 _profileViewSelectionPathComponentsDidChange(event)
127 {
128 this._updateClearFocusNodesButtonItem();
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000129 this.dispatchEventToListeners(WI.ContentView.Event.SelectionPathComponentsDidChange);
joepeck@webkit.org56d9f282016-03-06 00:28:39 +0000130 }
131
132 _scriptTimelineRecordRefreshed(event)
133 {
134 this._forceNextLayout = true;
135 this.needsLayout();
136 }
137
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000138 _profileOrientationButtonClicked()
joepeck@webkit.org56d9f282016-03-06 00:28:39 +0000139 {
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000140 this._profileOrientationButton.activated = !this._profileOrientationButton.activated;
141 let isInverted = this._profileOrientationButton.activated;
142 let newOrientation;
143 if (isInverted)
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000144 newOrientation = WI.ScriptProfileTimelineView.ProfileOrientation.BottomUp;
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000145 else
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000146 newOrientation = WI.ScriptProfileTimelineView.ProfileOrientation.TopDown;
joepeck@webkit.org56d9f282016-03-06 00:28:39 +0000147
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000148 WI.ScriptProfileTimelineView.profileOrientationSetting.value = newOrientation;
149 this._showProfileViewForOrientation(newOrientation, WI.ScriptProfileTimelineView.profileTypeSetting.value);
joepeck@webkit.org56d9f282016-03-06 00:28:39 +0000150
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000151 this.dispatchEventToListeners(WI.ContentView.Event.SelectionPathComponentsDidChange);
joepeck@webkit.org56d9f282016-03-06 00:28:39 +0000152
153 this._forceNextLayout = true;
154 this.needsLayout();
155 }
156
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000157 _topFunctionsButtonClicked()
158 {
159 this._topFunctionsButton.activated = !this._topFunctionsButton.activated;
160 let isTopFunctionsEnabled = this._topFunctionsButton.activated;
161 let newOrientation;
162 if (isTopFunctionsEnabled)
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000163 newOrientation = WI.ScriptProfileTimelineView.ProfileViewType.TopFunctions;
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000164 else
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000165 newOrientation = WI.ScriptProfileTimelineView.ProfileViewType.Hierarchy;
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000166
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000167 WI.ScriptProfileTimelineView.profileTypeSetting.value = newOrientation;
168 this._showProfileViewForOrientation(WI.ScriptProfileTimelineView.profileOrientationSetting.value, newOrientation);
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000169
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000170 this.dispatchEventToListeners(WI.ContentView.Event.SelectionPathComponentsDidChange);
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000171
172 this._forceNextLayout = true;
173 this.needsLayout();
174 }
175
176 _showProfileViewForOrientation(profileOrientation, profileViewType)
mattbaker@apple.coma128b282016-05-13 19:01:34 +0000177 {
178 let filterText;
179 if (this._profileView) {
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000180 this._profileView.removeEventListener(WI.ContentView.Event.SelectionPathComponentsDidChange, this._profileViewSelectionPathComponentsDidChange, this);
mattbaker@apple.coma128b282016-05-13 19:01:34 +0000181 this.removeSubview(this._profileView);
182 filterText = this._profileView.dataGrid.filterText;
183 }
184
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000185 let callingContextTree = this._callingContextTreeForOrientation(profileOrientation, profileViewType);
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000186 this._profileView = new WI.ProfileView(callingContextTree, this._sharedProfileViewData);
187 this._profileView.addEventListener(WI.ContentView.Event.SelectionPathComponentsDidChange, this._profileViewSelectionPathComponentsDidChange, this);
mattbaker@apple.coma128b282016-05-13 19:01:34 +0000188
189 this.addSubview(this._profileView);
190 this.setupDataGrid(this._profileView.dataGrid);
191
192 if (filterText)
193 this._profileView.dataGrid.filterText = filterText;
194 }
195
joepeck@webkit.org56d9f282016-03-06 00:28:39 +0000196 _updateClearFocusNodesButtonItem()
197 {
198 this._clearFocusNodesButtonItem.enabled = this._profileView.hasFocusNodes();
199 }
200
201 _clearFocusNodes()
202 {
203 this._profileView.clearFocusNodes();
204 }
205};
206
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000207WI.ScriptProfileTimelineView.ProfileOrientation = {
joepeck@webkit.org56d9f282016-03-06 00:28:39 +0000208 BottomUp: "bottom-up",
209 TopDown: "top-down",
210};
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000211
drousso@apple.com0b21e4c2017-08-02 03:09:57 +0000212WI.ScriptProfileTimelineView.ProfileViewType = {
sbarati@apple.com1fa3bd9f2016-06-13 22:43:20 +0000213 Hierarchy: "hierarchy",
214 TopFunctions: "top-functions",
215};