Web Inspector: hook up grid row filtering in the new Timelines UI
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Views / ScriptClusterTimelineView.js
1 /*
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
26 WebInspector.ScriptClusterTimelineView = class ScriptClusterTimelineView extends WebInspector.ClusterContentView
27 {
28     constructor(timeline, extraArguments)
29     {
30         super(timeline);
31
32         console.assert(timeline.type === WebInspector.TimelineRecord.Type.Script);
33
34         this._currentContentViewSetting = new WebInspector.Setting("script-cluster-timeline-view-current-view", WebInspector.ScriptClusterTimelineView.EventsIdentifier);
35
36         let showSelectorArrows = this._canShowProfileView();
37         function createPathComponent(displayName, className, identifier)
38         {
39             let pathComponent = new WebInspector.HierarchicalPathComponent(displayName, className, identifier, false, showSelectorArrows);
40             pathComponent.addEventListener(WebInspector.HierarchicalPathComponent.Event.SiblingWasSelected, this._pathComponentSelected, this);
41             return pathComponent;
42         }
43
44         this._eventsPathComponent = createPathComponent.call(this, WebInspector.UIString("Events"), "events-icon", WebInspector.ScriptClusterTimelineView.EventsIdentifier);
45         this._profilePathComponent = createPathComponent.call(this, WebInspector.UIString("Call Trees"), "call-trees-icon", WebInspector.ScriptClusterTimelineView.ProfileIdentifier);
46
47         if (this._canShowProfileView()) {
48             this._eventsPathComponent.nextSibling = this._profilePathComponent;
49             this._profilePathComponent.previousSibling = this._eventsPathComponent;
50         }
51
52         // FIXME: We should be able to create these lazily.
53         this._eventsContentView = new WebInspector.ScriptDetailsTimelineView(this.representedObject, extraArguments);
54         this._profileContentView = this._canShowProfileView() ? new WebInspector.ScriptProfileTimelineView(this.representedObject, extraArguments) : null;
55
56         this._showContentViewForIdentifier(this._currentContentViewSetting.value);
57
58         this.contentViewContainer.addEventListener(WebInspector.ContentViewContainer.Event.CurrentContentViewDidChange, this._scriptClusterViewCurrentContentViewDidChange, this)
59     }
60
61     // TimelineView
62
63     // FIXME: Determine a better way to bridge TimelineView methods to the sub-timeline views.
64     get zeroTime() { return this._contentViewContainer.currentContentView.zeroTime; }
65     set zeroTime(x) { this._contentViewContainer.currentContentView.zeroTime = x; }
66     get startTime() { return this._contentViewContainer.currentContentView.startTime; }
67     set startTime(x) { this._contentViewContainer.currentContentView.startTime = x; }
68     get endTime() { return this._contentViewContainer.currentContentView.endTime; }
69     set endTime(x) { this._contentViewContainer.currentContentView.endTime = x; }
70     get currentTime() { return this._contentViewContainer.currentContentView.currentTime; }
71     set currentTime(x) { this._contentViewContainer.currentContentView.currentTime = x; }
72     get navigationSidebarTreeOutline() { return this._contentViewContainer.currentContentView.navigationSidebarTreeOutline; }
73     reset() { return this._contentViewContainer.currentContentView.reset(); }
74     updateFilter(filters) { return this._contentViewContainer.currentContentView.updateFilter(filters); }
75     filterDidChange() { return this._contentViewContainer.currentContentView.filterDidChange(); }
76     matchDataGridNodeAgainstCustomFilters(node) { return this._contentViewContainer.currentContentView.matchDataGridNodeAgainstCustomFilters(node); }
77
78     // Public
79
80     get eventsContentView()
81     {
82         return this._eventsContentView;
83     }
84
85     get profileContentView()
86     {
87         return this._profileContentView;
88     }
89
90     get selectionPathComponents()
91     {
92         let currentContentView = this._contentViewContainer.currentContentView;
93         if (!currentContentView)
94             return [];
95
96         let components = [this._pathComponentForContentView(currentContentView)];
97         let subComponents = currentContentView.selectionPathComponents;
98         if (subComponents)
99             return components.concat(subComponents);
100         return components;
101     }
102
103     saveToCookie(cookie)
104     {
105         cookie[WebInspector.ScriptClusterTimelineView.ContentViewIdentifierCookieKey] = this._currentContentViewSetting.value;
106     }
107
108     restoreFromCookie(cookie)
109     {
110         this._showContentViewForIdentifier(cookie[WebInspector.ScriptClusterTimelineView.ContentViewIdentifierCookieKey]);
111     }
112
113     showEvents()
114     {
115         return this._showContentViewForIdentifier(WebInspector.ScriptClusterTimelineView.EventsIdentifier);
116     }
117
118     showProfile()
119     {
120         if (!this._canShowProfileView())
121             return this.showEvents();
122
123         return this._showContentViewForIdentifier(WebInspector.ScriptClusterTimelineView.ProfileIdentifier);
124     }
125
126     // Private
127
128     _canShowProfileView()
129     {
130         // COMPATIBILITY (iOS 9): Legacy backends did not include CallingContextTree ScriptProfiler data.
131         return window.ScriptProfilerAgent;
132     }
133
134     _pathComponentForContentView(contentView)
135     {
136         console.assert(contentView);
137         if (!contentView)
138             return null;
139         if (contentView === this._eventsContentView)
140             return this._eventsPathComponent;
141         if (contentView === this._profileContentView)
142             return this._profilePathComponent;
143         console.error("Unknown contentView.");
144         return null;
145     }
146
147     _identifierForContentView(contentView)
148     {
149         console.assert(contentView);
150         if (!contentView)
151             return null;
152         if (contentView === this._eventsContentView)
153             return WebInspector.ScriptClusterTimelineView.EventsIdentifier;
154         if (contentView === this._profileContentView)
155             return WebInspector.ScriptClusterTimelineView.ProfileIdentifier;
156         console.error("Unknown contentView.");
157         return null;
158     }
159
160     _showContentViewForIdentifier(identifier)
161     {
162         let contentViewToShow = null;
163
164         switch (identifier) {
165         case WebInspector.ScriptClusterTimelineView.EventsIdentifier:
166             contentViewToShow = this.eventsContentView;
167             break;
168         case WebInspector.ScriptClusterTimelineView.ProfileIdentifier:
169             contentViewToShow = this.profileContentView;
170             break;
171         }
172
173         if (!contentViewToShow)
174             contentViewToShow = this.eventsContentView;
175
176         console.assert(contentViewToShow);
177
178         this._currentContentViewSetting.value = this._identifierForContentView(contentViewToShow);
179
180         return this.contentViewContainer.showContentView(contentViewToShow);
181     }
182
183     _pathComponentSelected(event)
184     {
185         this._showContentViewForIdentifier(event.data.pathComponent.representedObject);
186     }
187
188     _scriptClusterViewCurrentContentViewDidChange(event)
189     {
190         let currentContentView = this._contentViewContainer.currentContentView;
191         if (!currentContentView)
192             return;
193
194         let previousContentView = currentContentView === this._eventsContentView ? this._profileContentView : this._eventsContentView;
195
196         currentContentView.zeroTime = previousContentView.zeroTime;
197         currentContentView.startTime = previousContentView.startTime;
198         currentContentView.endTime = previousContentView.endTime;
199         currentContentView.currentTime = previousContentView.currentTime;
200     }
201 };
202
203 WebInspector.ScriptClusterTimelineView.ContentViewIdentifierCookieKey = "script-cluster-timeline-view-identifier";
204
205 WebInspector.ScriptClusterTimelineView.EventsIdentifier = "events";
206 WebInspector.ScriptClusterTimelineView.ProfileIdentifier = "profile";