| /* |
| * Copyright (C) 2016 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| * THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| WI.ScriptClusterTimelineView = class ScriptClusterTimelineView extends WI.ClusterContentView |
| { |
| constructor(timeline, extraArguments) |
| { |
| super(timeline); |
| |
| console.assert(timeline.type === WI.TimelineRecord.Type.Script); |
| |
| this._currentContentViewSetting = new WI.Setting("script-cluster-timeline-view-current-view", WI.ScriptClusterTimelineView.EventsIdentifier); |
| |
| let showSelectorArrows = this._canShowProfileView(); |
| function createPathComponent(displayName, className, identifier) |
| { |
| let pathComponent = new WI.HierarchicalPathComponent(displayName, className, identifier, false, showSelectorArrows); |
| pathComponent.addEventListener(WI.HierarchicalPathComponent.Event.SiblingWasSelected, this._pathComponentSelected, this); |
| pathComponent.comparisonData = timeline; |
| return pathComponent; |
| } |
| |
| this._eventsPathComponent = createPathComponent.call(this, WI.UIString("Events"), "events-icon", WI.ScriptClusterTimelineView.EventsIdentifier); |
| this._profilePathComponent = createPathComponent.call(this, WI.UIString("Call Trees"), "call-trees-icon", WI.ScriptClusterTimelineView.ProfileIdentifier); |
| |
| if (this._canShowProfileView()) { |
| this._eventsPathComponent.nextSibling = this._profilePathComponent; |
| this._profilePathComponent.previousSibling = this._eventsPathComponent; |
| } |
| |
| // FIXME: We should be able to create these lazily. |
| this._eventsContentView = new WI.ScriptDetailsTimelineView(this.representedObject, extraArguments); |
| this._profileContentView = this._canShowProfileView() ? new WI.ScriptProfileTimelineView(this.representedObject, extraArguments) : null; |
| |
| this._showContentViewForIdentifier(this._currentContentViewSetting.value); |
| |
| this.contentViewContainer.addEventListener(WI.ContentViewContainer.Event.CurrentContentViewDidChange, this._scriptClusterViewCurrentContentViewDidChange, this); |
| } |
| |
| // TimelineView |
| |
| // FIXME: Determine a better way to bridge TimelineView methods to the sub-timeline views. |
| get showsLiveRecordingData() { return this._contentViewContainer.currentContentView.showsLiveRecordingData; } |
| get showsFilterBar() { return this._contentViewContainer.currentContentView.showsFilterBar; } |
| get zeroTime() { return this._contentViewContainer.currentContentView.zeroTime; } |
| set zeroTime(x) { this._contentViewContainer.currentContentView.zeroTime = x; } |
| get startTime() { return this._contentViewContainer.currentContentView.startTime; } |
| set startTime(x) { this._contentViewContainer.currentContentView.startTime = x; } |
| get endTime() { return this._contentViewContainer.currentContentView.endTime; } |
| set endTime(x) { this._contentViewContainer.currentContentView.endTime = x; } |
| get currentTime() { return this._contentViewContainer.currentContentView.currentTime; } |
| set currentTime(x) { this._contentViewContainer.currentContentView.currentTime = x; } |
| selectRecord(record) { this._contentViewContainer.currentContentView.selectRecord(record); } |
| updateFilter(filters) { return this._contentViewContainer.currentContentView.updateFilter(filters); } |
| filterDidChange() { return this._contentViewContainer.currentContentView.filterDidChange(); } |
| matchDataGridNodeAgainstCustomFilters(node) { return this._contentViewContainer.currentContentView.matchDataGridNodeAgainstCustomFilters(node); } |
| |
| reset() |
| { |
| this._eventsContentView.reset(); |
| |
| if (this._profileContentView) |
| this._profileContentView.reset(); |
| } |
| |
| // Public |
| |
| get eventsContentView() |
| { |
| return this._eventsContentView; |
| } |
| |
| get profileContentView() |
| { |
| return this._profileContentView; |
| } |
| |
| get selectionPathComponents() |
| { |
| let currentContentView = this._contentViewContainer.currentContentView; |
| if (!currentContentView) |
| return []; |
| |
| let components = [this._pathComponentForContentView(currentContentView)]; |
| |
| let subComponents = currentContentView.selectionPathComponents; |
| if (subComponents) |
| components.pushAll(subComponents); |
| |
| return components; |
| } |
| |
| saveToCookie(cookie) |
| { |
| cookie[WI.ScriptClusterTimelineView.ContentViewIdentifierCookieKey] = this._currentContentViewSetting.value; |
| } |
| |
| restoreFromCookie(cookie) |
| { |
| this._showContentViewForIdentifier(cookie[WI.ScriptClusterTimelineView.ContentViewIdentifierCookieKey]); |
| } |
| |
| showEvents() |
| { |
| return this._showContentViewForIdentifier(WI.ScriptClusterTimelineView.EventsIdentifier); |
| } |
| |
| showProfile() |
| { |
| if (!this._canShowProfileView()) |
| return this.showEvents(); |
| |
| return this._showContentViewForIdentifier(WI.ScriptClusterTimelineView.ProfileIdentifier); |
| } |
| |
| // Private |
| |
| _canShowProfileView() |
| { |
| // COMPATIBILITY (iOS 9): Legacy backends did not include CallingContextTree ScriptProfiler data. |
| return InspectorBackend.hasDomain("ScriptProfiler"); |
| } |
| |
| _pathComponentForContentView(contentView) |
| { |
| console.assert(contentView); |
| if (!contentView) |
| return null; |
| if (contentView === this._eventsContentView) |
| return this._eventsPathComponent; |
| if (contentView === this._profileContentView) |
| return this._profilePathComponent; |
| console.error("Unknown contentView."); |
| return null; |
| } |
| |
| _identifierForContentView(contentView) |
| { |
| console.assert(contentView); |
| if (!contentView) |
| return null; |
| if (contentView === this._eventsContentView) |
| return WI.ScriptClusterTimelineView.EventsIdentifier; |
| if (contentView === this._profileContentView) |
| return WI.ScriptClusterTimelineView.ProfileIdentifier; |
| console.error("Unknown contentView."); |
| return null; |
| } |
| |
| _showContentViewForIdentifier(identifier) |
| { |
| let contentViewToShow = null; |
| |
| switch (identifier) { |
| case WI.ScriptClusterTimelineView.EventsIdentifier: |
| contentViewToShow = this.eventsContentView; |
| break; |
| case WI.ScriptClusterTimelineView.ProfileIdentifier: |
| contentViewToShow = this.profileContentView; |
| break; |
| } |
| |
| if (!contentViewToShow) |
| contentViewToShow = this.eventsContentView; |
| |
| console.assert(contentViewToShow); |
| |
| this._currentContentViewSetting.value = this._identifierForContentView(contentViewToShow); |
| |
| return this.contentViewContainer.showContentView(contentViewToShow); |
| } |
| |
| _pathComponentSelected(event) |
| { |
| this._showContentViewForIdentifier(event.data.pathComponent.representedObject); |
| } |
| |
| _scriptClusterViewCurrentContentViewDidChange(event) |
| { |
| let currentContentView = this._contentViewContainer.currentContentView; |
| if (!currentContentView) |
| return; |
| |
| let previousContentView = currentContentView === this._eventsContentView ? this._profileContentView : this._eventsContentView; |
| |
| currentContentView.zeroTime = previousContentView.zeroTime; |
| currentContentView.startTime = previousContentView.startTime; |
| currentContentView.endTime = previousContentView.endTime; |
| currentContentView.currentTime = previousContentView.currentTime; |
| } |
| }; |
| |
| WI.ScriptClusterTimelineView.ContentViewIdentifierCookieKey = "script-cluster-timeline-view-identifier"; |
| |
| WI.ScriptClusterTimelineView.EventsIdentifier = "events"; |
| WI.ScriptClusterTimelineView.ProfileIdentifier = "profile"; |