summaryrefslogtreecommitdiff
path: root/Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js')
-rw-r--r--Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js678
1 files changed, 678 insertions, 0 deletions
diff --git a/Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js b/Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js
new file mode 100644
index 000000000..ab04ddf10
--- /dev/null
+++ b/Source/WebInspectorUI/UserInterface/Controllers/ReplayManager.js
@@ -0,0 +1,678 @@
+/*
+ * Copyright (C) 2013 University of Washington. All rights reserved.
+ * Copyright (C) 2014 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.
+ */
+
+WebInspector.ReplayManager = class ReplayManager extends WebInspector.Object
+{
+ constructor()
+ {
+ super();
+
+ this._sessionState = WebInspector.ReplayManager.SessionState.Inactive;
+ this._segmentState = WebInspector.ReplayManager.SegmentState.Unloaded;
+
+ this._activeSessionIdentifier = null;
+ this._activeSegmentIdentifier = null;
+ this._currentPosition = new WebInspector.ReplayPosition(0, 0);
+ this._initialized = false;
+
+ // These hold actual instances of sessions and segments.
+ this._sessions = new Map;
+ this._segments = new Map;
+ // These hold promises that resolve when the instance data is recieved.
+ this._sessionPromises = new Map;
+ this._segmentPromises = new Map;
+
+ // Playback speed is specified in replayToPosition commands, and persists
+ // for the duration of the playback command until another playback begins.
+ this._playbackSpeed = WebInspector.ReplayManager.PlaybackSpeed.RealTime;
+
+ if (window.ReplayAgent) {
+ var instance = this;
+ this._initializationPromise = ReplayAgent.currentReplayState()
+ .then(function(payload) {
+ console.assert(payload.sessionState in WebInspector.ReplayManager.SessionState, "Unknown session state: " + payload.sessionState);
+ console.assert(payload.segmentState in WebInspector.ReplayManager.SegmentState, "Unknown segment state: " + payload.segmentState);
+
+ instance._activeSessionIdentifier = payload.sessionIdentifier;
+ instance._activeSegmentIdentifier = payload.segmentIdentifier;
+ instance._sessionState = WebInspector.ReplayManager.SessionState[payload.sessionState];
+ instance._segmentState = WebInspector.ReplayManager.SegmentState[payload.segmentState];
+ instance._currentPosition = payload.replayPosition;
+
+ instance._initialized = true;
+ }).then(function() {
+ return ReplayAgent.getAvailableSessions();
+ }).then(function(payload) {
+ for (var sessionId of payload.ids)
+ instance.sessionCreated(sessionId);
+ }).catch(function(error) {
+ console.error("ReplayManager initialization failed: ", error);
+ throw error;
+ });
+ }
+ }
+
+ // Public
+
+ // The following state is invalid unless called from a function that's chained
+ // to the (resolved) ReplayManager.waitUntilInitialized promise.
+ get sessionState()
+ {
+ console.assert(this._initialized);
+ return this._sessionState;
+ }
+
+ get segmentState()
+ {
+ console.assert(this._initialized);
+ return this._segmentState;
+ }
+
+ get activeSessionIdentifier()
+ {
+ console.assert(this._initialized);
+ return this._activeSessionIdentifier;
+ }
+
+ get activeSegmentIdentifier()
+ {
+ console.assert(this._initialized);
+ return this._activeSegmentIdentifier;
+ }
+
+ get playbackSpeed()
+ {
+ console.assert(this._initialized);
+ return this._playbackSpeed;
+ }
+
+ set playbackSpeed(value)
+ {
+ console.assert(this._initialized);
+ this._playbackSpeed = value;
+ }
+
+ get currentPosition()
+ {
+ console.assert(this._initialized);
+ return this._currentPosition;
+ }
+
+ // These return promises even if the relevant instance is already created.
+ waitUntilInitialized() // --> ()
+ {
+ return this._initializationPromise;
+ }
+
+ // Return a promise that resolves to a session, if it exists.
+ getSession(sessionId) // --> (WebInspector.ReplaySession)
+ {
+ if (this._sessionPromises.has(sessionId))
+ return this._sessionPromises.get(sessionId);
+
+ var newPromise = ReplayAgent.getSessionData(sessionId)
+ .then(function(payload) {
+ return Promise.resolve(WebInspector.ReplaySession.fromPayload(sessionId, payload));
+ });
+
+ this._sessionPromises.set(sessionId, newPromise);
+ return newPromise;
+ }
+
+ // Return a promise that resolves to a session segment, if it exists.
+ getSegment(segmentId) // --> (WebInspector.ReplaySessionSegment)
+ {
+ if (this._segmentPromises.has(segmentId))
+ return this._segmentPromises.get(segmentId);
+
+ var newPromise = ReplayAgent.getSegmentData(segmentId)
+ .then(function(payload) {
+ return Promise.resolve(new WebInspector.ReplaySessionSegment(segmentId, payload));
+ });
+
+ this._segmentPromises.set(segmentId, newPromise);
+ return newPromise;
+ }
+
+ // Switch to the specified session.
+ // Returns a promise that resolves when the switch completes.
+ switchSession(sessionId) // --> ()
+ {
+ var manager = this;
+ var result = this.waitUntilInitialized();
+
+ if (this.sessionState === WebInspector.ReplayManager.SessionState.Capturing) {
+ result = result.then(function() {
+ return WebInspector.replayManager.stopCapturing();
+ });
+ }
+
+ if (this.sessionState === WebInspector.ReplayManager.SessionState.Replaying) {
+ result = result.then(function() {
+ return WebInspector.replayManager.cancelPlayback();
+ });
+ }
+
+ result = result.then(function() {
+ console.assert(manager.sessionState === WebInspector.ReplayManager.SessionState.Inactive);
+ console.assert(manager.segmentState === WebInspector.ReplayManager.SegmentState.Unloaded);
+
+ return manager.getSession(sessionId);
+ }).then(function ensureSessionDataIsLoaded(session) {
+ return ReplayAgent.switchSession(session.identifier);
+ }).catch(function(error) {
+ console.error("Failed to switch to session: ", error);
+ throw error;
+ });
+
+ return result;
+ }
+
+ // Start capturing into the current session as soon as possible.
+ // Returns a promise that resolves when capturing begins.
+ startCapturing() // --> ()
+ {
+ var manager = this;
+ var result = this.waitUntilInitialized();
+
+ if (this.sessionState === WebInspector.ReplayManager.SessionState.Capturing)
+ return result; // Already capturing.
+
+ if (this.sessionState === WebInspector.ReplayManager.SessionState.Replaying) {
+ result = result.then(function() {
+ return WebInspector.replayManager.cancelPlayback();
+ });
+ }
+
+ result = result.then(this._suppressBreakpointsAndResumeIfNeeded());
+
+ result = result.then(function() {
+ console.assert(manager.sessionState === WebInspector.ReplayManager.SessionState.Inactive);
+ console.assert(manager.segmentState === WebInspector.ReplayManager.SegmentState.Unloaded);
+
+ return ReplayAgent.startCapturing();
+ }).catch(function(error) {
+ console.error("Failed to start capturing: ", error);
+ throw error;
+ });
+
+ return result;
+ }
+
+ // Stop capturing into the current session as soon as possible.
+ // Returns a promise that resolves when capturing ends.
+ stopCapturing() // --> ()
+ {
+ console.assert(this.sessionState === WebInspector.ReplayManager.SessionState.Capturing, "Cannot stop capturing unless capture is active.");
+ console.assert(this.segmentState === WebInspector.ReplayManager.SegmentState.Appending);
+
+ return ReplayAgent.stopCapturing()
+ .catch(function(error) {
+ console.error("Failed to stop capturing: ", error);
+ throw error;
+ });
+ }
+
+ // Pause playback as soon as possible.
+ // Returns a promise that resolves when playback is paused.
+ pausePlayback() // --> ()
+ {
+ console.assert(this.sessionState !== WebInspector.ReplayManager.SessionState.Capturing, "Cannot pause playback while capturing.");
+
+ var manager = this;
+ var result = this.waitUntilInitialized();
+
+ if (this.sessionState === WebInspector.ReplayManager.SessionState.Inactive)
+ return result; // Already stopped.
+
+ if (this.segmentState !== WebInspector.ReplayManager.SegmentState.Dispatching)
+ return result; // Already stopped.
+
+ result = result.then(function() {
+ console.assert(manager.sessionState === WebInspector.ReplayManager.SessionState.Replaying);
+ console.assert(manager.segmentState === WebInspector.ReplayManager.SegmentState.Dispatching);
+
+ return ReplayAgent.pausePlayback();
+ }).catch(function(error) {
+ console.error("Failed to pause playback: ", error);
+ throw error;
+ });
+
+ return result;
+ }
+
+ // Pause playback and unload the current session segment as soon as possible.
+ // Returns a promise that resolves when the current segment is unloaded.
+ cancelPlayback() // --> ()
+ {
+ console.assert(this.sessionState !== WebInspector.ReplayManager.SessionState.Capturing, "Cannot stop playback while capturing.");
+
+ var manager = this;
+ var result = this.waitUntilInitialized();
+
+ if (this.sessionState === WebInspector.ReplayManager.SessionState.Inactive)
+ return result; // Already stopped.
+
+ result = result.then(function() {
+ console.assert(manager.sessionState === WebInspector.ReplayManager.SessionState.Replaying);
+ console.assert(manager.segmentState !== WebInspector.ReplayManager.SegmentState.Appending);
+
+ return ReplayAgent.cancelPlayback();
+ }).catch(function(error) {
+ console.error("Failed to stop playback: ", error);
+ throw error;
+ });
+
+ return result;
+ }
+
+ // Replay to the specified position as soon as possible using the current replay speed.
+ // Returns a promise that resolves when replay has begun (NOT when the position is reached).
+ replayToPosition(replayPosition) // --> ()
+ {
+ console.assert(replayPosition instanceof WebInspector.ReplayPosition, "Cannot replay to a position while capturing.");
+
+ var manager = this;
+ var result = this.waitUntilInitialized();
+
+ if (this.sessionState === WebInspector.ReplayManager.SessionState.Capturing) {
+ result = result.then(function() {
+ return WebInspector.replayManager.stopCapturing();
+ });
+ }
+
+ result = result.then(this._suppressBreakpointsAndResumeIfNeeded());
+
+ result = result.then(function() {
+ console.assert(manager.sessionState !== WebInspector.ReplayManager.SessionState.Capturing);
+ console.assert(manager.segmentState !== WebInspector.ReplayManager.SegmentState.Appending);
+
+ return ReplayAgent.replayToPosition(replayPosition, manager.playbackSpeed === WebInspector.ReplayManager.PlaybackSpeed.FastForward);
+ }).catch(function(error) {
+ console.error("Failed to start playback to position: ", replayPosition, error);
+ throw error;
+ });
+
+ return result;
+ }
+
+ // Replay to the end of the session as soon as possible using the current replay speed.
+ // Returns a promise that resolves when replay has begun (NOT when the end is reached).
+ replayToCompletion() // --> ()
+ {
+ var manager = this;
+ var result = this.waitUntilInitialized();
+
+ if (this.segmentState === WebInspector.ReplayManager.SegmentState.Dispatching)
+ return result; // Already running.
+
+ if (this.sessionState === WebInspector.ReplayManager.SessionState.Capturing) {
+ result = result.then(function() {
+ return WebInspector.replayManager.stopCapturing();
+ });
+ }
+
+ result = result.then(this._suppressBreakpointsAndResumeIfNeeded());
+
+ result = result.then(function() {
+ console.assert(manager.sessionState !== WebInspector.ReplayManager.SessionState.Capturing);
+ console.assert(manager.segmentState === WebInspector.ReplayManager.SegmentState.Loaded || manager.segmentState === WebInspector.ReplayManager.SegmentState.Unloaded);
+
+ return ReplayAgent.replayToCompletion(manager.playbackSpeed === WebInspector.ReplayManager.PlaybackSpeed.FastForward);
+ }).catch(function(error) {
+ console.error("Failed to start playback to completion: ", error);
+ throw error;
+ });
+
+ return result;
+ }
+
+ // Protected (called by ReplayObserver)
+
+ // Since these methods update session and segment state, they depend on the manager
+ // being properly initialized. So, each function body is prepended with a retry guard.
+ // This makes call sites simpler and avoids an extra event loop turn in the common case.
+
+ captureStarted()
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.captureStarted.bind(this));
+
+ this._changeSessionState(WebInspector.ReplayManager.SessionState.Capturing);
+
+ this.dispatchEventToListeners(WebInspector.ReplayManager.Event.CaptureStarted);
+ }
+
+ captureStopped()
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.captureStopped.bind(this));
+
+ this._changeSessionState(WebInspector.ReplayManager.SessionState.Inactive);
+ this._changeSegmentState(WebInspector.ReplayManager.SegmentState.Unloaded);
+
+ if (this._breakpointsWereSuppressed) {
+ delete this._breakpointsWereSuppressed;
+ WebInspector.debuggerManager.breakpointsEnabled = true;
+ }
+
+ this.dispatchEventToListeners(WebInspector.ReplayManager.Event.CaptureStopped);
+ }
+
+ playbackStarted()
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.playbackStarted.bind(this));
+
+ if (this.sessionState === WebInspector.ReplayManager.SessionState.Inactive)
+ this._changeSessionState(WebInspector.ReplayManager.SessionState.Replaying);
+
+ this._changeSegmentState(WebInspector.ReplayManager.SegmentState.Dispatching);
+
+ this.dispatchEventToListeners(WebInspector.ReplayManager.Event.PlaybackStarted);
+ }
+
+ playbackHitPosition(replayPosition, timestamp)
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.playbackHitPosition.bind(this, replayPosition, timestamp));
+
+ console.assert(this.sessionState === WebInspector.ReplayManager.SessionState.Replaying);
+ console.assert(this.segmentState === WebInspector.ReplayManager.SegmentState.Dispatching);
+ console.assert(replayPosition instanceof WebInspector.ReplayPosition);
+
+ this._currentPosition = replayPosition;
+ this.dispatchEventToListeners(WebInspector.ReplayManager.Event.PlaybackPositionChanged);
+ }
+
+ playbackPaused(position)
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.playbackPaused.bind(this, position));
+
+ console.assert(this.sessionState === WebInspector.ReplayManager.SessionState.Replaying);
+ this._changeSegmentState(WebInspector.ReplayManager.SegmentState.Loaded);
+
+ if (this._breakpointsWereSuppressed) {
+ delete this._breakpointsWereSuppressed;
+ WebInspector.debuggerManager.breakpointsEnabled = true;
+ }
+
+ this.dispatchEventToListeners(WebInspector.ReplayManager.Event.PlaybackPaused);
+ }
+
+ playbackFinished()
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.playbackFinished.bind(this));
+
+ this._changeSessionState(WebInspector.ReplayManager.SessionState.Inactive);
+ console.assert(this.segmentState === WebInspector.ReplayManager.SegmentState.Unloaded);
+
+ if (this._breakpointsWereSuppressed) {
+ delete this._breakpointsWereSuppressed;
+ WebInspector.debuggerManager.breakpointsEnabled = true;
+ }
+
+ this.dispatchEventToListeners(WebInspector.ReplayManager.Event.PlaybackFinished);
+ }
+
+ sessionCreated(sessionId)
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.sessionCreated.bind(this, sessionId));
+
+ console.assert(!this._sessions.has(sessionId), "Tried to add duplicate session identifier:", sessionId);
+ var sessionMap = this._sessions;
+ this.getSession(sessionId)
+ .then(function(session) {
+ sessionMap.set(sessionId, session);
+ }).catch(function(error) {
+ console.error("Error obtaining session data: ", error);
+ throw error;
+ });
+
+ this.dispatchEventToListeners(WebInspector.ReplayManager.Event.SessionAdded, {sessionId});
+ }
+
+ sessionModified(sessionId)
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.sessionModified.bind(this, sessionId));
+
+ this.getSession(sessionId).then(function(session) {
+ session.segmentsChanged();
+ });
+ }
+
+ sessionRemoved(sessionId)
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.sessionRemoved.bind(this, sessionId));
+
+ console.assert(this._sessions.has(sessionId), "Unknown session identifier:", sessionId);
+
+ if (!this._sessionPromises.has(sessionId))
+ return;
+
+ var manager = this;
+
+ this.getSession(sessionId)
+ .catch(function(error) {
+ // Wait for any outstanding promise to settle so it doesn't get re-added.
+ }).then(function() {
+ manager._sessionPromises.delete(sessionId);
+ var removedSession = manager._sessions.take(sessionId);
+ console.assert(removedSession);
+ manager.dispatchEventToListeners(WebInspector.ReplayManager.Event.SessionRemoved, {removedSession});
+ });
+ }
+
+ segmentCreated(segmentId)
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.segmentCreated.bind(this, segmentId));
+
+ console.assert(!this._segments.has(segmentId), "Tried to add duplicate segment identifier:", segmentId);
+
+ this._changeSegmentState(WebInspector.ReplayManager.SegmentState.Appending);
+
+ // Create a dummy segment, and don't try to load any data for it. It will
+ // be removed once the segment is complete, and then its data will be fetched.
+ var incompleteSegment = new WebInspector.IncompleteSessionSegment(segmentId);
+ this._segments.set(segmentId, incompleteSegment);
+ this._segmentPromises.set(segmentId, Promise.resolve(incompleteSegment));
+
+ this.dispatchEventToListeners(WebInspector.ReplayManager.Event.SessionSegmentAdded, {segmentIdentifier: segmentId});
+ }
+
+ segmentCompleted(segmentId)
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.segmentCompleted.bind(this, segmentId));
+
+ var placeholderSegment = this._segments.take(segmentId);
+ console.assert(placeholderSegment instanceof WebInspector.IncompleteSessionSegment);
+ this._segmentPromises.delete(segmentId);
+
+ var segmentMap = this._segments;
+ this.getSegment(segmentId)
+ .then(function(segment) {
+ segmentMap.set(segmentId, segment);
+ }).catch(function(error) {
+ console.error("Error obtaining segment data: ", error);
+ throw error;
+ });
+ }
+
+ segmentRemoved(segmentId)
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.segmentRemoved.bind(this, segmentId));
+
+ console.assert(this._segments.has(segmentId), "Unknown segment identifier:", segmentId);
+
+ if (!this._segmentPromises.has(segmentId))
+ return;
+
+ var manager = this;
+
+ // Wait for any outstanding promise to settle so it doesn't get re-added.
+ this.getSegment(segmentId)
+ .catch(function(error) {
+ return Promise.resolve();
+ }).then(function() {
+ manager._segmentPromises.delete(segmentId);
+ var removedSegment = manager._segments.take(segmentId);
+ console.assert(removedSegment);
+ manager.dispatchEventToListeners(WebInspector.ReplayManager.Event.SessionSegmentRemoved, {removedSegment});
+ });
+ }
+
+ segmentLoaded(segmentId)
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.segmentLoaded.bind(this, segmentId));
+
+ console.assert(this._segments.has(segmentId), "Unknown segment identifier:", segmentId);
+
+ console.assert(this.sessionState !== WebInspector.ReplayManager.SessionState.Capturing);
+ this._changeSegmentState(WebInspector.ReplayManager.SegmentState.Loaded);
+
+ var previousIdentifier = this._activeSegmentIdentifier;
+ this._activeSegmentIdentifier = segmentId;
+ this.dispatchEventToListeners(WebInspector.ReplayManager.Event.ActiveSegmentChanged, {previousSegmentIdentifier: previousIdentifier});
+ }
+
+ segmentUnloaded()
+ {
+ if (!this._initialized)
+ return this.waitUntilInitialized().then(this.segmentUnloaded.bind(this));
+
+ console.assert(this.sessionState === WebInspector.ReplayManager.SessionState.Replaying);
+ this._changeSegmentState(WebInspector.ReplayManager.SegmentState.Unloaded);
+
+ var previousIdentifier = this._activeSegmentIdentifier;
+ this._activeSegmentIdentifier = null;
+ this.dispatchEventToListeners(WebInspector.ReplayManager.Event.ActiveSegmentChanged, {previousSegmentIdentifier: previousIdentifier});
+ }
+
+ // Private
+
+ _changeSessionState(newState)
+ {
+ // Warn about no-op state changes. We shouldn't be seeing them.
+ var isAllowed = this._sessionState !== newState;
+
+ switch (this._sessionState) {
+ case WebInspector.ReplayManager.SessionState.Capturing:
+ isAllowed &= newState === WebInspector.ReplayManager.SessionState.Inactive;
+ break;
+
+ case WebInspector.ReplayManager.SessionState.Replaying:
+ isAllowed &= newState === WebInspector.ReplayManager.SessionState.Inactive;
+ break;
+ }
+
+ console.assert(isAllowed, "Invalid session state change: ", this._sessionState, " to ", newState);
+ if (isAllowed)
+ this._sessionState = newState;
+ }
+
+ _changeSegmentState(newState)
+ {
+ // Warn about no-op state changes. We shouldn't be seeing them.
+ var isAllowed = this._segmentState !== newState;
+
+ switch (this._segmentState) {
+ case WebInspector.ReplayManager.SegmentState.Appending:
+ isAllowed &= newState === WebInspector.ReplayManager.SegmentState.Unloaded;
+ break;
+ case WebInspector.ReplayManager.SegmentState.Unloaded:
+ isAllowed &= newState === WebInspector.ReplayManager.SegmentState.Appending || newState === WebInspector.ReplayManager.SegmentState.Loaded;
+ break;
+ case WebInspector.ReplayManager.SegmentState.Loaded:
+ isAllowed &= newState === WebInspector.ReplayManager.SegmentState.Unloaded || newState === WebInspector.ReplayManager.SegmentState.Dispatching;
+ break;
+ case WebInspector.ReplayManager.SegmentState.Dispatching:
+ isAllowed &= newState === WebInspector.ReplayManager.SegmentState.Loaded;
+ break;
+ }
+
+ console.assert(isAllowed, "Invalid segment state change: ", this._segmentState, " to ", newState);
+ if (isAllowed)
+ this._segmentState = newState;
+ }
+
+ _suppressBreakpointsAndResumeIfNeeded()
+ {
+ var manager = this;
+
+ return new Promise(function(resolve, reject) {
+ manager._breakpointsWereSuppressed = WebInspector.debuggerManager.breakpointsEnabled;
+ WebInspector.debuggerManager.breakpointsEnabled = false;
+
+ return WebInspector.debuggerManager.resume();
+ });
+ }
+};
+
+WebInspector.ReplayManager.Event = {
+ CaptureStarted: "replay-manager-capture-started",
+ CaptureStopped: "replay-manager-capture-stopped",
+
+ PlaybackStarted: "replay-manager-playback-started",
+ PlaybackPaused: "replay-manager-playback-paused",
+ PlaybackFinished: "replay-manager-playback-finished",
+ PlaybackPositionChanged: "replay-manager-play-back-position-changed",
+
+ ActiveSessionChanged: "replay-manager-active-session-changed",
+ ActiveSegmentChanged: "replay-manager-active-segment-changed",
+
+ SessionSegmentAdded: "replay-manager-session-segment-added",
+ SessionSegmentRemoved: "replay-manager-session-segment-removed",
+
+ SessionAdded: "replay-manager-session-added",
+ SessionRemoved: "replay-manager-session-removed",
+};
+
+WebInspector.ReplayManager.SessionState = {
+ Capturing: "replay-manager-session-state-capturing",
+ Inactive: "replay-manager-session-state-inactive",
+ Replaying: "replay-manager-session-state-replaying",
+};
+
+WebInspector.ReplayManager.SegmentState = {
+ Appending: "replay-manager-segment-state-appending",
+ Unloaded: "replay-manager-segment-state-unloaded",
+ Loaded: "replay-manager-segment-state-loaded",
+ Dispatching: "replay-manager-segment-state-dispatching",
+};
+
+WebInspector.ReplayManager.PlaybackSpeed = {
+ RealTime: "replay-manager-playback-speed-real-time",
+ FastForward: "replay-manager-playback-speed-fast-forward",
+};