/* * Copyright (C) 2017 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.RecordingTabContentView = class RecordingTabContentView extends WI.ContentBrowserTabContentView { constructor() { let {image, title} = WI.RecordingTabContentView.tabInfo(); let tabBarItem = new WI.GeneralTabBarItem(image, title); const navigationSidebarPanelConstructor = WI.RecordingNavigationSidebarPanel; const detailsSidebarPanelConstructors = [WI.RecordingStateDetailsSidebarPanel, WI.RecordingTraceDetailsSidebarPanel, WI.CanvasDetailsSidebarPanel]; const disableBackForward = true; let flexibleNavigationItem = new WI.ScrubberNavigationItem; super("recording", "recording", tabBarItem, navigationSidebarPanelConstructor, detailsSidebarPanelConstructors, disableBackForward, flexibleNavigationItem); this._visualActionIndexes = []; this._scrubberNavigationItem = flexibleNavigationItem; this._scrubberNavigationItem.value = 0; this._scrubberNavigationItem.disabled = true; this._scrubberNavigationItem.addEventListener(WI.ScrubberNavigationItem.Event.ValueChanged, this._scrubberNavigationItemValueChanged, this); this.navigationSidebarPanel.addEventListener(WI.RecordingNavigationSidebarPanel.Event.Import, this._navigationSidebarImport, this); this.navigationSidebarPanel.contentTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._navigationSidebarTreeOutlineSelectionChanged, this); this._recording = null; } // Static static tabInfo() { return { image: "Images/Recording.svg", title: WI.UIString("Recording"), }; } static isTabAllowed() { return !!window.CanvasAgent; } // Public get type() { return WI.RecordingTabContentView.Type; } canShowRepresentedObject(representedObject) { // Once a recording has been loaded for this tab, do not allow another one to be loaded. // This will cause new tabs to be opened for each recording, which is the desired behavior. if (this._recording) return false; return representedObject instanceof WI.Recording; } showRepresentedObject(representedObject, cookie) { super.showRepresentedObject(representedObject, cookie); this._recording = representedObject; this._recording.actions.then((actions) => { this._visualActionIndexes = []; actions.forEach((action, i) => { if (action.isVisual) this._visualActionIndexes.push(i); }); this._scrubberNavigationItem.value = 0; this._scrubberNavigationItem.min = 0; this._scrubberNavigationItem.max = actions.length - 1; this._scrubberNavigationItem.disabled = false; this.navigationSidebarPanel.recording = this._recording; this._updateActionIndex(this._scrubberNavigationItem.value); }); } // Protected restoreStateFromCookie(restorationType) { // Don't attempt to do anything to this tab. } saveStateToCookie(cookie) { // Don't attempt to do anything to this tab. } closed() { super.closed(); for (let detailsSidebarPanel of this.detailsSidebarPanels) detailsSidebarPanel.recording = null; this.navigationSidebarPanel.recording = null; } // Private _updateActionIndex(index, options = {}) { this._scrubberNavigationItem.value = index; options.actionCompletedCallback = (action, context) => { for (let detailsSidebarPanel of this.detailsSidebarPanels) { if (detailsSidebarPanel.updateAction) detailsSidebarPanel.updateAction(action, context, options); } }; this.contentBrowser.currentContentView.updateActionIndex(index, options); // This must be placed last, as it is possible for the update of the NavigationSidebarPanel // to trigger another update of the index, such as if the selected index is not expanded. if (!options.suppressNavigationUpdate) this.navigationSidebarPanel.updateActionIndex(index, options); } _scrubberNavigationItemValueChanged(event) { for (let i = 0; i <= this._visualActionIndexes.length; ++i) { if (this._visualActionIndexes[i] < this._scrubberNavigationItem.value) continue; let min = i ? this._visualActionIndexes[i - 1] : this._scrubberNavigationItem.min; let max = i < this._visualActionIndexes.length ? this._visualActionIndexes[i] : this._scrubberNavigationItem.max; this._updateActionIndex(this._scrubberNavigationItem.value >= (min + max) / 2 ? max : min); return; } } _navigationSidebarImport(event) { let {filename, payload} = event.data; let recording = WI.Recording.fromPayload(payload); if (!recording) { WI.Recording.synthesizeError(WI.UIString("unsupported version.")); return; } let extensionStart = filename.lastIndexOf("."); if (extensionStart !== -1) filename = filename.substring(0, extensionStart); recording.createDisplayName(filename); this.showRepresentedObject(recording); } _navigationSidebarTreeOutlineSelectionChanged(event) { // Ignore deselect events. if (!event.data.selectedElement) return; let options = {suppressNavigationUpdate: true}; let selectedTreeElement = this.navigationSidebarPanel.contentTreeOutline.selectedTreeElement; if (selectedTreeElement instanceof WI.FolderTreeElement) selectedTreeElement = selectedTreeElement.children.lastValue; this._updateActionIndex(selectedTreeElement.index, options); } }; WI.RecordingTabContentView.Type = "recording";