<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[164986] trunk/Source</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/164986">164986</a></dd>
<dt>Author</dt> <dd>bburg@apple.com</dd>
<dt>Date</dt> <dd>2014-03-03 09:01:11 -0800 (Mon, 03 Mar 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Web Replay: upstream input storage, capture/replay machinery, and inspector domain
https://bugs.webkit.org/show_bug.cgi?id=128782
Source/JavaScriptCore:
Reviewed by Timothy Hatcher.
Alter the replay inputs code generator so that it knows when it is necessary to
to include headers for HEAVY_SCALAR types such as WTF::String and WebCore::URL.
* JavaScriptCore.xcodeproj/project.pbxproj:
* replay/scripts/CodeGeneratorReplayInputs.py:
(Framework.fromString):
(Frameworks): Add WTF as an allowed framework for code generation.
(Generator.generate_includes): Include headers for HEAVY_SCALAR types in the header file.
(Generator.generate_includes.declaration):
(Generator.generate_includes.or):
(Generator.generate_type_forward_declarations): Skip HEAVY_SCALAR types.
Source/WebCore:
Reviewed by Timothy Hatcher, Joseph Pecoraro, and Andreas Kling.
No new tests yet, as they rely on infrastructure tracked in https://webkit.org/b/129190.
Replayable executions are organized into ReplaySessions, which can
contain several ReplaySessionSegments that divide overall execution
at main frame navigation boundaries. NondeterministicInput subclasses
are stored in SegmentedInputStorage according to the input's InputQueue.
Capture and playback are controlled at the page granularity by the Page's
ReplayController. The controller knows how to create new segments, replay to
arbitrary positions in the ReplaySession, and track the active InputCursor.
The capturing and replaying input cursor subclasses encapsulate state for
storing new inputs and loading/dispatching saved inputs, respectively.
The ReplayAgent and associated inspector protocol domain is the friendly
public API for programmatically capturing and replaying sessions.
* DerivedSources.make: Add replay inputs code generation target. Add the
replay domain specification to the list of inspector domains.
* ForwardingHeaders/replay/EncodedValue.h: Added.
* WebCore.xcodeproj/project.pbxproj: Add many files, and export
`WebReplayScripts` environment variable to DerivedSources.make.
* inspector/InspectorController.cpp: Add the replay agent.
(WebCore::InspectorController::InspectorController):
* inspector/InspectorInstrumentation.cpp:
Add events for segment lifecycle events, and loading/unloading of sessions
and segments, and capture/replay progress events. The replay controller
also needs to know about detached and committed frames.
(WebCore::InspectorInstrumentation::frameDetachedFromParentImpl):
(WebCore::InspectorInstrumentation::didCommitLoadImpl):
(WebCore::InspectorInstrumentation::sessionCreatedImpl):
(WebCore::InspectorInstrumentation::sessionLoadedImpl):
(WebCore::InspectorInstrumentation::sessionModifiedImpl):
(WebCore::InspectorInstrumentation::segmentCreatedImpl):
(WebCore::InspectorInstrumentation::segmentCompletedImpl):
(WebCore::InspectorInstrumentation::segmentLoadedImpl):
(WebCore::InspectorInstrumentation::segmentUnloadedImpl):
(WebCore::InspectorInstrumentation::captureStartedImpl):
(WebCore::InspectorInstrumentation::captureStoppedImpl):
(WebCore::InspectorInstrumentation::playbackStartedImpl):
(WebCore::InspectorInstrumentation::playbackPausedImpl):
(WebCore::InspectorInstrumentation::playbackHitPositionImpl):
(WebCore::InspectorInstrumentation::replayAgentEnabled):
* inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::replayAgentEnabled):
(WebCore::InspectorInstrumentation::sessionCreated):
(WebCore::InspectorInstrumentation::sessionLoaded):
(WebCore::InspectorInstrumentation::sessionModified):
(WebCore::InspectorInstrumentation::segmentCreated):
(WebCore::InspectorInstrumentation::segmentCompleted):
(WebCore::InspectorInstrumentation::segmentLoaded):
(WebCore::InspectorInstrumentation::segmentUnloaded):
(WebCore::InspectorInstrumentation::captureStarted):
(WebCore::InspectorInstrumentation::captureStopped):
(WebCore::InspectorInstrumentation::playbackStarted):
(WebCore::InspectorInstrumentation::playbackPaused):
(WebCore::InspectorInstrumentation::playbackHitPosition):
* inspector/InspectorReplayAgent.cpp: Added.
(WebCore::buildInspectorObjectForPosition):
(WebCore::buildInspectorObjectForInput):
(WebCore::buildInspectorObjectForSession):
(WebCore::SerializeInputToJSONFunctor::SerializeInputToJSONFunctor):
(WebCore::SerializeInputToJSONFunctor::~SerializeInputToJSONFunctor):
(WebCore::SerializeInputToJSONFunctor::operator()):
(WebCore::SerializeInputToJSONFunctor::returnValue):
(WebCore::buildInspectorObjectForSegment):
(WebCore::InspectorReplayAgent::InspectorReplayAgent):
(WebCore::InspectorReplayAgent::~InspectorReplayAgent):
(WebCore::InspectorReplayAgent::sessionState):
(WebCore::InspectorReplayAgent::didCreateFrontendAndBackend):
(WebCore::InspectorReplayAgent::willDestroyFrontendAndBackend):
(WebCore::InspectorReplayAgent::frameNavigated):
(WebCore::InspectorReplayAgent::frameDetached):
(WebCore::InspectorReplayAgent::sessionCreated):
(WebCore::InspectorReplayAgent::sessionModified):
(WebCore::InspectorReplayAgent::sessionLoaded):
(WebCore::InspectorReplayAgent::segmentCreated):
(WebCore::InspectorReplayAgent::segmentCompleted):
(WebCore::InspectorReplayAgent::segmentLoaded):
(WebCore::InspectorReplayAgent::segmentUnloaded):
(WebCore::InspectorReplayAgent::captureStarted):
(WebCore::InspectorReplayAgent::captureStopped):
(WebCore::InspectorReplayAgent::playbackStarted):
(WebCore::InspectorReplayAgent::playbackPaused):
(WebCore::InspectorReplayAgent::playbackHitPosition):
(WebCore::InspectorReplayAgent::startCapturing):
(WebCore::InspectorReplayAgent::stopCapturing):
(WebCore::InspectorReplayAgent::replayToPosition):
(WebCore::InspectorReplayAgent::replayToCompletion):
(WebCore::InspectorReplayAgent::pausePlayback):
(WebCore::InspectorReplayAgent::cancelPlayback):
(WebCore::InspectorReplayAgent::switchSession):
(WebCore::InspectorReplayAgent::insertSessionSegment):
(WebCore::InspectorReplayAgent::removeSessionSegment):
Provide a public API for modifying sessions. This is the backend support
for user editing of replay sessions to add/remove specific segments.
(WebCore::InspectorReplayAgent::findSession):
(WebCore::InspectorReplayAgent::findSegment):
(WebCore::InspectorReplayAgent::getAvailableSessions):
(WebCore::InspectorReplayAgent::getSerializedSession):
(WebCore::InspectorReplayAgent::getSerializedSegment):
Most of the replay protocol domain speaks in terms of sesssion and
segment identifiers. These functions return the actual data associated
with these identifiers.
* inspector/InspectorReplayAgent.h: Added.
* inspector/InstrumentingAgents.cpp:
(WebCore::InstrumentingAgents::InstrumentingAgents):
(WebCore::InstrumentingAgents::reset):
* inspector/InstrumentingAgents.h:
(WebCore::InstrumentingAgents::inspectorReplayAgent): Added.
(WebCore::InstrumentingAgents::setInspectorReplayAgent): Added.
* inspector/protocol/Replay.json: Added.
* page/Page.cpp:
(WebCore::Page::Page):
* page/Page.h:
(WebCore::Page::replayController): Added.
* platform/Logging.h: Add WebReplay logging channel.
* replay/AllReplayInputs.h: Added. Simplifies importing all input definitions.
* replay/CapturingInputCursor.cpp: Added.
(WebCore::CapturingInputCursor::CapturingInputCursor):
(WebCore::CapturingInputCursor::~CapturingInputCursor):
(WebCore::CapturingInputCursor::create):
(WebCore::CapturingInputCursor::storeInput):
(WebCore::CapturingInputCursor::loadInput):
(WebCore::CapturingInputCursor::uncheckedLoadInput):
* replay/CapturingInputCursor.h: Added.
* replay/EventLoopInput.h:
(WebCore::EventLoopInputBase::EventLoopInputBase):
(WebCore::EventLoopInputBase::timestamp):
(WebCore::EventLoopInputBase::setTimestamp): Support deserialization.
* replay/EventLoopInputDispatcher.cpp: Added. This class encapsulates the timers
and measurements used to dispatch event loop inputs during replay.
(WebCore::EventLoopInputDispatcher::EventLoopInputDispatcher):
(WebCore::EventLoopInputDispatcher::run):
(WebCore::EventLoopInputDispatcher::pause):
(WebCore::EventLoopInputDispatcher::timerFired):
(WebCore::EventLoopInputDispatcher::dispatchInputSoon):
(WebCore::EventLoopInputDispatcher::dispatchInput):
* replay/EventLoopInputDispatcher.h: Added.
(WebCore::EventLoopInputDispatcherClient::EventLoopInputDispatcherClient):
(WebCore::EventLoopInputDispatcherClient::~EventLoopInputDispatcherClient):
* replay/FunctorInputCursor.h: Added.
(WebCore::FunctorInputCursor::~FunctorInputCursor):
(WebCore::FunctorInputCursor::forEachInputInQueue):
(WebCore::FunctorInputCursor::FunctorInputCursor):
(WebCore::FunctorInputCursor::storeInput):
(WebCore::FunctorInputCursor::loadInput):
(WebCore::FunctorInputCursor::uncheckedLoadInput):
* replay/ReplayController.cpp: Added.
(WebCore::ReplayController::ReplayController):
(WebCore::ReplayController::switchSession):
(WebCore::ReplayController::createSegment):
(WebCore::ReplayController::completeSegment):
(WebCore::ReplayController::loadSegment):
(WebCore::ReplayController::unloadSegment):
(WebCore::ReplayController::startCapturing):
(WebCore::ReplayController::stopCapturing):
(WebCore::ReplayController::startPlayback):
(WebCore::ReplayController::pausePlayback):
(WebCore::ReplayController::cancelPlayback):
(WebCore::ReplayController::replayToPosition):
(WebCore::ReplayController::frameDetached):
(WebCore::ReplayController::frameNavigated):
(WebCore::ReplayController::loadedSession):
(WebCore::ReplayController::loadedSegment):
(WebCore::ReplayController::activeInputCursor):
(WebCore::ReplayController::dispatcher):
(WebCore::ReplayController::willDispatchInput):
(WebCore::ReplayController::didDispatchInput):
(WebCore::ReplayController::didDispatchFinalInput):
* replay/ReplayController.h: Added.
(WebCore::ReplayPosition::ReplayPosition):
(WebCore::ReplayPosition::operator<):
(WebCore::ReplayPosition::operator==):
* replay/ReplayInputCreationMethods.cpp: Added.
Static factory implementations for inputs belong here.
(WebCore::InitialNavigation::createFromPage):
* replay/ReplayInputDispatchMethods.cpp: Added.
All dispatch() implementations for generated replay inputs belong here.
(WebCore::BeginSegmentSentinel::dispatch):
(WebCore::EndSegmentSentinel::dispatch):
(WebCore::InitialNavigation::dispatch):
* replay/ReplayInputTypes.cpp:
(WebCore::ReplayInputTypes::ReplayInputTypes):
* replay/ReplayInputTypes.h: Define strings for WebCore inputs.
* replay/ReplaySession.cpp: Added.
(WebCore::ReplaySession::create):
(WebCore::ReplaySession::ReplaySession):
(WebCore::ReplaySession::~ReplaySession):
(WebCore::ReplaySession::appendSegment):
(WebCore::ReplaySession::insertSegment):
(WebCore::ReplaySession::removeSegment):
* replay/ReplaySession.h: Added.
(WebCore::ReplaySession::identifier):
(WebCore::ReplaySession::timestamp):
(WebCore::ReplaySession::size):
(WebCore::ReplaySession::at):
(WebCore::ReplaySession::begin):
(WebCore::ReplaySession::end):
* replay/ReplaySessionSegment.cpp: Added.
(WebCore::ReplaySessionSegment::create):
(WebCore::ReplaySessionSegment::ReplaySessionSegment):
(WebCore::ReplaySessionSegment::~ReplaySessionSegment):
(WebCore::ReplaySessionSegment::createCapturingCursor):
(WebCore::ReplaySessionSegment::createReplayingCursor):
(WebCore::ReplaySessionSegment::createFunctorCursor):
* replay/ReplaySessionSegment.h: Added.
(WebCore::ReplaySessionSegment::identifier):
(WebCore::ReplaySessionSegment::timestamp):
* replay/ReplayingInputCursor.cpp: Added.
(WebCore::ReplayingInputCursor::ReplayingInputCursor):
(WebCore::ReplayingInputCursor::~ReplayingInputCursor):
(WebCore::ReplayingInputCursor::create):
(WebCore::ReplayingInputCursor::storeInput):
(WebCore::ReplayingInputCursor::loadInput):
(WebCore::ReplayingInputCursor::uncheckedLoadInput):
* replay/ReplayingInputCursor.h: Added.
* replay/SegmentedInputStorage.cpp: Added.
(WebCore::queueTypeToLogPrefix):
(WebCore::jsonStringForInput):
(WebCore::offsetForInputQueue):
(WebCore::SegmentedInputStorage::SegmentedInputStorage):
(WebCore::SegmentedInputStorage::~SegmentedInputStorage):
(WebCore::SegmentedInputStorage::load):
(WebCore::SegmentedInputStorage::store):
(WebCore::SegmentedInputStorage::queueSize):
* replay/SegmentedInputStorage.h: Added.
* replay/SerializationMethods.cpp: Added.
Specializations of EncodingTraits for WebCore types belong here.
(JSC::EncodingTraits<NondeterministicInputBase>::encodeValue):
(JSC::EncodingTraits<NondeterministicInputBase>::decodeValue):
(JSC::EncodingTraits<SecurityOrigin>::encodeValue):
(JSC::EncodingTraits<SecurityOrigin>::decodeValue):
(JSC::EncodingTraits<URL>::encodeValue):
(JSC::EncodingTraits<URL>::decodeValue):
* replay/SerializationMethods.h: Added.
* replay/WebInputs.json: Added.
In this inital patch, we define BeginSegmentSentinel,
EndSegmentSentinel, and InitialNavigation inputs.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorereplayscriptsCodeGeneratorReplayInputspy">trunk/Source/JavaScriptCore/replay/scripts/CodeGeneratorReplayInputs.py</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreDerivedSourcesmake">trunk/Source/WebCore/DerivedSources.make</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorControllercpp">trunk/Source/WebCore/inspector/InspectorController.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorInstrumentationcpp">trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorInstrumentationh">trunk/Source/WebCore/inspector/InspectorInstrumentation.h</a></li>
<li><a href="#trunkSourceWebCoreinspectorInstrumentingAgentscpp">trunk/Source/WebCore/inspector/InstrumentingAgents.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInstrumentingAgentsh">trunk/Source/WebCore/inspector/InstrumentingAgents.h</a></li>
<li><a href="#trunkSourceWebCoremakegeneratedsourcessh">trunk/Source/WebCore/make-generated-sources.sh</a></li>
<li><a href="#trunkSourceWebCorepagePagecpp">trunk/Source/WebCore/page/Page.cpp</a></li>
<li><a href="#trunkSourceWebCorepagePageh">trunk/Source/WebCore/page/Page.h</a></li>
<li><a href="#trunkSourceWebCoreplatformLoggingh">trunk/Source/WebCore/platform/Logging.h</a></li>
<li><a href="#trunkSourceWebCorereplayEventLoopInputh">trunk/Source/WebCore/replay/EventLoopInput.h</a></li>
<li><a href="#trunkSourceWebCorereplayReplayInputTypescpp">trunk/Source/WebCore/replay/ReplayInputTypes.cpp</a></li>
<li><a href="#trunkSourceWebCorereplayReplayInputTypesh">trunk/Source/WebCore/replay/ReplayInputTypes.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreForwardingHeadersreplayEncodedValueh">trunk/Source/WebCore/ForwardingHeaders/replay/EncodedValue.h</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorReplayAgentcpp">trunk/Source/WebCore/inspector/InspectorReplayAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorReplayAgenth">trunk/Source/WebCore/inspector/InspectorReplayAgent.h</a></li>
<li><a href="#trunkSourceWebCoreinspectorprotocolReplayjson">trunk/Source/WebCore/inspector/protocol/Replay.json</a></li>
<li><a href="#trunkSourceWebCorereplayAllReplayInputsh">trunk/Source/WebCore/replay/AllReplayInputs.h</a></li>
<li><a href="#trunkSourceWebCorereplayCapturingInputCursorcpp">trunk/Source/WebCore/replay/CapturingInputCursor.cpp</a></li>
<li><a href="#trunkSourceWebCorereplayCapturingInputCursorh">trunk/Source/WebCore/replay/CapturingInputCursor.h</a></li>
<li><a href="#trunkSourceWebCorereplayEventLoopInputDispatchercpp">trunk/Source/WebCore/replay/EventLoopInputDispatcher.cpp</a></li>
<li><a href="#trunkSourceWebCorereplayEventLoopInputDispatcherh">trunk/Source/WebCore/replay/EventLoopInputDispatcher.h</a></li>
<li><a href="#trunkSourceWebCorereplayFunctorInputCursorh">trunk/Source/WebCore/replay/FunctorInputCursor.h</a></li>
<li><a href="#trunkSourceWebCorereplayReplayControllercpp">trunk/Source/WebCore/replay/ReplayController.cpp</a></li>
<li><a href="#trunkSourceWebCorereplayReplayControllerh">trunk/Source/WebCore/replay/ReplayController.h</a></li>
<li><a href="#trunkSourceWebCorereplayReplayInputCreationMethodscpp">trunk/Source/WebCore/replay/ReplayInputCreationMethods.cpp</a></li>
<li><a href="#trunkSourceWebCorereplayReplayInputDispatchMethodscpp">trunk/Source/WebCore/replay/ReplayInputDispatchMethods.cpp</a></li>
<li><a href="#trunkSourceWebCorereplayReplaySessioncpp">trunk/Source/WebCore/replay/ReplaySession.cpp</a></li>
<li><a href="#trunkSourceWebCorereplayReplaySessionh">trunk/Source/WebCore/replay/ReplaySession.h</a></li>
<li><a href="#trunkSourceWebCorereplayReplaySessionSegmentcpp">trunk/Source/WebCore/replay/ReplaySessionSegment.cpp</a></li>
<li><a href="#trunkSourceWebCorereplayReplaySessionSegmenth">trunk/Source/WebCore/replay/ReplaySessionSegment.h</a></li>
<li><a href="#trunkSourceWebCorereplayReplayingInputCursorcpp">trunk/Source/WebCore/replay/ReplayingInputCursor.cpp</a></li>
<li><a href="#trunkSourceWebCorereplayReplayingInputCursorh">trunk/Source/WebCore/replay/ReplayingInputCursor.h</a></li>
<li><a href="#trunkSourceWebCorereplaySegmentedInputStoragecpp">trunk/Source/WebCore/replay/SegmentedInputStorage.cpp</a></li>
<li><a href="#trunkSourceWebCorereplaySegmentedInputStorageh">trunk/Source/WebCore/replay/SegmentedInputStorage.h</a></li>
<li><a href="#trunkSourceWebCorereplaySerializationMethodscpp">trunk/Source/WebCore/replay/SerializationMethods.cpp</a></li>
<li><a href="#trunkSourceWebCorereplaySerializationMethodsh">trunk/Source/WebCore/replay/SerializationMethods.h</a></li>
<li><a href="#trunkSourceWebCorereplayWebInputsjson">trunk/Source/WebCore/replay/WebInputs.json</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2014-03-03 Brian Burg <bburg@apple.com>
+
+ Web Replay: upstream input storage, capture/replay machinery, and inspector domain
+ https://bugs.webkit.org/show_bug.cgi?id=128782
+
+ Reviewed by Timothy Hatcher.
+
+ Alter the replay inputs code generator so that it knows when it is necessary to
+ to include headers for HEAVY_SCALAR types such as WTF::String and WebCore::URL.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * replay/scripts/CodeGeneratorReplayInputs.py:
+ (Framework.fromString):
+ (Frameworks): Add WTF as an allowed framework for code generation.
+ (Generator.generate_includes): Include headers for HEAVY_SCALAR types in the header file.
+ (Generator.generate_includes.declaration):
+ (Generator.generate_includes.or):
+ (Generator.generate_type_forward_declarations): Skip HEAVY_SCALAR types.
+
</ins><span class="cx"> 2014-03-02 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><span class="cx"> PolymorphicPutByIdList should have a simpler construction API with basically a single entrypoint
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -961,6 +961,8 @@
</span><span class="cx">                 978801411471AD920041B016 /* JSDateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 9788FC231471AD0C0068CE2D /* JSDateMath.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 9928FF3B18AC4AEC00B8CF12 /* JSReplayInputs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9928FF3918AC4AEC00B8CF12 /* JSReplayInputs.cpp */; };
</span><span class="cx">                 9928FF3C18AC4AEC00B8CF12 /* JSReplayInputs.h in Headers */ = {isa = PBXBuildFile; fileRef = 9928FF3A18AC4AEC00B8CF12 /* JSReplayInputs.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                99CC0B6218BE9946006CEBCC /* CodeGeneratorReplayInputsTemplates.py in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A1E18A1B1E70026D88F /* CodeGeneratorReplayInputsTemplates.py */; settings = {ATTRIBUTES = (Private, ); }; };
+                99CC0B6318BE9950006CEBCC /* CodeGeneratorReplayInputs.py in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A1D18A1B1E70026D88F /* CodeGeneratorReplayInputs.py */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 99E45A2418A1B2590026D88F /* EmptyInputCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A1F18A1B2590026D88F /* EmptyInputCursor.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 99E45A2518A1B2590026D88F /* EncodedValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E45A2018A1B2590026D88F /* EncodedValue.cpp */; };
</span><span class="cx">                 99E45A2618A1B2590026D88F /* EncodedValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A2118A1B2590026D88F /* EncodedValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -5471,6 +5473,7 @@
</span><span class="cx">                                 86EBF3041560F06A008E9222 /* NamePrototype.h in Headers */,
</span><span class="cx">                                 BC02E9110E1839DB000F9297 /* NativeErrorConstructor.h in Headers */,
</span><span class="cx">                                 BC02E9130E1839DB000F9297 /* NativeErrorPrototype.h in Headers */,
</span><ins>+                                99CC0B6318BE9950006CEBCC /* CodeGeneratorReplayInputs.py in Headers */,
</ins><span class="cx">                                 0FFB922016D033B70055A5DB /* NodeConstructors.h in Headers */,
</span><span class="cx">                                 7EFF00640EC05A9A00AA7C93 /* NodeInfo.h in Headers */,
</span><span class="cx">                                 BC18C43F0E16F5CD00B34460 /* Nodes.h in Headers */,
</span><span class="lines">@@ -5479,6 +5482,7 @@
</span><span class="cx">                                 BC18C4420E16F5CD00B34460 /* NumberConstructor.lut.h in Headers */,
</span><span class="cx">                                 BC18C4430E16F5CD00B34460 /* NumberObject.h in Headers */,
</span><span class="cx">                                 BC18C4440E16F5CD00B34460 /* NumberPrototype.h in Headers */,
</span><ins>+                                99CC0B6218BE9946006CEBCC /* CodeGeneratorReplayInputsTemplates.py in Headers */,
</ins><span class="cx">                                 142D3939103E4560007DCB52 /* NumericStrings.h in Headers */,
</span><span class="cx">                                 86F3EEBD168CDE930077B92A /* ObjCCallbackFunction.h in Headers */,
</span><span class="cx">                                 86F3EEBF168CDE930077B92A /* ObjcRuntimeExtras.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorereplayscriptsCodeGeneratorReplayInputspy"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/replay/scripts/CodeGeneratorReplayInputs.py (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/replay/scripts/CodeGeneratorReplayInputs.py        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/JavaScriptCore/replay/scripts/CodeGeneratorReplayInputs.py        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -103,6 +103,10 @@
</span><span class="cx"> "namespace": ""
</span><span class="cx"> },
</span><span class="cx">
</span><ins>+ "WTF": {
+ "prefix": "WTF",
+ "namespace": "WTF",
+ },
</ins><span class="cx"> "JavaScriptCore": {
</span><span class="cx"> "prefix": "JS",
</span><span class="cx"> "namespace": "JSC",
</span><span class="lines">@@ -166,6 +170,9 @@
</span><span class="cx"> if frameworkString == "Global":
</span><span class="cx"> return Frameworks.Global
</span><span class="cx">
</span><ins>+ if frameworkString == "WTF":
+ return Frameworks.WTF
+
</ins><span class="cx"> if frameworkString == "JavaScriptCore":
</span><span class="cx"> return Frameworks.JavaScriptCore
</span><span class="cx">
</span><span class="lines">@@ -180,6 +187,7 @@
</span><span class="cx">
</span><span class="cx"> class Frameworks:
</span><span class="cx"> Global = Framework("Global")
</span><ins>+ WTF = Framework("WTF")
</ins><span class="cx"> JavaScriptCore = Framework("JavaScriptCore")
</span><span class="cx"> WebCore = Framework("WebCore")
</span><span class="cx"> Test = Framework("Test")
</span><span class="lines">@@ -616,11 +624,14 @@
</span><span class="cx"> if _type.framework is Frameworks.Global:
</span><span class="cx"> continue
</span><span class="cx"> # For RefCounted types, we reverse when to include the header so that the destructor can be
</span><del>- # used in the header file. Enums within classes cannot be forward declared, so we include
</del><ins>+ # used in the header file.
+ include_for_destructor = _type.mode is TypeModes.SHARED
+ # Enums within classes cannot be forward declared, so we include
</ins><span class="cx"> # headers with the relevant class declaration.
</span><del>- include_for_destructor = _type.mode is TypeModes.SHARED
</del><span class="cx"> include_for_enclosing_class = _type.is_enum() and _type.enclosing_class is not None
</span><del>- if (not includes_for_types) ^ (include_for_destructor or include_for_enclosing_class):
</del><ins>+ # Include headers for types like URL and String which are copied, not owned or shared.
+ include_for_copyable_member = _type.mode is TypeModes.HEAVY_SCALAR or _type.mode is TypeModes.SCALAR
+ if (not includes_for_types) ^ (include_for_destructor or include_for_enclosing_class or include_for_copyable_member):
</ins><span class="cx"> continue
</span><span class="cx">
</span><span class="cx"> if self.target_framework != _type.framework:
</span><span class="lines">@@ -654,6 +665,8 @@
</span><span class="cx"> continue
</span><span class="cx"> if _type.enclosing_class is not None:
</span><span class="cx"> continue
</span><ins>+ if _type.mode == TypeModes.SCALAR or _type.mode == TypeModes.HEAVY_SCALAR:
+ continue
</ins><span class="cx"> if _type.is_enum():
</span><span class="cx"> declaration = "enum %s : %s;" % (_type.type_name(), _type.underlying_storage)
</span><span class="cx"> else:
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/ChangeLog        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -1,3 +1,273 @@
</span><ins>+2014-03-03 Brian Burg <bburg@apple.com>
+
+ Web Replay: upstream input storage, capture/replay machinery, and inspector domain
+ https://bugs.webkit.org/show_bug.cgi?id=128782
+
+ Reviewed by Timothy Hatcher, Joseph Pecoraro, and Andreas Kling.
+
+ No new tests yet, as they rely on infrastructure tracked in https://webkit.org/b/129190.
+
+ Replayable executions are organized into ReplaySessions, which can
+ contain several ReplaySessionSegments that divide overall execution
+ at main frame navigation boundaries. NondeterministicInput subclasses
+ are stored in SegmentedInputStorage according to the input's InputQueue.
+
+ Capture and playback are controlled at the page granularity by the Page's
+ ReplayController. The controller knows how to create new segments, replay to
+ arbitrary positions in the ReplaySession, and track the active InputCursor.
+
+ The capturing and replaying input cursor subclasses encapsulate state for
+ storing new inputs and loading/dispatching saved inputs, respectively.
+
+ The ReplayAgent and associated inspector protocol domain is the friendly
+ public API for programmatically capturing and replaying sessions.
+
+ * DerivedSources.make: Add replay inputs code generation target. Add the
+ replay domain specification to the list of inspector domains.
+
+ * ForwardingHeaders/replay/EncodedValue.h: Added.
+ * WebCore.xcodeproj/project.pbxproj: Add many files, and export
+ `WebReplayScripts` environment variable to DerivedSources.make.
+
+ * inspector/InspectorController.cpp: Add the replay agent.
+ (WebCore::InspectorController::InspectorController):
+
+ * inspector/InspectorInstrumentation.cpp:
+ Add events for segment lifecycle events, and loading/unloading of sessions
+ and segments, and capture/replay progress events. The replay controller
+ also needs to know about detached and committed frames.
+
+ (WebCore::InspectorInstrumentation::frameDetachedFromParentImpl):
+ (WebCore::InspectorInstrumentation::didCommitLoadImpl):
+ (WebCore::InspectorInstrumentation::sessionCreatedImpl):
+ (WebCore::InspectorInstrumentation::sessionLoadedImpl):
+ (WebCore::InspectorInstrumentation::sessionModifiedImpl):
+ (WebCore::InspectorInstrumentation::segmentCreatedImpl):
+ (WebCore::InspectorInstrumentation::segmentCompletedImpl):
+ (WebCore::InspectorInstrumentation::segmentLoadedImpl):
+ (WebCore::InspectorInstrumentation::segmentUnloadedImpl):
+ (WebCore::InspectorInstrumentation::captureStartedImpl):
+ (WebCore::InspectorInstrumentation::captureStoppedImpl):
+ (WebCore::InspectorInstrumentation::playbackStartedImpl):
+ (WebCore::InspectorInstrumentation::playbackPausedImpl):
+ (WebCore::InspectorInstrumentation::playbackHitPositionImpl):
+ (WebCore::InspectorInstrumentation::replayAgentEnabled):
+ * inspector/InspectorInstrumentation.h:
+ (WebCore::InspectorInstrumentation::replayAgentEnabled):
+ (WebCore::InspectorInstrumentation::sessionCreated):
+ (WebCore::InspectorInstrumentation::sessionLoaded):
+ (WebCore::InspectorInstrumentation::sessionModified):
+ (WebCore::InspectorInstrumentation::segmentCreated):
+ (WebCore::InspectorInstrumentation::segmentCompleted):
+ (WebCore::InspectorInstrumentation::segmentLoaded):
+ (WebCore::InspectorInstrumentation::segmentUnloaded):
+ (WebCore::InspectorInstrumentation::captureStarted):
+ (WebCore::InspectorInstrumentation::captureStopped):
+ (WebCore::InspectorInstrumentation::playbackStarted):
+ (WebCore::InspectorInstrumentation::playbackPaused):
+ (WebCore::InspectorInstrumentation::playbackHitPosition):
+
+ * inspector/InspectorReplayAgent.cpp: Added.
+ (WebCore::buildInspectorObjectForPosition):
+ (WebCore::buildInspectorObjectForInput):
+ (WebCore::buildInspectorObjectForSession):
+ (WebCore::SerializeInputToJSONFunctor::SerializeInputToJSONFunctor):
+ (WebCore::SerializeInputToJSONFunctor::~SerializeInputToJSONFunctor):
+ (WebCore::SerializeInputToJSONFunctor::operator()):
+ (WebCore::SerializeInputToJSONFunctor::returnValue):
+ (WebCore::buildInspectorObjectForSegment):
+ (WebCore::InspectorReplayAgent::InspectorReplayAgent):
+ (WebCore::InspectorReplayAgent::~InspectorReplayAgent):
+ (WebCore::InspectorReplayAgent::sessionState):
+ (WebCore::InspectorReplayAgent::didCreateFrontendAndBackend):
+ (WebCore::InspectorReplayAgent::willDestroyFrontendAndBackend):
+ (WebCore::InspectorReplayAgent::frameNavigated):
+ (WebCore::InspectorReplayAgent::frameDetached):
+ (WebCore::InspectorReplayAgent::sessionCreated):
+ (WebCore::InspectorReplayAgent::sessionModified):
+ (WebCore::InspectorReplayAgent::sessionLoaded):
+ (WebCore::InspectorReplayAgent::segmentCreated):
+ (WebCore::InspectorReplayAgent::segmentCompleted):
+ (WebCore::InspectorReplayAgent::segmentLoaded):
+ (WebCore::InspectorReplayAgent::segmentUnloaded):
+ (WebCore::InspectorReplayAgent::captureStarted):
+ (WebCore::InspectorReplayAgent::captureStopped):
+ (WebCore::InspectorReplayAgent::playbackStarted):
+ (WebCore::InspectorReplayAgent::playbackPaused):
+ (WebCore::InspectorReplayAgent::playbackHitPosition):
+ (WebCore::InspectorReplayAgent::startCapturing):
+ (WebCore::InspectorReplayAgent::stopCapturing):
+ (WebCore::InspectorReplayAgent::replayToPosition):
+ (WebCore::InspectorReplayAgent::replayToCompletion):
+ (WebCore::InspectorReplayAgent::pausePlayback):
+ (WebCore::InspectorReplayAgent::cancelPlayback):
+ (WebCore::InspectorReplayAgent::switchSession):
+ (WebCore::InspectorReplayAgent::insertSessionSegment):
+ (WebCore::InspectorReplayAgent::removeSessionSegment):
+ Provide a public API for modifying sessions. This is the backend support
+ for user editing of replay sessions to add/remove specific segments.
+
+ (WebCore::InspectorReplayAgent::findSession):
+ (WebCore::InspectorReplayAgent::findSegment):
+ (WebCore::InspectorReplayAgent::getAvailableSessions):
+ (WebCore::InspectorReplayAgent::getSerializedSession):
+ (WebCore::InspectorReplayAgent::getSerializedSegment):
+ Most of the replay protocol domain speaks in terms of sesssion and
+ segment identifiers. These functions return the actual data associated
+ with these identifiers.
+
+ * inspector/InspectorReplayAgent.h: Added.
+ * inspector/InstrumentingAgents.cpp:
+ (WebCore::InstrumentingAgents::InstrumentingAgents):
+ (WebCore::InstrumentingAgents::reset):
+ * inspector/InstrumentingAgents.h:
+ (WebCore::InstrumentingAgents::inspectorReplayAgent): Added.
+ (WebCore::InstrumentingAgents::setInspectorReplayAgent): Added.
+ * inspector/protocol/Replay.json: Added.
+
+ * page/Page.cpp:
+ (WebCore::Page::Page):
+ * page/Page.h:
+ (WebCore::Page::replayController): Added.
+ * platform/Logging.h: Add WebReplay logging channel.
+ * replay/AllReplayInputs.h: Added. Simplifies importing all input definitions.
+
+ * replay/CapturingInputCursor.cpp: Added.
+ (WebCore::CapturingInputCursor::CapturingInputCursor):
+ (WebCore::CapturingInputCursor::~CapturingInputCursor):
+ (WebCore::CapturingInputCursor::create):
+ (WebCore::CapturingInputCursor::storeInput):
+ (WebCore::CapturingInputCursor::loadInput):
+ (WebCore::CapturingInputCursor::uncheckedLoadInput):
+ * replay/CapturingInputCursor.h: Added.
+
+ * replay/EventLoopInput.h:
+ (WebCore::EventLoopInputBase::EventLoopInputBase):
+ (WebCore::EventLoopInputBase::timestamp):
+ (WebCore::EventLoopInputBase::setTimestamp): Support deserialization.
+
+ * replay/EventLoopInputDispatcher.cpp: Added. This class encapsulates the timers
+ and measurements used to dispatch event loop inputs during replay.
+
+ (WebCore::EventLoopInputDispatcher::EventLoopInputDispatcher):
+ (WebCore::EventLoopInputDispatcher::run):
+ (WebCore::EventLoopInputDispatcher::pause):
+ (WebCore::EventLoopInputDispatcher::timerFired):
+ (WebCore::EventLoopInputDispatcher::dispatchInputSoon):
+ (WebCore::EventLoopInputDispatcher::dispatchInput):
+ * replay/EventLoopInputDispatcher.h: Added.
+ (WebCore::EventLoopInputDispatcherClient::EventLoopInputDispatcherClient):
+ (WebCore::EventLoopInputDispatcherClient::~EventLoopInputDispatcherClient):
+
+ * replay/FunctorInputCursor.h: Added.
+ (WebCore::FunctorInputCursor::~FunctorInputCursor):
+ (WebCore::FunctorInputCursor::forEachInputInQueue):
+ (WebCore::FunctorInputCursor::FunctorInputCursor):
+ (WebCore::FunctorInputCursor::storeInput):
+ (WebCore::FunctorInputCursor::loadInput):
+ (WebCore::FunctorInputCursor::uncheckedLoadInput):
+
+ * replay/ReplayController.cpp: Added.
+ (WebCore::ReplayController::ReplayController):
+ (WebCore::ReplayController::switchSession):
+ (WebCore::ReplayController::createSegment):
+ (WebCore::ReplayController::completeSegment):
+ (WebCore::ReplayController::loadSegment):
+ (WebCore::ReplayController::unloadSegment):
+ (WebCore::ReplayController::startCapturing):
+ (WebCore::ReplayController::stopCapturing):
+ (WebCore::ReplayController::startPlayback):
+ (WebCore::ReplayController::pausePlayback):
+ (WebCore::ReplayController::cancelPlayback):
+ (WebCore::ReplayController::replayToPosition):
+ (WebCore::ReplayController::frameDetached):
+ (WebCore::ReplayController::frameNavigated):
+ (WebCore::ReplayController::loadedSession):
+ (WebCore::ReplayController::loadedSegment):
+ (WebCore::ReplayController::activeInputCursor):
+ (WebCore::ReplayController::dispatcher):
+ (WebCore::ReplayController::willDispatchInput):
+ (WebCore::ReplayController::didDispatchInput):
+ (WebCore::ReplayController::didDispatchFinalInput):
+ * replay/ReplayController.h: Added.
+ (WebCore::ReplayPosition::ReplayPosition):
+ (WebCore::ReplayPosition::operator<):
+ (WebCore::ReplayPosition::operator==):
+
+ * replay/ReplayInputCreationMethods.cpp: Added.
+ Static factory implementations for inputs belong here.
+ (WebCore::InitialNavigation::createFromPage):
+
+ * replay/ReplayInputDispatchMethods.cpp: Added.
+ All dispatch() implementations for generated replay inputs belong here.
+ (WebCore::BeginSegmentSentinel::dispatch):
+ (WebCore::EndSegmentSentinel::dispatch):
+ (WebCore::InitialNavigation::dispatch):
+
+ * replay/ReplayInputTypes.cpp:
+ (WebCore::ReplayInputTypes::ReplayInputTypes):
+ * replay/ReplayInputTypes.h: Define strings for WebCore inputs.
+
+ * replay/ReplaySession.cpp: Added.
+ (WebCore::ReplaySession::create):
+ (WebCore::ReplaySession::ReplaySession):
+ (WebCore::ReplaySession::~ReplaySession):
+ (WebCore::ReplaySession::appendSegment):
+ (WebCore::ReplaySession::insertSegment):
+ (WebCore::ReplaySession::removeSegment):
+ * replay/ReplaySession.h: Added.
+ (WebCore::ReplaySession::identifier):
+ (WebCore::ReplaySession::timestamp):
+ (WebCore::ReplaySession::size):
+ (WebCore::ReplaySession::at):
+ (WebCore::ReplaySession::begin):
+ (WebCore::ReplaySession::end):
+
+ * replay/ReplaySessionSegment.cpp: Added.
+ (WebCore::ReplaySessionSegment::create):
+ (WebCore::ReplaySessionSegment::ReplaySessionSegment):
+ (WebCore::ReplaySessionSegment::~ReplaySessionSegment):
+ (WebCore::ReplaySessionSegment::createCapturingCursor):
+ (WebCore::ReplaySessionSegment::createReplayingCursor):
+ (WebCore::ReplaySessionSegment::createFunctorCursor):
+ * replay/ReplaySessionSegment.h: Added.
+ (WebCore::ReplaySessionSegment::identifier):
+ (WebCore::ReplaySessionSegment::timestamp):
+
+ * replay/ReplayingInputCursor.cpp: Added.
+ (WebCore::ReplayingInputCursor::ReplayingInputCursor):
+ (WebCore::ReplayingInputCursor::~ReplayingInputCursor):
+ (WebCore::ReplayingInputCursor::create):
+ (WebCore::ReplayingInputCursor::storeInput):
+ (WebCore::ReplayingInputCursor::loadInput):
+ (WebCore::ReplayingInputCursor::uncheckedLoadInput):
+ * replay/ReplayingInputCursor.h: Added.
+
+ * replay/SegmentedInputStorage.cpp: Added.
+ (WebCore::queueTypeToLogPrefix):
+ (WebCore::jsonStringForInput):
+ (WebCore::offsetForInputQueue):
+ (WebCore::SegmentedInputStorage::SegmentedInputStorage):
+ (WebCore::SegmentedInputStorage::~SegmentedInputStorage):
+ (WebCore::SegmentedInputStorage::load):
+ (WebCore::SegmentedInputStorage::store):
+ (WebCore::SegmentedInputStorage::queueSize):
+ * replay/SegmentedInputStorage.h: Added.
+
+ * replay/SerializationMethods.cpp: Added.
+ Specializations of EncodingTraits for WebCore types belong here.
+
+ (JSC::EncodingTraits<NondeterministicInputBase>::encodeValue):
+ (JSC::EncodingTraits<NondeterministicInputBase>::decodeValue):
+ (JSC::EncodingTraits<SecurityOrigin>::encodeValue):
+ (JSC::EncodingTraits<SecurityOrigin>::decodeValue):
+ (JSC::EncodingTraits<URL>::encodeValue):
+ (JSC::EncodingTraits<URL>::decodeValue):
+ * replay/SerializationMethods.h: Added.
+ * replay/WebInputs.json: Added.
+ In this inital patch, we define BeginSegmentSentinel,
+ EndSegmentSentinel, and InitialNavigation inputs.
+
</ins><span class="cx"> 2014-03-03 Antoine Quint <graouts@webkit.org>
</span><span class="cx">
</span><span class="cx"> Respect SVG fragment identifiers in <img> src attribute
</span></span></pre></div>
<a id="trunkSourceWebCoreDerivedSourcesmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/DerivedSources.make (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/DerivedSources.make        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/DerivedSources.make        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -1109,6 +1109,7 @@
</span><span class="cx"> $(WebCore)/inspector/protocol/Network.json \
</span><span class="cx"> $(WebCore)/inspector/protocol/Page.json \
</span><span class="cx"> $(WebCore)/inspector/protocol/Profiler.json \
</span><ins>+ $(WebCore)/inspector/protocol/Replay.json \
</ins><span class="cx"> $(WebCore)/inspector/protocol/Timeline.json \
</span><span class="cx"> $(WebCore)/inspector/protocol/Worker.json \
</span><span class="cx"> #
</span><span class="lines">@@ -1142,6 +1143,22 @@
</span><span class="cx">         perl $(InspectorScripts)/xxd.pl CommandLineAPIModuleSource_js ./CommandLineAPIModuleSource.min.js CommandLineAPIModuleSource.h
</span><span class="cx">         rm -f ./CommandLineAPIModuleSource.min.js
</span><span class="cx">
</span><ins>+# Web Replay inputs generator
+
+INPUT_GENERATOR_SCRIPTS = \
+ $(WebReplayScripts)/CodeGeneratorReplayInputs.py \
+ $(WebReplayScripts)/CodeGeneratorReplayInputsTemplates.py \
+#
+
+INPUT_GENERATOR_SPECIFICATIONS = \
+        $(WebCore)/replay/WebInputs.json \
+#
+
+all : WebReplayInputs.h
+
+WebReplayInputs.h : $(INPUT_GENERATOR_SPECIFICATIONS) $(INPUT_GENERATOR_SCRIPTS)
+        python $(WebReplayScripts)/CodeGeneratorReplayInputs.py --outputDir . --framework WebCore $(INPUT_GENERATOR_SPECIFICATIONS)
+
</ins><span class="cx"> -include $(JS_DOM_HEADERS:.h=.dep)
</span><span class="cx">
</span><span class="cx"> # ------------------------
</span></span></pre></div>
<a id="trunkSourceWebCoreForwardingHeadersreplayEncodedValueh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/ForwardingHeaders/replay/EncodedValue.h (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ForwardingHeaders/replay/EncodedValue.h         (rev 0)
+++ trunk/Source/WebCore/ForwardingHeaders/replay/EncodedValue.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+#ifndef WebCore_FWD_EncodedValue_h
+#define WebCore_FWD_EncodedValue_h
+#include <JavaScriptCore/EncodedValue.h>
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -3497,6 +3497,31 @@
</span><span class="cx">                 990A1A0518ADA48400183FD1 /* ReplayInputTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 990A19F518ADA48400183FD1 /* ReplayInputTypes.h */; };
</span><span class="cx">                 9920398218B95BC600B39AF9 /* UserInputBridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9920398018B95BC600B39AF9 /* UserInputBridge.cpp */; };
</span><span class="cx">                 9920398318B95BC600B39AF9 /* UserInputBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 9920398118B95BC600B39AF9 /* UserInputBridge.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                99CC0B4D18BE9849006CEBCC /* AllReplayInputs.h in Headers */ = {isa = PBXBuildFile; fileRef = 99CC0B3818BE9849006CEBCC /* AllReplayInputs.h */; };
+                99CC0B4E18BE9849006CEBCC /* CapturingInputCursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99CC0B3918BE9849006CEBCC /* CapturingInputCursor.cpp */; };
+                99CC0B4F18BE9849006CEBCC /* CapturingInputCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 99CC0B3A18BE9849006CEBCC /* CapturingInputCursor.h */; };
+                99CC0B5018BE9849006CEBCC /* EventLoopInputDispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99CC0B3B18BE9849006CEBCC /* EventLoopInputDispatcher.cpp */; };
+                99CC0B5118BE9849006CEBCC /* EventLoopInputDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 99CC0B3C18BE9849006CEBCC /* EventLoopInputDispatcher.h */; };
+                99CC0B5218BE9849006CEBCC /* FunctorInputCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 99CC0B3D18BE9849006CEBCC /* FunctorInputCursor.h */; };
+                99CC0B5318BE9849006CEBCC /* ReplayController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99CC0B3E18BE9849006CEBCC /* ReplayController.cpp */; };
+                99CC0B5418BE9849006CEBCC /* ReplayController.h in Headers */ = {isa = PBXBuildFile; fileRef = 99CC0B3F18BE9849006CEBCC /* ReplayController.h */; };
+                99CC0B5518BE9849006CEBCC /* ReplayingInputCursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99CC0B4018BE9849006CEBCC /* ReplayingInputCursor.cpp */; };
+                99CC0B5618BE984A006CEBCC /* ReplayingInputCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 99CC0B4118BE9849006CEBCC /* ReplayingInputCursor.h */; };
+                99CC0B5718BE984A006CEBCC /* ReplayInputCreationMethods.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99CC0B4218BE9849006CEBCC /* ReplayInputCreationMethods.cpp */; };
+                99CC0B5818BE984A006CEBCC /* ReplayInputDispatchMethods.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99CC0B4318BE9849006CEBCC /* ReplayInputDispatchMethods.cpp */; };
+                99CC0B5918BE984A006CEBCC /* ReplaySession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99CC0B4418BE9849006CEBCC /* ReplaySession.cpp */; };
+                99CC0B5A18BE984A006CEBCC /* ReplaySession.h in Headers */ = {isa = PBXBuildFile; fileRef = 99CC0B4518BE9849006CEBCC /* ReplaySession.h */; };
+                99CC0B5B18BE984A006CEBCC /* ReplaySessionSegment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99CC0B4618BE9849006CEBCC /* ReplaySessionSegment.cpp */; };
+                99CC0B5C18BE984A006CEBCC /* ReplaySessionSegment.h in Headers */ = {isa = PBXBuildFile; fileRef = 99CC0B4718BE9849006CEBCC /* ReplaySessionSegment.h */; };
+                99CC0B5D18BE984A006CEBCC /* SegmentedInputStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99CC0B4818BE9849006CEBCC /* SegmentedInputStorage.cpp */; };
+                99CC0B5E18BE984A006CEBCC /* SegmentedInputStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 99CC0B4918BE9849006CEBCC /* SegmentedInputStorage.h */; };
+                99CC0B5F18BE984A006CEBCC /* SerializationMethods.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99CC0B4A18BE9849006CEBCC /* SerializationMethods.cpp */; };
+                99CC0B6018BE984A006CEBCC /* SerializationMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 99CC0B4B18BE9849006CEBCC /* SerializationMethods.h */; };
+                99CC0B6118BE984A006CEBCC /* WebInputs.json in Resources */ = {isa = PBXBuildFile; fileRef = 99CC0B4C18BE9849006CEBCC /* WebInputs.json */; };
+                99CC0B6618BE9F15006CEBCC /* InspectorReplayAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99CC0B6418BE9F15006CEBCC /* InspectorReplayAgent.cpp */; };
+                99CC0B6718BE9F15006CEBCC /* InspectorReplayAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 99CC0B6518BE9F15006CEBCC /* InspectorReplayAgent.h */; };
+                99CC0B6A18BEA1FF006CEBCC /* WebReplayInputs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99CC0B6818BEA1FF006CEBCC /* WebReplayInputs.cpp */; };
+                99CC0B6B18BEA1FF006CEBCC /* WebReplayInputs.h in Headers */ = {isa = PBXBuildFile; fileRef = 99CC0B6918BEA1FF006CEBCC /* WebReplayInputs.h */; };
</ins><span class="cx">                 99E45A1718A063BE0026D88F /* EventLoopInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A1618A063BE0026D88F /* EventLoopInput.h */; };
</span><span class="cx">                 9A1142041832D135000BB8AD /* ValueToString.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A1142031832D134000BB8AD /* ValueToString.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 9A1B6F97158869C80011A8C4 /* JSDOMStringListCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A1B6F96158869C80011A8C4 /* JSDOMStringListCustom.cpp */; };
</span><span class="lines">@@ -10460,6 +10485,31 @@
</span><span class="cx">                 990A19F518ADA48400183FD1 /* ReplayInputTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReplayInputTypes.h; sourceTree = "<group>"; };
</span><span class="cx">                 9920398018B95BC600B39AF9 /* UserInputBridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserInputBridge.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 9920398118B95BC600B39AF9 /* UserInputBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserInputBridge.h; sourceTree = "<group>"; };
</span><ins>+                99CC0B3818BE9849006CEBCC /* AllReplayInputs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AllReplayInputs.h; sourceTree = "<group>"; };
+                99CC0B3918BE9849006CEBCC /* CapturingInputCursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CapturingInputCursor.cpp; sourceTree = "<group>"; };
+                99CC0B3A18BE9849006CEBCC /* CapturingInputCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CapturingInputCursor.h; sourceTree = "<group>"; };
+                99CC0B3B18BE9849006CEBCC /* EventLoopInputDispatcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventLoopInputDispatcher.cpp; sourceTree = "<group>"; };
+                99CC0B3C18BE9849006CEBCC /* EventLoopInputDispatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventLoopInputDispatcher.h; sourceTree = "<group>"; };
+                99CC0B3D18BE9849006CEBCC /* FunctorInputCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctorInputCursor.h; sourceTree = "<group>"; };
+                99CC0B3E18BE9849006CEBCC /* ReplayController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReplayController.cpp; sourceTree = "<group>"; };
+                99CC0B3F18BE9849006CEBCC /* ReplayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReplayController.h; sourceTree = "<group>"; };
+                99CC0B4018BE9849006CEBCC /* ReplayingInputCursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReplayingInputCursor.cpp; sourceTree = "<group>"; };
+                99CC0B4118BE9849006CEBCC /* ReplayingInputCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReplayingInputCursor.h; sourceTree = "<group>"; };
+                99CC0B4218BE9849006CEBCC /* ReplayInputCreationMethods.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReplayInputCreationMethods.cpp; sourceTree = "<group>"; };
+                99CC0B4318BE9849006CEBCC /* ReplayInputDispatchMethods.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReplayInputDispatchMethods.cpp; sourceTree = "<group>"; };
+                99CC0B4418BE9849006CEBCC /* ReplaySession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReplaySession.cpp; sourceTree = "<group>"; };
+                99CC0B4518BE9849006CEBCC /* ReplaySession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReplaySession.h; sourceTree = "<group>"; };
+                99CC0B4618BE9849006CEBCC /* ReplaySessionSegment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReplaySessionSegment.cpp; sourceTree = "<group>"; };
+                99CC0B4718BE9849006CEBCC /* ReplaySessionSegment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReplaySessionSegment.h; sourceTree = "<group>"; };
+                99CC0B4818BE9849006CEBCC /* SegmentedInputStorage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SegmentedInputStorage.cpp; sourceTree = "<group>"; };
+                99CC0B4918BE9849006CEBCC /* SegmentedInputStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SegmentedInputStorage.h; sourceTree = "<group>"; };
+                99CC0B4A18BE9849006CEBCC /* SerializationMethods.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerializationMethods.cpp; sourceTree = "<group>"; };
+                99CC0B4B18BE9849006CEBCC /* SerializationMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SerializationMethods.h; sourceTree = "<group>"; };
+                99CC0B4C18BE9849006CEBCC /* WebInputs.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = WebInputs.json; sourceTree = "<group>"; };
+                99CC0B6418BE9F15006CEBCC /* InspectorReplayAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorReplayAgent.cpp; sourceTree = "<group>"; };
+                99CC0B6518BE9F15006CEBCC /* InspectorReplayAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorReplayAgent.h; sourceTree = "<group>"; };
+                99CC0B6818BEA1FF006CEBCC /* WebReplayInputs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebReplayInputs.cpp; sourceTree = "<group>"; };
+                99CC0B6918BEA1FF006CEBCC /* WebReplayInputs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebReplayInputs.h; sourceTree = "<group>"; };
</ins><span class="cx">                 99E45A1618A063BE0026D88F /* EventLoopInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventLoopInput.h; sourceTree = "<group>"; };
</span><span class="cx">                 9A1142031832D134000BB8AD /* ValueToString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueToString.h; sourceTree = "<group>"; };
</span><span class="cx">                 9A1B6F96158869C80011A8C4 /* JSDOMStringListCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMStringListCustom.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -14850,6 +14900,8 @@
</span><span class="cx">                                 4F6FDD631341DEDD001F8EE3 /* InspectorPageAgent.h */,
</span><span class="cx">                                 9F0D6B2C121BFEBA006C0288 /* InspectorProfilerAgent.cpp */,
</span><span class="cx">                                 9F0D6B2D121BFEBA006C0288 /* InspectorProfilerAgent.h */,
</span><ins>+                                99CC0B6418BE9F15006CEBCC /* InspectorReplayAgent.cpp */,
+                                99CC0B6518BE9F15006CEBCC /* InspectorReplayAgent.h */,
</ins><span class="cx">                                 82AB1771125C826700C5069D /* InspectorResourceAgent.cpp */,
</span><span class="cx">                                 82AB1772125C826700C5069D /* InspectorResourceAgent.h */,
</span><span class="cx">                                 82AB176F125C826700C5069D /* InspectorStyleSheet.cpp */,
</span><span class="lines">@@ -15668,9 +15720,9 @@
</span><span class="cx">                 51C4AA5118B28357007BFE9B /* mac */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                510192D818B7D7AB007FC7A1 /* imageControlsMac.css */,
</ins><span class="cx">                                 510192CF18B6B9AB007FC7A1 /* ImageControlsRootElementMac.cpp */,
</span><span class="cx">                                 510192D018B6B9AB007FC7A1 /* ImageControlsRootElementMac.h */,
</span><del>-                                510192D818B7D7AB007FC7A1 /* imageControlsMac.css */,
</del><span class="cx">                         );
</span><span class="cx">                         path = mac;
</span><span class="cx">                         sourceTree = "<group>";
</span><span class="lines">@@ -15800,6 +15852,8 @@
</span><span class="cx">                                 656581AF09D14EE6000E61D7 /* UserAgentStyleSheetsData.cpp */,
</span><span class="cx">                                 1A1414B313A0F0500019996C /* WebKitFontFamilyNames.cpp */,
</span><span class="cx">                                 1A1414B413A0F0500019996C /* WebKitFontFamilyNames.h */,
</span><ins>+                                99CC0B6818BEA1FF006CEBCC /* WebReplayInputs.cpp */,
+                                99CC0B6918BEA1FF006CEBCC /* WebReplayInputs.h */,
</ins><span class="cx">                                 656581EA09D1508D000E61D7 /* XLinkNames.cpp */,
</span><span class="cx">                                 656581EB09D1508D000E61D7 /* XLinkNames.h */,
</span><span class="cx">                                 A833C80A0A2CF25600D57664 /* XMLNames.cpp */,
</span><span class="lines">@@ -16061,6 +16115,8 @@
</span><span class="cx">                                 975CA287130365F800E99AD9 /* Crypto.cpp */,
</span><span class="cx">                                 975CA288130365F800E99AD9 /* Crypto.h */,
</span><span class="cx">                                 975CA289130365F800E99AD9 /* Crypto.idl */,
</span><ins>+                                1AF4CEE718BC350100BC2D34 /* DefaultVisitedLinkStore.cpp */,
+                                1AF4CEE818BC350100BC2D34 /* DefaultVisitedLinkStore.h */,
</ins><span class="cx">                                 CCC2B51015F613060048CDD6 /* DeviceClient.h */,
</span><span class="cx">                                 CCC2B51115F613060048CDD6 /* DeviceController.cpp */,
</span><span class="cx">                                 CCC2B51215F613060048CDD6 /* DeviceController.h */,
</span><span class="lines">@@ -16080,8 +16136,6 @@
</span><span class="cx">                                 517FBA18151AA71B00B57959 /* DOMWindowExtension.h */,
</span><span class="cx">                                 97D2AD0114B823A60093DF32 /* DOMWindowProperty.cpp */,
</span><span class="cx">                                 97D2AD0214B823A60093DF32 /* DOMWindowProperty.h */,
</span><del>-                                1AF4CEE718BC350100BC2D34 /* DefaultVisitedLinkStore.cpp */,
-                                1AF4CEE818BC350100BC2D34 /* DefaultVisitedLinkStore.h */,
</del><span class="cx">                                 A718760D0B2A120100A16ECE /* DragActions.h */,
</span><span class="cx">                                 A7CA59620B27C1F200FA021D /* DragClient.h */,
</span><span class="cx">                                 A7CA595C0B27BD9E00FA021D /* DragController.cpp */,
</span><span class="lines">@@ -17850,11 +17904,32 @@
</span><span class="cx">                 99E45A1318A021760026D88F /* replay */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                99CC0B3818BE9849006CEBCC /* AllReplayInputs.h */,
+                                99CC0B3918BE9849006CEBCC /* CapturingInputCursor.cpp */,
+                                99CC0B3A18BE9849006CEBCC /* CapturingInputCursor.h */,
</ins><span class="cx">                                 99E45A1618A063BE0026D88F /* EventLoopInput.h */,
</span><ins>+                                99CC0B3B18BE9849006CEBCC /* EventLoopInputDispatcher.cpp */,
+                                99CC0B3C18BE9849006CEBCC /* EventLoopInputDispatcher.h */,
+                                99CC0B3D18BE9849006CEBCC /* FunctorInputCursor.h */,
+                                99CC0B3E18BE9849006CEBCC /* ReplayController.cpp */,
+                                99CC0B3F18BE9849006CEBCC /* ReplayController.h */,
+                                99CC0B4018BE9849006CEBCC /* ReplayingInputCursor.cpp */,
+                                99CC0B4118BE9849006CEBCC /* ReplayingInputCursor.h */,
+                                99CC0B4218BE9849006CEBCC /* ReplayInputCreationMethods.cpp */,
+                                99CC0B4318BE9849006CEBCC /* ReplayInputDispatchMethods.cpp */,
</ins><span class="cx">                                 990A19F418ADA48400183FD1 /* ReplayInputTypes.cpp */,
</span><span class="cx">                                 990A19F518ADA48400183FD1 /* ReplayInputTypes.h */,
</span><ins>+                                99CC0B4418BE9849006CEBCC /* ReplaySession.cpp */,
+                                99CC0B4518BE9849006CEBCC /* ReplaySession.h */,
+                                99CC0B4618BE9849006CEBCC /* ReplaySessionSegment.cpp */,
+                                99CC0B4718BE9849006CEBCC /* ReplaySessionSegment.h */,
+                                99CC0B4818BE9849006CEBCC /* SegmentedInputStorage.cpp */,
+                                99CC0B4918BE9849006CEBCC /* SegmentedInputStorage.h */,
+                                99CC0B4A18BE9849006CEBCC /* SerializationMethods.cpp */,
+                                99CC0B4B18BE9849006CEBCC /* SerializationMethods.h */,
</ins><span class="cx">                                 9920398018B95BC600B39AF9 /* UserInputBridge.cpp */,
</span><span class="cx">                                 9920398118B95BC600B39AF9 /* UserInputBridge.h */,
</span><ins>+                                99CC0B4C18BE9849006CEBCC /* WebInputs.json */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = replay;
</span><span class="cx">                         sourceTree = "<group>";
</span><span class="lines">@@ -17983,9 +18058,9 @@
</span><span class="cx">                 A5C974CE11485FDA0066F2AB /* cocoa */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><del>-                                7CC564B918BAC720001B9652 /* TelephoneNumberDetectorCocoa.cpp */,
</del><span class="cx">                                 A5C974CF11485FF10066F2AB /* KeyEventCocoa.h */,
</span><span class="cx">                                 A5C974D011485FF10066F2AB /* KeyEventCocoa.mm */,
</span><ins>+                                7CC564B918BAC720001B9652 /* TelephoneNumberDetectorCocoa.cpp */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = cocoa;
</span><span class="cx">                         sourceTree = "<group>";
</span><span class="lines">@@ -22668,6 +22743,7 @@
</span><span class="cx">                                 BCF7E491137CD7C7001DDAE7 /* AdjustViewSizeOrNot.h in Headers */,
</span><span class="cx">                                 84D0C4061115F1EA0018AA34 /* AffineTransform.h in Headers */,
</span><span class="cx">                                 0705850817FA4689005F2BCB /* AllAudioCapabilities.h in Headers */,
</span><ins>+                                99CC0B4D18BE9849006CEBCC /* AllReplayInputs.h in Headers */,
</ins><span class="cx">                                 073AB4B317F8BACA006E0D6F /* AllVideoCapabilities.h in Headers */,
</span><span class="cx">                                 CEDA12D7152CA1CB00D9E08D /* AlternativeTextClient.h in Headers */,
</span><span class="cx">                                 CE08C3D2152B599A0021B8C2 /* AlternativeTextController.h in Headers */,
</span><span class="lines">@@ -22840,6 +22916,7 @@
</span><span class="cx">                                 07C59B7617F7D0DB000FBCBB /* CapabilityRange.h in Headers */,
</span><span class="cx">                                 079D0868162F20E800DB8658 /* CaptionUserPreferences.h in Headers */,
</span><span class="cx">                                 079D086B162F21F900DB8658 /* CaptionUserPreferencesMediaAF.h in Headers */,
</span><ins>+                                99CC0B4F18BE9849006CEBCC /* CapturingInputCursor.h in Headers */,
</ins><span class="cx">                                 6550B69E099DF0270090D781 /* CDATASection.h in Headers */,
</span><span class="cx">                                 CDDD571518B57A8200A94FCB /* CDMSession.h in Headers */,
</span><span class="cx">                                 5FA904CA178E61F5004C8A2D /* CertificateInfo.h in Headers */,
</span><span class="lines">@@ -22900,6 +22977,7 @@
</span><span class="cx">                                 97627B8E14FB3CEE002CDCA1 /* ContextDestructionObserver.h in Headers */,
</span><span class="cx">                                 93B6A0E60B0BCA5C00F5027A /* ContextMenu.h in Headers */,
</span><span class="cx">                                 065AD4F50B0C2EDA005A2B1D /* ContextMenuClient.h in Headers */,
</span><ins>+                                5106D7BE18BDB76F000AB166 /* ContextMenuContext.h in Headers */,
</ins><span class="cx">                                 065AD4F70B0C2EDA005A2B1D /* ContextMenuController.h in Headers */,
</span><span class="cx">                                 06027CAD0B1CBFC000884B2D /* ContextMenuItem.h in Headers */,
</span><span class="cx">                                 7ADE722610CBBB9B006B3B3A /* ContextMenuProvider.h in Headers */,
</span><span class="lines">@@ -23069,6 +23147,7 @@
</span><span class="cx">                                 41A3D58F101C152D00316D07 /* DedicatedWorkerThread.h in Headers */,
</span><span class="cx">                                 FD06DFA6134A4DEF006F5D7D /* DefaultAudioDestinationNode.h in Headers */,
</span><span class="cx">                                 4167EBF6102962BA003D252A /* DefaultSharedWorkerRepository.h in Headers */,
</span><ins>+                                1AF4CEEA18BC350100BC2D34 /* DefaultVisitedLinkStore.h in Headers */,
</ins><span class="cx">                                 FD31602C12B0267600C1A359 /* DelayDSPKernel.h in Headers */,
</span><span class="cx">                                 FD31602E12B0267600C1A359 /* DelayNode.h in Headers */,
</span><span class="cx">                                 FD31603112B0267600C1A359 /* DelayProcessor.h in Headers */,
</span><span class="lines">@@ -23519,6 +23598,7 @@
</span><span class="cx">                                 AD4495F4141FC08900541EDF /* EventListenerMap.h in Headers */,
</span><span class="cx">                                 1CA19E160DC255CA0065A994 /* EventLoop.h in Headers */,
</span><span class="cx">                                 99E45A1718A063BE0026D88F /* EventLoopInput.h in Headers */,
</span><ins>+                                99CC0B5118BE9849006CEBCC /* EventLoopInputDispatcher.h in Headers */,
</ins><span class="cx">                                 939885C408B7E3D100E707C4 /* EventNames.h in Headers */,
</span><span class="cx">                                 8F67561B1288B17B0047ACA3 /* EventQueue.h in Headers */,
</span><span class="cx">                                 E0FEF372B17C53EAC1C1FBEE /* EventSource.h in Headers */,
</span><span class="lines">@@ -23641,6 +23721,7 @@
</span><span class="cx">                                 97205AB0123928CA00B17380 /* FTPDirectoryDocument.h in Headers */,
</span><span class="cx">                                 51C81B8A0C4422F70019ECE3 /* FTPDirectoryParser.h in Headers */,
</span><span class="cx">                                 26B999931803B9D900D01121 /* FunctionCall.h in Headers */,
</span><ins>+                                99CC0B5218BE9849006CEBCC /* FunctorInputCursor.h in Headers */,
</ins><span class="cx">                                 FD31600D12B0267600C1A359 /* GainNode.h in Headers */,
</span><span class="cx">                                 935C477509AC4D8E00A6AAB4 /* GapRects.h in Headers */,
</span><span class="cx">                                 1432E8470C51493800B1500F /* GCController.h in Headers */,
</span><span class="lines">@@ -23718,7 +23799,6 @@
</span><span class="cx">                                 977B3867122883E900B81FF8 /* HTMLDocumentParser.h in Headers */,
</span><span class="cx">                                 93309DE8099E64920056E581 /* htmlediting.h in Headers */,
</span><span class="cx">                                 93F198E608245E59001E9ABC /* HTMLElement.h in Headers */,
</span><del>-                                9920398318B95BC600B39AF9 /* UserInputBridge.h in Headers */,
</del><span class="cx">                                 A17C81230F2A5CF7005DAAEB /* HTMLElementFactory.h in Headers */,
</span><span class="cx">                                 977B37241228721700B81FF8 /* HTMLElementStack.h in Headers */,
</span><span class="cx">                                 B562DB6017D3CD630010AF96 /* HTMLElementTypeHelpers.h in Headers */,
</span><span class="lines">@@ -23791,6 +23871,7 @@
</span><span class="cx">                                 978AD67514130A8D00C7CAE3 /* HTMLSpanElement.h in Headers */,
</span><span class="cx">                                 A871DC230A15205700B12A68 /* HTMLStyleElement.h in Headers */,
</span><span class="cx">                                 D3D4E973130C7CFE007BA540 /* HTMLSummaryElement.h in Headers */,
</span><ins>+                                99CC0B6B18BEA1FF006CEBCC /* WebReplayInputs.h in Headers */,
</ins><span class="cx">                                 A871DB2B0A150BD600B12A68 /* HTMLTableCaptionElement.h in Headers */,
</span><span class="cx">                                 A871DB2A0A150BD600B12A68 /* HTMLTableCellElement.h in Headers */,
</span><span class="cx">                                 A871DB2F0A150BD600B12A68 /* HTMLTableColElement.h in Headers */,
</span><span class="lines">@@ -23944,6 +24025,7 @@
</span><span class="cx">                                 0F03C0751884805500A5F8CA /* InspectorOverlay.h in Headers */,
</span><span class="cx">                                 4F6FDD651341DEDD001F8EE3 /* InspectorPageAgent.h in Headers */,
</span><span class="cx">                                 9F0D6B2F121BFEBA006C0288 /* InspectorProfilerAgent.h in Headers */,
</span><ins>+                                99CC0B6718BE9F15006CEBCC /* InspectorReplayAgent.h in Headers */,
</ins><span class="cx">                                 82AB1776125C826700C5069D /* InspectorResourceAgent.h in Headers */,
</span><span class="cx">                                 82AB1774125C826700C5069D /* InspectorStyleSheet.h in Headers */,
</span><span class="cx">                                 82889B4D13C62392009A6156 /* InspectorStyleTextEditor.h in Headers */,
</span><span class="lines">@@ -24006,7 +24088,6 @@
</span><span class="cx">                                 FDA15EBE12B03F0B003A583A /* JSConvolverNode.h in Headers */,
</span><span class="cx">                                 FE6FD48E0F676E9300092873 /* JSCoordinates.h in Headers */,
</span><span class="cx">                                 930705DA09E0C9BF00B17FE4 /* JSCounter.h in Headers */,
</span><del>-                                1AF4CEEA18BC350100BC2D34 /* DefaultVisitedLinkStore.h in Headers */,
</del><span class="cx">                                 975CA2A21303679D00E99AD9 /* JSCrypto.h in Headers */,
</span><span class="cx">                                 E157A8F118185425009F821D /* JSCryptoAlgorithmBuilder.h in Headers */,
</span><span class="cx">                                 E1C657131815F9DD00256CDD /* JSCryptoAlgorithmDictionary.h in Headers */,
</span><span class="lines">@@ -24108,7 +24189,6 @@
</span><span class="cx">                                 1AE2AA210A1CDAB400B42B25 /* JSHTMLBaseFontElement.h in Headers */,
</span><span class="cx">                                 1AE2AA230A1CDAB400B42B25 /* JSHTMLBodyElement.h in Headers */,
</span><span class="cx">                                 1AE2AA250A1CDAB400B42B25 /* JSHTMLBRElement.h in Headers */,
</span><del>-                                7CC564B818BABEA6001B9652 /* TelephoneNumberDetector.h in Headers */,
</del><span class="cx">                                 A80E7E9F0A1A83E3007FB8C5 /* JSHTMLButtonElement.h in Headers */,
</span><span class="cx">                                 938E666209F09B87008A48EC /* JSHTMLCanvasElement.h in Headers */,
</span><span class="cx">                                 BCCBAD410C18C14200CE890F /* JSHTMLCollection.h in Headers */,
</span><span class="lines">@@ -24543,7 +24623,6 @@
</span><span class="cx">                                 450CEBF115073BBE002BB149 /* LabelableElement.h in Headers */,
</span><span class="cx">                                 A456FA2711AD4A830020B420 /* LabelsNodeList.h in Headers */,
</span><span class="cx">                                 85EC9AFB0A71A2C600EEEAED /* Language.h in Headers */,
</span><del>-                                5106D7BE18BDB76F000AB166 /* ContextMenuContext.h in Headers */,
</del><span class="cx">                                 2917B5621473496C0052C9D0 /* LayerFlushScheduler.h in Headers */,
</span><span class="cx">                                 2917B5631473496C0052C9D0 /* LayerFlushSchedulerClient.h in Headers */,
</span><span class="cx">                                 93F72AF31666EDFC002A02BD /* LayerPool.h in Headers */,
</span><span class="lines">@@ -25057,7 +25136,11 @@
</span><span class="cx">                                 A871DFE40A15376B00B12A68 /* RenderWidget.h in Headers */,
</span><span class="cx">                                 A89CCC530F44E98100B5DA10 /* ReplaceNodeWithSpanCommand.h in Headers */,
</span><span class="cx">                                 93309E0A099E64920056E581 /* ReplaceSelectionCommand.h in Headers */,
</span><ins>+                                99CC0B5418BE9849006CEBCC /* ReplayController.h in Headers */,
+                                99CC0B5618BE984A006CEBCC /* ReplayingInputCursor.h in Headers */,
</ins><span class="cx">                                 990A1A0518ADA48400183FD1 /* ReplayInputTypes.h in Headers */,
</span><ins>+                                99CC0B5A18BE984A006CEBCC /* ReplaySession.h in Headers */,
+                                99CC0B5C18BE984A006CEBCC /* ReplaySessionSegment.h in Headers */,
</ins><span class="cx">                                 4998AEC613F9D0EA0090B1AA /* RequestAnimationFrameCallback.h in Headers */,
</span><span class="cx">                                 F55B3DD01251F12D003EF269 /* ResetInputType.h in Headers */,
</span><span class="cx">                                 514BC843161CF05C004D52F4 /* ResourceBuffer.h in Headers */,
</span><span class="lines">@@ -25191,6 +25274,7 @@
</span><span class="cx">                                 974D2DA5146A535D00D51F8B /* SecurityPolicy.h in Headers */,
</span><span class="cx">                                 2D5BC42716F882EE007048D0 /* SecurityPolicyViolationEvent.h in Headers */,
</span><span class="cx">                                 371F4FFC0D25E7F300ECE0D5 /* SegmentedFontData.h in Headers */,
</span><ins>+                                99CC0B5E18BE984A006CEBCC /* SegmentedInputStorage.h in Headers */,
</ins><span class="cx">                                 B2C3DA2F0D006C1D00EF6F26 /* SegmentedString.h in Headers */,
</span><span class="cx">                                 BEA807C90F714A0300524199 /* SelectionRect.h in Headers */,
</span><span class="cx">                                 E44B4BB4141650D7002B1D8B /* SelectorChecker.h in Headers */,
</span><span class="lines">@@ -25199,6 +25283,7 @@
</span><span class="cx">                                 26B999971804D54200D01121 /* SelectorCompiler.h in Headers */,
</span><span class="cx">                                 415071581685067300C3C7B3 /* SelectorFilter.h in Headers */,
</span><span class="cx">                                 E45322AC140CE267005A0F92 /* SelectorQuery.h in Headers */,
</span><ins>+                                99CC0B6018BE984A006CEBCC /* SerializationMethods.h in Headers */,
</ins><span class="cx">                                 E18DF33518AAF12C00773E59 /* SerializedCryptoKeyWrap.h in Headers */,
</span><span class="cx">                                 A75E497610752ACB00C9B896 /* SerializedScriptValue.h in Headers */,
</span><span class="cx">                                 756B2CE118B7101600FECFAA /* SessionID.h in Headers */,
</span><span class="lines">@@ -25624,6 +25709,7 @@
</span><span class="cx">                                 A8CFF0510A154F09000A4234 /* TableLayout.h in Headers */,
</span><span class="cx">                                 BCE3BEC30D222B1D007E06E4 /* TagNodeList.h in Headers */,
</span><span class="cx">                                 F55B3DD61251F12D003EF269 /* TelephoneInputType.h in Headers */,
</span><ins>+                                7CC564B818BABEA6001B9652 /* TelephoneNumberDetector.h in Headers */,
</ins><span class="cx">                                 C65046A9167BFB5500CC2A4D /* TemplateContentDocumentFragment.h in Headers */,
</span><span class="cx">                                 6550B6A6099DF0270090D781 /* Text.h in Headers */,
</span><span class="cx">                                 93309E17099E64920056E581 /* TextAffinity.h in Headers */,
</span><span class="lines">@@ -25746,6 +25832,7 @@
</span><span class="cx">                                 003F1FEA11E6AB43008258D9 /* UserContentTypes.h in Headers */,
</span><span class="cx">                                 BCACF3BD1072921A00C0C8A3 /* UserContentURLPattern.h in Headers */,
</span><span class="cx">                                 2542F4DB1166C25A00E89A86 /* UserGestureIndicator.h in Headers */,
</span><ins>+                                9920398318B95BC600B39AF9 /* UserInputBridge.h in Headers */,
</ins><span class="cx">                                 078E092E17D14D1C00420AA1 /* UserMediaClient.h in Headers */,
</span><span class="cx">                                 078E092F17D14D1C00420AA1 /* UserMediaController.h in Headers */,
</span><span class="cx">                                 078E093017D14D1C00420AA1 /* UserMediaRequest.h in Headers */,
</span><span class="lines">@@ -25781,8 +25868,8 @@
</span><span class="cx">                                 93309E20099E64920056E581 /* VisiblePosition.h in Headers */,
</span><span class="cx">                                 A883DF280F3D045D00F19BF6 /* VisibleSelection.h in Headers */,
</span><span class="cx">                                 93309E1E099E64920056E581 /* VisibleUnits.h in Headers */,
</span><ins>+                                419BC2DF1685329900D64D6D /* VisitedLinkState.h in Headers */,
</ins><span class="cx">                                 1ABA80001897341200DCE9D6 /* VisitedLinkStore.h in Headers */,
</span><del>-                                419BC2DF1685329900D64D6D /* VisitedLinkState.h in Headers */,
</del><span class="cx">                                 E44613B60CD6344E00FADA75 /* VoidCallback.h in Headers */,
</span><span class="cx">                                 BE20507A18A4586B0080647E /* VTTCue.h in Headers */,
</span><span class="cx">                                 A14832B0187F618D00DA63A6 /* WAKAppKitStubs.h in Headers */,
</span><span class="lines">@@ -26161,6 +26248,7 @@
</span><span class="cx">                                 9370918D1416D86B00477333 /* textAreaResizeCorner@2x.png in Resources */,
</span><span class="cx">                                 46D4F24B0AF97E810035385A /* verticalTextCursor.png in Resources */,
</span><span class="cx">                                 85136CA70AED665900F90A3D /* waitCursor.png in Resources */,
</span><ins>+                                99CC0B6118BE984A006CEBCC /* WebInputs.json in Resources */,
</ins><span class="cx">                                 85136CA80AED665900F90A3D /* westResizeCursor.png in Resources */,
</span><span class="cx">                                 1AB1AE7A0C051FDE00139F4F /* zoomInCursor.png in Resources */,
</span><span class="cx">                                 1AB1AE7B0C051FDE00139F4F /* zoomOutCursor.png in Resources */,
</span><span class="lines">@@ -26274,7 +26362,7 @@
</span><span class="cx">                         );
</span><span class="cx">                         runOnlyForDeploymentPostprocessing = 0;
</span><span class="cx">                         shellPath = /bin/sh;
</span><del>-                        shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore\"\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore\"\n\n/bin/ln -sfh \"${SRCROOT}\" WebCore\nexport WebCore=\"WebCore\"\nexport InspectorScripts=\"${JAVASCRIPTCORE_PRIVATE_HEADERS_DIR}\"\n\nif [ ! $CC ]; then\n export CC=\"`xcrun -find clang`\"\nfi\n\nif [ ! $GPERF ]; then\n export GPERF=\"`xcrun -find gperf`\"\nfi\n\nif [ \"${ACTION}\" = \"build\" -o \"${ACTION}\" = \"install\" -o \"${ACTION}\" = \"installhdrs\" ]; then\n make --no-builtin-rules -f \"WebCore/DerivedSources.make\" -j `/usr/sbin/sysctl -n hw.activecpu` SDKROOT=\"${SDKROOT}\"\nfi\n";
</del><ins>+                        shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore\"\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore\"\n\n/bin/ln -sfh \"${SRCROOT}\" WebCore\nexport WebCore=\"WebCore\"\nexport InspectorScripts=\"${JAVASCRIPTCORE_PRIVATE_HEADERS_DIR}\"\nexport WebReplayScripts=\"${JAVASCRIPTCORE_PRIVATE_HEADERS_DIR}\"\n\nif [ ! $CC ]; then\n export CC=\"`xcrun -find clang`\"\nfi\n\nif [ ! $GPERF ]; then\n export GPERF=\"`xcrun -find gperf`\"\nfi\n\nif [ \"${ACTION}\" = \"build\" -o \"${ACTION}\" = \"install\" -o \"${ACTION}\" = \"installhdrs\" ]; then\n make --no-builtin-rules -f \"WebCore/DerivedSources.make\" -j `/usr/sbin/sysctl -n hw.activecpu` SDKROOT=\"${SDKROOT}\"\nfi\n";
</ins><span class="cx">                 };
</span><span class="cx"> /* End PBXShellScriptBuildPhase section */
</span><span class="cx">
</span><span class="lines">@@ -26410,7 +26498,6 @@
</span><span class="cx">                                 85031B3C0A44EFC700F992E0 /* BeforeUnloadEvent.cpp in Sources */,
</span><span class="cx">                                 B2C3DA230D006C1D00EF6F26 /* BidiContext.cpp in Sources */,
</span><span class="cx">                                 BCE7898B1120E8020060ECE5 /* BidiRun.cpp in Sources */,
</span><del>-                                5106D7BD18BDB76F000AB166 /* ContextMenuContext.cpp in Sources */,
</del><span class="cx">                                 FD31608C12B026F700C1A359 /* Biquad.cpp in Sources */,
</span><span class="cx">                                 FD31602412B0267600C1A359 /* BiquadDSPKernel.cpp in Sources */,
</span><span class="cx">                                 FDC54F041399B0DA008D9117 /* BiquadFilterNode.cpp in Sources */,
</span><span class="lines">@@ -26461,6 +26548,7 @@
</span><span class="cx">                                 070584FF17F9F05E005F2BCB /* CapabilityRange.cpp in Sources */,
</span><span class="cx">                                 072CA86116CB4DC3008AE131 /* CaptionUserPreferences.cpp in Sources */,
</span><span class="cx">                                 079D086C162F21F900DB8658 /* CaptionUserPreferencesMediaAF.cpp in Sources */,
</span><ins>+                                99CC0B4E18BE9849006CEBCC /* CapturingInputCursor.cpp in Sources */,
</ins><span class="cx">                                 6550B69D099DF0270090D781 /* CDATASection.cpp in Sources */,
</span><span class="cx">                                 CDA98E0B1603CD6000FEA3B1 /* CDM.cpp in Sources */,
</span><span class="cx">                                 CDCA98EB18B2C8EB00C12FF9 /* CDMPrivateMediaPlayer.cpp in Sources */,
</span><span class="lines">@@ -26514,6 +26602,7 @@
</span><span class="cx">                                 97C471DB12F925BD0086354B /* ContentSecurityPolicy.cpp in Sources */,
</span><span class="cx">                                 41D015CB0F4B5C71004A662F /* ContentType.cpp in Sources */,
</span><span class="cx">                                 97627B8D14FB3CEE002CDCA1 /* ContextDestructionObserver.cpp in Sources */,
</span><ins>+                                5106D7BD18BDB76F000AB166 /* ContextMenuContext.cpp in Sources */,
</ins><span class="cx">                                 065AD4F60B0C2EDA005A2B1D /* ContextMenuController.cpp in Sources */,
</span><span class="cx">                                 06027CB30B1CC03D00884B2D /* ContextMenuItemMac.mm in Sources */,
</span><span class="cx">                                 93B6A0EA0B0BCA8400F5027A /* ContextMenuMac.mm in Sources */,
</span><span class="lines">@@ -26659,6 +26748,7 @@
</span><span class="cx">                                 41A3D58E101C152D00316D07 /* DedicatedWorkerThread.cpp in Sources */,
</span><span class="cx">                                 FD06DFA5134A4DEF006F5D7D /* DefaultAudioDestinationNode.cpp in Sources */,
</span><span class="cx">                                 4167EBF5102962BA003D252A /* DefaultSharedWorkerRepository.cpp in Sources */,
</span><ins>+                                1AF4CEE918BC350100BC2D34 /* DefaultVisitedLinkStore.cpp in Sources */,
</ins><span class="cx">                                 FD31602B12B0267600C1A359 /* DelayDSPKernel.cpp in Sources */,
</span><span class="cx">                                 FD31602D12B0267600C1A359 /* DelayNode.cpp in Sources */,
</span><span class="cx">                                 FD31603012B0267600C1A359 /* DelayProcessor.cpp in Sources */,
</span><span class="lines">@@ -26931,6 +27021,7 @@
</span><span class="cx">                                 FE6938B61045D67E008EABB6 /* EventHandlerIOS.mm in Sources */,
</span><span class="cx">                                 93C09A7F0B064EEF005ABD4D /* EventHandlerMac.mm in Sources */,
</span><span class="cx">                                 AD4495F3141FC08900541EDF /* EventListenerMap.cpp in Sources */,
</span><ins>+                                99CC0B5018BE9849006CEBCC /* EventLoopInputDispatcher.cpp in Sources */,
</ins><span class="cx">                                 26F40D4A14904A6300CA67C4 /* EventLoopIOS.mm in Sources */,
</span><span class="cx">                                 1CA19E050DC255950065A994 /* EventLoopMac.mm in Sources */,
</span><span class="cx">                                 939885C308B7E3D100E707C4 /* EventNames.cpp in Sources */,
</span><span class="lines">@@ -27303,6 +27394,7 @@
</span><span class="cx">                                 7C522D4B15B477E8009B7C95 /* InspectorOverlay.cpp in Sources */,
</span><span class="cx">                                 4F6FDD641341DEDD001F8EE3 /* InspectorPageAgent.cpp in Sources */,
</span><span class="cx">                                 9F0D6B2E121BFEBA006C0288 /* InspectorProfilerAgent.cpp in Sources */,
</span><ins>+                                99CC0B6618BE9F15006CEBCC /* InspectorReplayAgent.cpp in Sources */,
</ins><span class="cx">                                 82AB1775125C826700C5069D /* InspectorResourceAgent.cpp in Sources */,
</span><span class="cx">                                 82AB1773125C826700C5069D /* InspectorStyleSheet.cpp in Sources */,
</span><span class="cx">                                 82889B4C13C62392009A6156 /* InspectorStyleTextEditor.cpp in Sources */,
</span><span class="lines">@@ -27874,7 +27966,6 @@
</span><span class="cx">                                 8542A7960AE5C94200DF58DF /* JSSVGPoint.cpp in Sources */,
</span><span class="cx">                                 B2FA3DE20AB75A6F000E5AC4 /* JSSVGPointList.cpp in Sources */,
</span><span class="cx">                                 B2FA3DE50AB75A6F000E5AC4 /* JSSVGPolygonElement.cpp in Sources */,
</span><del>-                                7CC564BA18BAC720001B9652 /* TelephoneNumberDetectorCocoa.cpp in Sources */,
</del><span class="cx">                                 B2FA3DE70AB75A6F000E5AC4 /* JSSVGPolylineElement.cpp in Sources */,
</span><span class="cx">                                 B2FA3DE90AB75A6F000E5AC4 /* JSSVGPreserveAspectRatio.cpp in Sources */,
</span><span class="cx">                                 B2FA3DEB0AB75A6F000E5AC4 /* JSSVGRadialGradientElement.cpp in Sources */,
</span><span class="lines">@@ -28266,7 +28357,6 @@
</span><span class="cx">                                 1ADA14100E1AE5D900023EE5 /* PluginMainThreadScheduler.cpp in Sources */,
</span><span class="cx">                                 71E2183B17359FB8006E6E4D /* PlugInsResourcesData.cpp in Sources */,
</span><span class="cx">                                 76FF17E311235673001D61B5 /* PluginViewNone.cpp in Sources */,
</span><del>-                                9920398218B95BC600B39AF9 /* UserInputBridge.cpp in Sources */,
</del><span class="cx">                                 B2B1F7160D00CAA8004AEA64 /* PointerEventsHitRules.cpp in Sources */,
</span><span class="cx">                                 A1E1154613015C4E0054AC8C /* PointLightSource.cpp in Sources */,
</span><span class="cx">                                 97059977107D975200A50A7C /* PolicyCallback.cpp in Sources */,
</span><span class="lines">@@ -28410,7 +28500,13 @@
</span><span class="cx">                                 A871DFE50A15376B00B12A68 /* RenderWidget.cpp in Sources */,
</span><span class="cx">                                 A89CCC520F44E98100B5DA10 /* ReplaceNodeWithSpanCommand.cpp in Sources */,
</span><span class="cx">                                 93309E09099E64920056E581 /* ReplaceSelectionCommand.cpp in Sources */,
</span><ins>+                                99CC0B5318BE9849006CEBCC /* ReplayController.cpp in Sources */,
+                                99CC0B5518BE9849006CEBCC /* ReplayingInputCursor.cpp in Sources */,
+                                99CC0B5718BE984A006CEBCC /* ReplayInputCreationMethods.cpp in Sources */,
+                                99CC0B5818BE984A006CEBCC /* ReplayInputDispatchMethods.cpp in Sources */,
</ins><span class="cx">                                 990A1A0418ADA48400183FD1 /* ReplayInputTypes.cpp in Sources */,
</span><ins>+                                99CC0B5918BE984A006CEBCC /* ReplaySession.cpp in Sources */,
+                                99CC0B5B18BE984A006CEBCC /* ReplaySessionSegment.cpp in Sources */,
</ins><span class="cx">                                 F55B3DCF1251F12D003EF269 /* ResetInputType.cpp in Sources */,
</span><span class="cx">                                 514BC842161CF05C004D52F4 /* ResourceBuffer.cpp in Sources */,
</span><span class="cx">                                 514BC83F161CF04A004D52F4 /* ResourceBuffer.mm in Sources */,
</span><span class="lines">@@ -28530,6 +28626,7 @@
</span><span class="cx">                                 BCD0E0FA0E972C3500265DEA /* SecurityOrigin.cpp in Sources */,
</span><span class="cx">                                 974D2DA4146A535D00D51F8B /* SecurityPolicy.cpp in Sources */,
</span><span class="cx">                                 371F4FFD0D25E7F300ECE0D5 /* SegmentedFontData.cpp in Sources */,
</span><ins>+                                99CC0B5D18BE984A006CEBCC /* SegmentedInputStorage.cpp in Sources */,
</ins><span class="cx">                                 B2C3DA2E0D006C1D00EF6F26 /* SegmentedString.cpp in Sources */,
</span><span class="cx">                                 BEA807C80F714A0300524199 /* SelectionRect.cpp in Sources */,
</span><span class="cx">                                 E44B4BB3141650D7002B1D8B /* SelectorChecker.cpp in Sources */,
</span><span class="lines">@@ -28537,6 +28634,7 @@
</span><span class="cx">                                 26B999961804D54200D01121 /* SelectorCompiler.cpp in Sources */,
</span><span class="cx">                                 415071571685067300C3C7B3 /* SelectorFilter.cpp in Sources */,
</span><span class="cx">                                 E45322AB140CE267005A0F92 /* SelectorQuery.cpp in Sources */,
</span><ins>+                                99CC0B5F18BE984A006CEBCC /* SerializationMethods.cpp in Sources */,
</ins><span class="cx">                                 E18DF33818AAF14D00773E59 /* SerializedCryptoKeyWrapMac.mm in Sources */,
</span><span class="cx">                                 A75E497710752ACB00C9B896 /* SerializedScriptValue.cpp in Sources */,
</span><span class="cx">                                 93309E0F099E64920056E581 /* SetNodeAttributeCommand.cpp in Sources */,
</span><span class="lines">@@ -28770,6 +28868,7 @@
</span><span class="cx">                                 B2227A230D00BF220071B782 /* SVGForeignObjectElement.cpp in Sources */,
</span><span class="cx">                                 B2227A260D00BF220071B782 /* SVGGElement.cpp in Sources */,
</span><span class="cx">                                 087E0AF613606D0B00FA4BA8 /* SVGGlyph.cpp in Sources */,
</span><ins>+                                99CC0B6A18BEA1FF006CEBCC /* WebReplayInputs.cpp in Sources */,
</ins><span class="cx">                                 B2A1F2AD0CEF0ABF00442F6A /* SVGGlyphElement.cpp in Sources */,
</span><span class="cx">                                 24D912BD13CA9A9700D21915 /* SVGGlyphRefElement.cpp in Sources */,
</span><span class="cx">                                 B2227A290D00BF220071B782 /* SVGGradientElement.cpp in Sources */,
</span><span class="lines">@@ -28832,7 +28931,6 @@
</span><span class="cx">                                 B2227AC00D00BF220071B782 /* SVGSymbolElement.cpp in Sources */,
</span><span class="cx">                                 B2227AC40D00BF220071B782 /* SVGTests.cpp in Sources */,
</span><span class="cx">                                 B2227AC70D00BF220071B782 /* SVGTextContentElement.cpp in Sources */,
</span><del>-                                1AF4CEEC18BC3C1B00BC2D34 /* VisitedLinkStore.cpp in Sources */,
</del><span class="cx">                                 B2227ACA0D00BF220071B782 /* SVGTextElement.cpp in Sources */,
</span><span class="cx">                                 B2227ACD0D00BF220071B782 /* SVGTextPathElement.cpp in Sources */,
</span><span class="cx">                                 B2227AD00D00BF220071B782 /* SVGTextPositioningElement.cpp in Sources */,
</span><span class="lines">@@ -28848,7 +28946,6 @@
</span><span class="cx">                                 B2227AEF0D00BF220071B782 /* SVGViewElement.cpp in Sources */,
</span><span class="cx">                                 B2227AF20D00BF220071B782 /* SVGViewSpec.cpp in Sources */,
</span><span class="cx">                                 8485228A1190173C006EDC7F /* SVGVKernElement.cpp in Sources */,
</span><del>-                                1AF4CEE918BC350100BC2D34 /* DefaultVisitedLinkStore.cpp in Sources */,
</del><span class="cx">                                 B2227AF50D00BF220071B782 /* SVGZoomAndPan.cpp in Sources */,
</span><span class="cx">                                 B2E4EC970D00C22B00432643 /* SVGZoomEvent.cpp in Sources */,
</span><span class="cx">                                 E180811216FCF42F00B80D07 /* SynchronousLoaderClient.cpp in Sources */,
</span><span class="lines">@@ -28859,6 +28956,7 @@
</span><span class="cx">                                 5DA97ECE168E787B000E3676 /* SystemVersionMac.mm in Sources */,
</span><span class="cx">                                 BCE3BEC20D222B1D007E06E4 /* TagNodeList.cpp in Sources */,
</span><span class="cx">                                 F55B3DD51251F12D003EF269 /* TelephoneInputType.cpp in Sources */,
</span><ins>+                                7CC564BA18BAC720001B9652 /* TelephoneNumberDetectorCocoa.cpp in Sources */,
</ins><span class="cx">                                 7A29BA6A187B7C1D00F29CEB /* TemporaryOpenGLSetting.cpp in Sources */,
</span><span class="cx">                                 6550B6A5099DF0270090D781 /* Text.cpp in Sources */,
</span><span class="cx">                                 CE7B2DB61586ABAD0098B3FA /* TextAlternativeWithRange.mm in Sources */,
</span><span class="lines">@@ -28964,6 +29062,7 @@
</span><span class="cx">                                 1AE79D42188DB61F002239C2 /* UserContentController.cpp in Sources */,
</span><span class="cx">                                 BCACF3BC1072921A00C0C8A3 /* UserContentURLPattern.cpp in Sources */,
</span><span class="cx">                                 2542F4DA1166C25A00E89A86 /* UserGestureIndicator.cpp in Sources */,
</span><ins>+                                9920398218B95BC600B39AF9 /* UserInputBridge.cpp in Sources */,
</ins><span class="cx">                                 078E091217D14CEE00420AA1 /* UserMediaController.cpp in Sources */,
</span><span class="cx">                                 078E091317D14CEE00420AA1 /* UserMediaRequest.cpp in Sources */,
</span><span class="cx">                                 BCDF317B11F8D683003C5BF8 /* UserTypingGestureIndicator.cpp in Sources */,
</span><span class="lines">@@ -28987,6 +29086,7 @@
</span><span class="cx">                                 A883DF270F3D045D00F19BF6 /* VisibleSelection.cpp in Sources */,
</span><span class="cx">                                 93309E1D099E64920056E581 /* VisibleUnits.cpp in Sources */,
</span><span class="cx">                                 419BC2DE1685329900D64D6D /* VisitedLinkState.cpp in Sources */,
</span><ins>+                                1AF4CEEC18BC3C1B00BC2D34 /* VisitedLinkStore.cpp in Sources */,
</ins><span class="cx">                                 BE20507918A458680080647E /* VTTCue.cpp in Sources */,
</span><span class="cx">                                 A14832B1187F61E100DA63A6 /* WAKAppKitStubs.m in Sources */,
</span><span class="cx">                                 A14832B3187F629100DA63A6 /* WAKClipView.m in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorController.cpp (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorController.cpp        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/inspector/InspectorController.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx"> * Copyright (C) 2011 Google Inc. All rights reserved.
</span><ins>+ * Copyright (C) 2014 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions are
</span><span class="lines">@@ -52,6 +53,7 @@
</span><span class="cx"> #include "InspectorOverlay.h"
</span><span class="cx"> #include "InspectorPageAgent.h"
</span><span class="cx"> #include "InspectorProfilerAgent.h"
</span><ins>+#include "InspectorReplayAgent.h"
</ins><span class="cx"> #include "InspectorResourceAgent.h"
</span><span class="cx"> #include "InspectorTimelineAgent.h"
</span><span class="cx"> #include "InspectorWebBackendDispatchers.h"
</span><span class="lines">@@ -124,6 +126,10 @@
</span><span class="cx"> m_agents.append(std::make_unique<InspectorIndexedDBAgent>(m_instrumentingAgents.get(), m_injectedScriptManager.get(), pageAgent));
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+#if ENABLE(WEB_REPLAY)
+ m_agents.append(std::make_unique<InspectorReplayAgent>(m_instrumentingAgents.get(), pageAgent));
+#endif
+
</ins><span class="cx"> auto domStorageAgentPtr = std::make_unique<InspectorDOMStorageAgent>(m_instrumentingAgents.get(), m_pageAgent);
</span><span class="cx"> InspectorDOMStorageAgent* domStorageAgent = domStorageAgentPtr.get();
</span><span class="cx"> m_agents.append(std::move(domStorageAgentPtr));
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorInstrumentationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx"> * Copyright (C) 2011 Google Inc. All rights reserved.
</span><ins>+* Copyright (C) 2014 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions are
</span><span class="lines">@@ -76,6 +77,11 @@
</span><span class="cx"> #include <wtf/StdLibExtras.h>
</span><span class="cx"> #include <wtf/text/CString.h>
</span><span class="cx">
</span><ins>+#if ENABLE(WEB_REPLAY)
+#include "InspectorReplayAgent.h"
+#include "ReplayController.h" // for ReplayPosition.
+#endif
+
</ins><span class="cx"> using namespace Inspector;
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -740,6 +746,13 @@
</span><span class="cx"> {
</span><span class="cx"> if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent())
</span><span class="cx"> pageAgent->frameDetached(frame);
</span><ins>+
+#if ENABLE(WEB_REPLAY)
+ if (frame->isMainFrame()) {
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->frameDetached(frame);
+ }
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void InspectorInstrumentation::didCommitLoadImpl(InstrumentingAgents* instrumentingAgents, Page* page, DocumentLoader* loader)
</span><span class="lines">@@ -772,6 +785,10 @@
</span><span class="cx"> domAgent->didCommitLoad(loader->frame()->document());
</span><span class="cx"> if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent())
</span><span class="cx"> pageAgent->frameNavigated(loader);
</span><ins>+#if ENABLE(WEB_REPLAY)
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->frameNavigated(loader);
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void InspectorInstrumentation::frameDocumentUpdatedImpl(InstrumentingAgents* instrumentingAgents, Frame* frame)
</span><span class="lines">@@ -1045,6 +1062,80 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+#if ENABLE(WEB_REPLAY)
+void InspectorInstrumentation::sessionCreatedImpl(InstrumentingAgents* instrumentingAgents, PassRefPtr<ReplaySession> session)
+{
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->sessionCreated(session);
+}
+
+void InspectorInstrumentation::sessionLoadedImpl(InstrumentingAgents* instrumentingAgents, PassRefPtr<ReplaySession> session)
+{
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->sessionLoaded(session);
+}
+
+void InspectorInstrumentation::sessionModifiedImpl(InstrumentingAgents* instrumentingAgents, PassRefPtr<ReplaySession> session)
+{
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->sessionModified(session);
+}
+
+void InspectorInstrumentation::segmentCreatedImpl(InstrumentingAgents* instrumentingAgents, PassRefPtr<ReplaySessionSegment> segment)
+{
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->segmentCreated(segment);
+}
+
+void InspectorInstrumentation::segmentCompletedImpl(InstrumentingAgents* instrumentingAgents, PassRefPtr<ReplaySessionSegment> segment)
+{
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->segmentCompleted(segment);
+}
+
+void InspectorInstrumentation::segmentLoadedImpl(InstrumentingAgents* instrumentingAgents, PassRefPtr<ReplaySessionSegment> segment)
+{
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->segmentLoaded(segment);
+}
+
+void InspectorInstrumentation::segmentUnloadedImpl(InstrumentingAgents* instrumentingAgents)
+{
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->segmentUnloaded();
+}
+
+void InspectorInstrumentation::captureStartedImpl(InstrumentingAgents* instrumentingAgents)
+{
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->captureStarted();
+}
+
+void InspectorInstrumentation::captureStoppedImpl(InstrumentingAgents* instrumentingAgents)
+{
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->captureStopped();
+}
+
+void InspectorInstrumentation::playbackStartedImpl(InstrumentingAgents* instrumentingAgents)
+{
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->playbackStarted();
+}
+
+void InspectorInstrumentation::playbackPausedImpl(InstrumentingAgents* instrumentingAgents, const ReplayPosition& position)
+{
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->playbackPaused(position);
+}
+
+void InspectorInstrumentation::playbackHitPositionImpl(InstrumentingAgents* instrumentingAgents, const ReplayPosition& position)
+{
+ if (InspectorReplayAgent* replayAgent = instrumentingAgents->inspectorReplayAgent())
+ replayAgent->playbackHitPosition(position);
+}
+#endif
+
</ins><span class="cx"> void InspectorInstrumentation::networkStateChangedImpl(InstrumentingAgents* instrumentingAgents)
</span><span class="cx"> {
</span><span class="cx"> if (InspectorApplicationCacheAgent* applicationCacheAgent = instrumentingAgents->inspectorApplicationCacheAgent())
</span><span class="lines">@@ -1070,6 +1161,17 @@
</span><span class="cx"> return instrumentingAgents && instrumentingAgents->inspectorTimelineAgent();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+bool InspectorInstrumentation::replayAgentEnabled(ScriptExecutionContext* scriptExecutionContext)
+{
+#if ENABLE(WEB_REPLAY)
+ InstrumentingAgents* instrumentingAgents = instrumentingAgentsForContext(scriptExecutionContext);
+ return instrumentingAgents && instrumentingAgents->inspectorReplayAgent();
+#else
+ UNUSED_PARAM(scriptExecutionContext);
+ return false;
+#endif
+}
+
</ins><span class="cx"> void InspectorInstrumentation::pauseOnNativeEventIfNeeded(InstrumentingAgents* instrumentingAgents, bool isDOMEvent, const String& eventName, bool synchronous)
</span><span class="cx"> {
</span><span class="cx"> if (InspectorDOMDebuggerAgent* domDebuggerAgent = instrumentingAgents->inspectorDOMDebuggerAgent())
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorInstrumentationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx"> * Copyright (C) 2010 Google Inc. All rights reserved.
</span><ins>+* Copyright (C) 2014 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions are
</span><span class="lines">@@ -45,6 +46,12 @@
</span><span class="cx"> #include <inspector/ConsoleTypes.h>
</span><span class="cx"> #include <wtf/RefPtr.h>
</span><span class="cx">
</span><ins>+#if ENABLE(WEB_REPLAY)
+#include "ReplaySession.h"
+#include "ReplaySessionSegment.h"
+#endif
+
+
</ins><span class="cx"> namespace Deprecated {
</span><span class="cx"> class ScriptObject;
</span><span class="cx"> }
</span><span class="lines">@@ -93,6 +100,8 @@
</span><span class="cx"> class WorkerGlobalScopeProxy;
</span><span class="cx"> class XMLHttpRequest;
</span><span class="cx">
</span><ins>+struct ReplayPosition;
+
</ins><span class="cx"> #define FAST_RETURN_IF_NO_FRONTENDS(value) if (LIKELY(!hasFrontends())) return value;
</span><span class="cx">
</span><span class="cx"> class InspectorInstrumentation {
</span><span class="lines">@@ -239,6 +248,24 @@
</span><span class="cx"> static void workerGlobalScopeTerminated(ScriptExecutionContext*, WorkerGlobalScopeProxy*);
</span><span class="cx"> static void willEvaluateWorkerScript(WorkerGlobalScope*, int workerThreadStartMode);
</span><span class="cx">
</span><ins>+#if ENABLE(WEB_REPLAY)
+ static void sessionCreated(Page*, PassRefPtr<ReplaySession>);
+ static void sessionLoaded(Page*, PassRefPtr<ReplaySession>);
+ static void sessionModified(Page*, PassRefPtr<ReplaySession>);
+
+ static void segmentCreated(Page*, PassRefPtr<ReplaySessionSegment>);
+ static void segmentCompleted(Page*, PassRefPtr<ReplaySessionSegment>);
+ static void segmentLoaded(Page*, PassRefPtr<ReplaySessionSegment>);
+ static void segmentUnloaded(Page*);
+
+ static void captureStarted(Page*);
+ static void captureStopped(Page*);
+
+ static void playbackStarted(Page*);
+ static void playbackPaused(Page*, const ReplayPosition&);
+ static void playbackHitPosition(Page*, const ReplayPosition&);
+#endif
+
</ins><span class="cx"> #if ENABLE(WEB_SOCKETS)
</span><span class="cx"> static void didCreateWebSocket(Document*, unsigned long identifier, const URL& requestURL, const URL& documentURL, const String& protocol);
</span><span class="cx"> static void willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const ResourceRequest&);
</span><span class="lines">@@ -263,11 +290,13 @@
</span><span class="cx"> static bool hasFrontends() { return s_frontendCounter; }
</span><span class="cx"> static bool consoleAgentEnabled(ScriptExecutionContext*);
</span><span class="cx"> static bool timelineAgentEnabled(ScriptExecutionContext*);
</span><ins>+ static bool replayAgentEnabled(ScriptExecutionContext*);
</ins><span class="cx"> #else
</span><span class="cx"> static bool hasFrontends() { return false; }
</span><span class="cx"> static bool consoleAgentEnabled(ScriptExecutionContext*) { return false; }
</span><span class="cx"> static bool runtimeAgentEnabled(Frame*) { return false; }
</span><span class="cx"> static bool timelineAgentEnabled(ScriptExecutionContext*) { return false; }
</span><ins>+ static bool replayAgentEnabled(ScriptExecutionContext*) { return false; }
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> static void registerInstrumentingAgents(InstrumentingAgents*);
</span><span class="lines">@@ -416,6 +445,24 @@
</span><span class="cx"> static void didStartWorkerGlobalScopeImpl(InstrumentingAgents*, WorkerGlobalScopeProxy*, const URL&);
</span><span class="cx"> static void workerGlobalScopeTerminatedImpl(InstrumentingAgents*, WorkerGlobalScopeProxy*);
</span><span class="cx">
</span><ins>+#if ENABLE(WEB_REPLAY)
+ static void sessionCreatedImpl(InstrumentingAgents*, PassRefPtr<ReplaySession>);
+ static void sessionLoadedImpl(InstrumentingAgents*, PassRefPtr<ReplaySession>);
+ static void sessionModifiedImpl(InstrumentingAgents*, PassRefPtr<ReplaySession>);
+
+ static void segmentCreatedImpl(InstrumentingAgents*, PassRefPtr<ReplaySessionSegment>);
+ static void segmentCompletedImpl(InstrumentingAgents*, PassRefPtr<ReplaySessionSegment>);
+ static void segmentLoadedImpl(InstrumentingAgents*, PassRefPtr<ReplaySessionSegment>);
+ static void segmentUnloadedImpl(InstrumentingAgents*);
+
+ static void captureStartedImpl(InstrumentingAgents*);
+ static void captureStoppedImpl(InstrumentingAgents*);
+
+ static void playbackStartedImpl(InstrumentingAgents*);
+ static void playbackPausedImpl(InstrumentingAgents*, const ReplayPosition&);
+ static void playbackHitPositionImpl(InstrumentingAgents*, const ReplayPosition&);
+#endif
+
</ins><span class="cx"> #if ENABLE(WEB_SOCKETS)
</span><span class="cx"> static void didCreateWebSocketImpl(InstrumentingAgents*, unsigned long identifier, const URL& requestURL, const URL& documentURL, const String& protocol, Document*);
</span><span class="cx"> static void willSendWebSocketHandshakeRequestImpl(InstrumentingAgents*, unsigned long identifier, const ResourceRequest&, Document*);
</span><span class="lines">@@ -1773,6 +1820,148 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+#if ENABLE(WEB_REPLAY)
+inline void InspectorInstrumentation::sessionCreated(Page* page, PassRefPtr<ReplaySession> session)
+{
+#if ENABLE(INSPECTOR)
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page))
+ sessionCreatedImpl(instrumentingAgents, session);
+#else
+ UNUSED_PARAM(page);
+ UNUSED_PARAM(session);
+#endif
+}
+
+inline void InspectorInstrumentation::sessionLoaded(Page* page, PassRefPtr<ReplaySession> session)
+{
+#if ENABLE(INSPECTOR)
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page))
+ sessionLoadedImpl(instrumentingAgents, session);
+#else
+ UNUSED_PARAM(page);
+ UNUSED_PARAM(session);
+#endif
+}
+
+inline void InspectorInstrumentation::sessionModified(Page* page, PassRefPtr<ReplaySession> session)
+{
+#if ENABLE(INSPECTOR)
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page))
+ sessionModifiedImpl(instrumentingAgents, session);
+#else
+ UNUSED_PARAM(page);
+ UNUSED_PARAM(session);
+#endif
+}
+
+inline void InspectorInstrumentation::segmentCreated(Page* page, PassRefPtr<ReplaySessionSegment> segment)
+{
+#if ENABLE(INSPECTOR)
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page))
+ segmentCreatedImpl(instrumentingAgents, segment);
+#else
+ UNUSED_PARAM(page);
+ UNUSED_PARAM(segment);
+#endif
+}
+
+inline void InspectorInstrumentation::segmentCompleted(Page* page, PassRefPtr<ReplaySessionSegment> segment)
+{
+#if ENABLE(INSPECTOR)
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page))
+ segmentCompletedImpl(instrumentingAgents, segment);
+#else
+ UNUSED_PARAM(page);
+ UNUSED_PARAM(segment);
+#endif
+}
+
+inline void InspectorInstrumentation::segmentLoaded(Page* page, PassRefPtr<ReplaySessionSegment> segment)
+{
+#if ENABLE(INSPECTOR)
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page))
+ segmentLoadedImpl(instrumentingAgents, segment);
+#else
+ UNUSED_PARAM(page);
+ UNUSED_PARAM(segment);
+#endif
+}
+
+inline void InspectorInstrumentation::segmentUnloaded(Page* page)
+{
+#if ENABLE(INSPECTOR)
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page))
+ segmentUnloadedImpl(instrumentingAgents);
+#else
+ UNUSED_PARAM(page);
+#endif
+}
+
+inline void InspectorInstrumentation::captureStarted(Page* page)
+{
+#if ENABLE(INSPECTOR)
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page))
+ captureStartedImpl(instrumentingAgents);
+#else
+ UNUSED_PARAM(page);
+#endif
+}
+
+inline void InspectorInstrumentation::captureStopped(Page* page)
+{
+#if ENABLE(INSPECTOR)
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page))
+ captureStoppedImpl(instrumentingAgents);
+#else
+ UNUSED_PARAM(page);
+#endif
+}
+
+inline void InspectorInstrumentation::playbackStarted(Page* page)
+{
+#if ENABLE(INSPECTOR)
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page))
+ playbackStartedImpl(instrumentingAgents);
+#else
+ UNUSED_PARAM(page);
+#endif
+}
+
+inline void InspectorInstrumentation::playbackPaused(Page* page, const ReplayPosition& position)
+{
+#if ENABLE(INSPECTOR)
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page))
+ playbackPausedImpl(instrumentingAgents, position);
+#else
+ UNUSED_PARAM(page);
+ UNUSED_PARAM(position);
+#endif
+}
+
+inline void InspectorInstrumentation::playbackHitPosition(Page* page, const ReplayPosition& position)
+{
+#if ENABLE(INSPECTOR)
+ FAST_RETURN_IF_NO_FRONTENDS(void());
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForPage(page))
+ playbackHitPositionImpl(instrumentingAgents, position);
+#else
+ UNUSED_PARAM(page);
+ UNUSED_PARAM(position);
+#endif
+}
+#endif // ENABLE(WEB_REPLAY)
+
</ins><span class="cx"> inline void InspectorInstrumentation::networkStateChanged(Page* page)
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(INSPECTOR)
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorReplayAgentcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/inspector/InspectorReplayAgent.cpp (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorReplayAgent.cpp         (rev 0)
+++ trunk/Source/WebCore/inspector/InspectorReplayAgent.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,484 @@
</span><ins>+/*
+ * Copyright (C) 2011-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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#include "config.h"
+#include "InspectorReplayAgent.h"
+
+#if ENABLE(INSPECTOR) && ENABLE(WEB_REPLAY)
+
+#include "DocumentLoader.h"
+#include "Event.h"
+#include "EventLoopInput.h"
+#include "Frame.h"
+#include "FunctorInputCursor.h"
+#include "InspectorController.h"
+#include "InspectorPageAgent.h"
+#include "InspectorWebTypeBuilders.h"
+#include "InstrumentingAgents.h"
+#include "Logging.h"
+#include "Page.h"
+#include "ReplayController.h"
+#include "ReplaySession.h"
+#include "ReplaySessionSegment.h"
+#include "SerializationMethods.h"
+#include "WebReplayInputs.h" // For EncodingTraits<InputQueue>.
+#include <inspector/InspectorValues.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+using namespace Inspector;
+
+namespace WebCore {
+
+static PassRefPtr<TypeBuilder::Replay::ReplayPosition> buildInspectorObjectForPosition(const ReplayPosition& position)
+{
+ RefPtr<TypeBuilder::Replay::ReplayPosition> positionObject = TypeBuilder::Replay::ReplayPosition::create()
+ .setSegmentOffset(position.segmentOffset)
+ .setInputOffset(position.inputOffset);
+
+ return positionObject.release();
+}
+
+static PassRefPtr<TypeBuilder::Replay::ReplayInput> buildInspectorObjectForInput(const NondeterministicInputBase& input, size_t offset)
+{
+ EncodedValue encodedInput = EncodingTraits<NondeterministicInputBase>::encodeValue(input);
+ RefPtr<TypeBuilder::Replay::ReplayInput> inputObject = TypeBuilder::Replay::ReplayInput::create()
+ .setType(input.type())
+ .setOffset(offset)
+ .setData(encodedInput.asObject());
+
+ if (input.queue() == InputQueue::EventLoopInput)
+ inputObject->setTimestamp(static_cast<const EventLoopInputBase&>(input).timestamp());
+
+ return inputObject.release();
+}
+
+static PassRefPtr<TypeBuilder::Replay::ReplaySession> buildInspectorObjectForSession(PassRefPtr<ReplaySession> prpSession)
+{
+ RefPtr<ReplaySession> session = prpSession;
+ RefPtr<TypeBuilder::Array<SegmentIdentifier>> segments = TypeBuilder::Array<SegmentIdentifier>::create();
+
+ for (auto it = session->begin(); it != session->end(); ++it)
+ segments->addItem((*it)->identifier());
+
+ RefPtr<TypeBuilder::Replay::ReplaySession> sessionObject = TypeBuilder::Replay::ReplaySession::create()
+ .setId(session->identifier())
+ .setTimestamp(session->timestamp())
+ .setSegments(segments.release());
+
+ return sessionObject.release();
+}
+
+class SerializeInputToJSONFunctor {
+public:
+ typedef PassRefPtr<TypeBuilder::Array<TypeBuilder::Replay::ReplayInput>> ReturnType;
+
+ SerializeInputToJSONFunctor()
+ : m_inputs(TypeBuilder::Array<TypeBuilder::Replay::ReplayInput>::create()) { }
+ ~SerializeInputToJSONFunctor() { }
+
+ void operator()(size_t index, const NondeterministicInputBase* input)
+ {
+ LOG(WebReplay, "%-25s Writing %5zu: %s\n", "[SerializeInput]", index, input->type().string().ascii().data());
+
+ if (RefPtr<TypeBuilder::Replay::ReplayInput> serializedInput = buildInspectorObjectForInput(*input, index))
+ m_inputs->addItem(serializedInput.release());
+ }
+
+ ReturnType returnValue() { return m_inputs.release(); }
+private:
+ RefPtr<TypeBuilder::Array<TypeBuilder::Replay::ReplayInput>> m_inputs;
+};
+
+static PassRefPtr<TypeBuilder::Replay::SessionSegment> buildInspectorObjectForSegment(PassRefPtr<ReplaySessionSegment> prpSegment)
+{
+ RefPtr<ReplaySessionSegment> segment = prpSegment;
+ RefPtr<TypeBuilder::Array<TypeBuilder::Replay::ReplayInputQueue>> queuesObject = TypeBuilder::Array<TypeBuilder::Replay::ReplayInputQueue>::create();
+
+ for (size_t i = 0; i < static_cast<size_t>(InputQueue::Count); i++) {
+ SerializeInputToJSONFunctor collector;
+ InputQueue queue = static_cast<InputQueue>(i);
+ RefPtr<TypeBuilder::Array<TypeBuilder::Replay::ReplayInput>> queueInputs = segment->createFunctorCursor()->forEachInputInQueue(queue, collector);
+
+ RefPtr<TypeBuilder::Replay::ReplayInputQueue> queueObject = TypeBuilder::Replay::ReplayInputQueue::create()
+ .setType(EncodingTraits<InputQueue>::encodeValue(queue).convertTo<String>())
+ .setInputs(queueInputs);
+
+ queuesObject->addItem(queueObject.release());
+ }
+
+ RefPtr<TypeBuilder::Replay::SessionSegment> segmentObject = TypeBuilder::Replay::SessionSegment::create()
+ .setId(segment->identifier())
+ .setTimestamp(segment->timestamp())
+ .setQueues(queuesObject.release());
+
+ return segmentObject.release();
+}
+
+InspectorReplayAgent::InspectorReplayAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent)
+ : InspectorAgentBase(ASCIILiteral("Replay"), instrumentingAgents)
+ , m_page(*pageAgent->page())
+{
+}
+
+InspectorReplayAgent::~InspectorReplayAgent()
+{
+ ASSERT(!m_sessionsMap.size());
+ ASSERT(!m_segmentsMap.size());
+}
+
+SessionState InspectorReplayAgent::sessionState() const
+{
+ return m_page.replayController().sessionState();
+}
+
+void InspectorReplayAgent::didCreateFrontendAndBackend(InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher)
+{
+ m_frontendDispatcher = std::make_unique<InspectorReplayFrontendDispatcher>(frontendChannel);
+ m_backendDispatcher = InspectorReplayBackendDispatcher::create(backendDispatcher, this);
+
+ m_instrumentingAgents->setInspectorReplayAgent(this);
+ ASSERT(sessionState() == SessionState::Inactive);
+
+ // Keep track of the (default) session currently loaded by ReplayController,
+ // and any segments within the session.
+ RefPtr<ReplaySession> session = m_page.replayController().loadedSession();
+ m_sessionsMap.add(session->identifier(), session.release());
+
+ for (auto it = session->begin(); it != session->end(); ++it)
+ m_segmentsMap.add((*it)->identifier(), *it);
+}
+
+void InspectorReplayAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason)
+{
+ m_frontendDispatcher = nullptr;
+ m_backendDispatcher.clear();
+
+ m_instrumentingAgents->setInspectorReplayAgent(nullptr);
+
+ // Drop references to all sessions and segments.
+ m_sessionsMap.clear();
+ m_segmentsMap.clear();
+}
+
+void InspectorReplayAgent::frameNavigated(DocumentLoader* loader)
+{
+ if (sessionState() != SessionState::Inactive)
+ m_page.replayController().frameNavigated(loader);
+}
+
+void InspectorReplayAgent::frameDetached(Frame* frame)
+{
+ if (sessionState() != SessionState::Inactive)
+ m_page.replayController().frameDetached(frame);
+}
+
+void InspectorReplayAgent::sessionCreated(PassRefPtr<ReplaySession> prpSession)
+{
+ RefPtr<ReplaySession> session = prpSession;
+
+ auto result = m_sessionsMap.add(session->identifier(), session);
+ // Can't have two sessions with same identifier.
+ ASSERT_UNUSED(result, result.isNewEntry);
+
+ m_frontendDispatcher->sessionCreated(session->identifier());
+}
+
+void InspectorReplayAgent::sessionModified(PassRefPtr<ReplaySession> session)
+{
+ m_frontendDispatcher->sessionModified(session->identifier());
+}
+
+void InspectorReplayAgent::sessionLoaded(PassRefPtr<ReplaySession> prpSession)
+{
+ RefPtr<ReplaySession> session = prpSession;
+
+ // In case we didn't know about the loaded session, add here.
+ m_sessionsMap.add(session->identifier(), session);
+
+ m_frontendDispatcher->sessionLoaded(session->identifier());
+}
+
+void InspectorReplayAgent::segmentCreated(PassRefPtr<ReplaySessionSegment> prpSegment)
+{
+ RefPtr<ReplaySessionSegment> segment = prpSegment;
+
+ auto result = m_segmentsMap.add(segment->identifier(), segment);
+ // Can't have two segments with the same identifier.
+ ASSERT_UNUSED(result, result.isNewEntry);
+
+ m_frontendDispatcher->segmentCreated(segment->identifier());
+}
+
+void InspectorReplayAgent::segmentCompleted(PassRefPtr<ReplaySessionSegment> segment)
+{
+ m_frontendDispatcher->segmentCompleted(segment->identifier());
+}
+
+void InspectorReplayAgent::segmentLoaded(PassRefPtr<ReplaySessionSegment> prpSegment)
+{
+ RefPtr<ReplaySessionSegment> segment = prpSegment;
+
+ // In case we didn't know about the loaded segment, add here.
+ m_segmentsMap.add(segment->identifier(), segment);
+
+ m_frontendDispatcher->segmentLoaded(segment->identifier());
+}
+
+void InspectorReplayAgent::segmentUnloaded()
+{
+ m_frontendDispatcher->segmentUnloaded();
+}
+
+void InspectorReplayAgent::captureStarted()
+{
+ LOG(WebReplay, "-----CAPTURE START-----");
+
+ m_frontendDispatcher->captureStarted();
+}
+
+void InspectorReplayAgent::captureStopped()
+{
+ LOG(WebReplay, "-----CAPTURE STOP-----");
+
+ m_frontendDispatcher->captureStopped();
+}
+
+void InspectorReplayAgent::playbackStarted()
+{
+ LOG(WebReplay, "-----REPLAY START-----");
+
+ m_frontendDispatcher->playbackStarted();
+}
+
+void InspectorReplayAgent::playbackPaused(const ReplayPosition& position)
+{
+ LOG(WebReplay, "-----REPLAY PAUSED-----");
+
+ m_frontendDispatcher->playbackPaused(buildInspectorObjectForPosition(position));
+}
+
+void InspectorReplayAgent::playbackHitPosition(const ReplayPosition& position)
+{
+ m_frontendDispatcher->playbackHitPosition(buildInspectorObjectForPosition(position), monotonicallyIncreasingTime());
+}
+
+void InspectorReplayAgent::startCapturing(ErrorString* errorString)
+{
+ if (sessionState() != SessionState::Inactive) {
+ *errorString = ASCIILiteral("Can't start capturing if the session is already capturing or replaying.");
+ return;
+ }
+
+ m_page.replayController().startCapturing();
+}
+
+void InspectorReplayAgent::stopCapturing(ErrorString* errorString)
+{
+ if (sessionState() != SessionState::Capturing) {
+ *errorString = ASCIILiteral("Can't stop capturing if capture is not in progress.");
+ return;
+ }
+
+ m_page.replayController().stopCapturing();
+}
+
+void InspectorReplayAgent::replayToPosition(ErrorString* errorString, const RefPtr<InspectorObject>& positionObject, bool fastReplay)
+{
+ ReplayPosition position;
+ if (!positionObject->getNumber(ASCIILiteral("segmentOffset"), &position.segmentOffset)) {
+ *errorString = ASCIILiteral("Couldn't decode ReplayPosition segment offset provided to ReplayAgent.replayToPosition.");
+ return;
+ }
+
+ if (!positionObject->getNumber(ASCIILiteral("inputOffset"), &position.inputOffset)) {
+ *errorString = ASCIILiteral("Couldn't decode ReplayPosition input offset provided to ReplayAgent.replayToPosition.");
+ return;
+ }
+
+ if (sessionState() != SessionState::Inactive) {
+ *errorString = ASCIILiteral("Can't start replay while capture or playback is in progress.");
+ return;
+ }
+
+ m_page.replayController().replayToPosition(position, (fastReplay) ? DispatchSpeed::FastForward : DispatchSpeed::RealTime);
+}
+
+void InspectorReplayAgent::replayToCompletion(ErrorString* errorString, bool fastReplay)
+{
+ if (sessionState() != SessionState::Inactive) {
+ *errorString = ASCIILiteral("Can't start replay while capture or playback is in progress.");
+ return;
+ }
+
+ m_page.replayController().replayToCompletion((fastReplay) ? DispatchSpeed::FastForward : DispatchSpeed::RealTime);
+}
+
+void InspectorReplayAgent::pausePlayback(ErrorString* errorString)
+{
+ if (sessionState() != SessionState::Replaying) {
+ *errorString = ASCIILiteral("Can't pause playback if playback is not in progress.");
+ return;
+ }
+
+ m_page.replayController().pausePlayback();
+}
+
+void InspectorReplayAgent::cancelPlayback(ErrorString* errorString)
+{
+ if (sessionState() == SessionState::Capturing) {
+ *errorString = ASCIILiteral("Can't cancel playback if capture is in progress.");
+ return;
+ }
+
+ m_page.replayController().cancelPlayback();
+}
+
+void InspectorReplayAgent::switchSession(ErrorString* errorString, SessionIdentifier identifier)
+{
+ ASSERT(identifier > 0);
+
+ if (sessionState() != SessionState::Inactive) {
+ *errorString = ASCIILiteral("Can't switch sessions unless the session is neither capturing or replaying.");
+ return;
+ }
+
+ RefPtr<ReplaySession> session = findSession(errorString, identifier);
+ if (!session)
+ return;
+
+ m_page.replayController().switchSession(session);
+}
+
+void InspectorReplayAgent::insertSessionSegment(ErrorString* errorString, SessionIdentifier sessionIdentifier, SegmentIdentifier segmentIdentifier, int segmentIndex)
+{
+ ASSERT(sessionIdentifier > 0);
+ ASSERT(segmentIdentifier > 0);
+ ASSERT(segmentIndex >= 0);
+
+ RefPtr<ReplaySession> session = findSession(errorString, sessionIdentifier);
+ RefPtr<ReplaySessionSegment> segment = findSegment(errorString, segmentIdentifier);
+
+ if (!session || !segment)
+ return;
+
+ if (static_cast<size_t>(segmentIndex) > session->size()) {
+ *errorString = ASCIILiteral("Invalid segment index.");
+ return;
+ }
+
+ if (session == m_page.replayController().loadedSession() && sessionState() != SessionState::Inactive) {
+ *errorString = ASCIILiteral("Can't modify a loaded session unless the session is inactive.");
+ return;
+ }
+
+ session->insertSegment(segmentIndex, segment);
+ sessionModified(session);
+}
+
+void InspectorReplayAgent::removeSessionSegment(ErrorString* errorString, SessionIdentifier identifier, int segmentIndex)
+{
+ ASSERT(identifier > 0);
+ ASSERT(segmentIndex >= 0);
+
+ RefPtr<ReplaySession> session = findSession(errorString, identifier);
+
+ if (!session)
+ return;
+
+ if (static_cast<size_t>(segmentIndex) >= session->size()) {
+ *errorString = ASCIILiteral("Invalid segment index.");
+ return;
+ }
+
+ if (session == m_page.replayController().loadedSession() && sessionState() != SessionState::Inactive) {
+ *errorString = ASCIILiteral("Can't modify a loaded session unless the session is inactive.");
+ return;
+ }
+
+ session->removeSegment(segmentIndex);
+ sessionModified(session);
+}
+
+PassRefPtr<ReplaySession> InspectorReplayAgent::findSession(ErrorString* errorString, SessionIdentifier identifier)
+{
+ ASSERT(identifier > 0);
+
+ auto it = m_sessionsMap.find(identifier);
+ if (it == m_sessionsMap.end()) {
+ *errorString = ASCIILiteral("Couldn't find session with specified identifier");
+ return nullptr;
+ }
+
+ return it->value;
+}
+
+PassRefPtr<ReplaySessionSegment> InspectorReplayAgent::findSegment(ErrorString* errorString, SegmentIdentifier identifier)
+{
+ ASSERT(identifier > 0);
+
+ auto it = m_segmentsMap.find(identifier);
+ if (it == m_segmentsMap.end()) {
+ *errorString = ASCIILiteral("Couldn't find segment with specified identifier");
+ return nullptr;
+ }
+
+ return it->value;
+}
+
+void InspectorReplayAgent::getAvailableSessions(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<SessionIdentifier>>& sessionsList)
+{
+ sessionsList = TypeBuilder::Array<SessionIdentifier>::create();
+ for (auto& pair : m_sessionsMap)
+ sessionsList->addItem(pair.key);
+}
+
+void InspectorReplayAgent::getSerializedSession(ErrorString* errorString, SessionIdentifier identifier, RefPtr<Inspector::TypeBuilder::Replay::ReplaySession>& serializedObject)
+{
+ RefPtr<ReplaySession> session = findSession(errorString, identifier);
+ if (!session) {
+ *errorString = ASCIILiteral("Couldn't find the specified session.");
+ return;
+ }
+
+ serializedObject = buildInspectorObjectForSession(session);
+}
+
+void InspectorReplayAgent::getSerializedSegment(ErrorString* errorString, SegmentIdentifier identifier, RefPtr<Inspector::TypeBuilder::Replay::SessionSegment>& serializedObject)
+{
+ RefPtr<ReplaySessionSegment> segment = findSegment(errorString, identifier);
+ if (!segment) {
+ *errorString = ASCIILiteral("Couldn't find the specified segment.");
+ return;
+ }
+
+ serializedObject = buildInspectorObjectForSegment(segment);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INSPECTOR) && ENABLE(WEB_REPLAY)
</ins></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorReplayAgenth"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/inspector/InspectorReplayAgent.h (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorReplayAgent.h         (rev 0)
+++ trunk/Source/WebCore/inspector/InspectorReplayAgent.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,125 @@
</span><ins>+/*
+ * Copyright (C) 2011-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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#ifndef InspectorReplayAgent_h
+#define InspectorReplayAgent_h
+
+#if ENABLE(INSPECTOR) && ENABLE(WEB_REPLAY)
+
+#include "InspectorWebAgentBase.h"
+#include "InspectorWebBackendDispatchers.h"
+#include "InspectorWebFrontendDispatchers.h"
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class DocumentLoader;
+class Frame;
+class InspectorPageAgent;
+class InstrumentingAgents;
+class Page;
+class ReplaySession;
+class ReplaySessionSegment;
+
+enum class SessionState;
+
+struct ReplayPosition;
+
+typedef String ErrorString;
+typedef int SessionIdentifier;
+typedef int SegmentIdentifier;
+
+class InspectorReplayAgent final
+ : public InspectorAgentBase
+ , public Inspector::InspectorReplayBackendDispatcherHandler {
+ WTF_MAKE_NONCOPYABLE(InspectorReplayAgent);
+public:
+ InspectorReplayAgent(InstrumentingAgents*, InspectorPageAgent*);
+ ~InspectorReplayAgent();
+
+ virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override;
+ virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override;
+
+ // Callbacks from InspectorInstrumentation.
+ void frameNavigated(DocumentLoader*);
+ void frameDetached(Frame*);
+
+ // Notifications from ReplayController.
+ void sessionCreated(PassRefPtr<ReplaySession>);
+ // This is called internally (when adding/removing) and by ReplayController during capture.
+ void sessionModified(PassRefPtr<ReplaySession>);
+ void sessionLoaded(PassRefPtr<ReplaySession>);
+
+ void segmentCreated(PassRefPtr<ReplaySessionSegment>);
+ void segmentCompleted(PassRefPtr<ReplaySessionSegment>);
+ void segmentLoaded(PassRefPtr<ReplaySessionSegment>);
+ void segmentUnloaded();
+
+ void captureStarted();
+ void captureStopped();
+
+ void playbackStarted();
+ void playbackPaused(const ReplayPosition&);
+ void playbackHitPosition(const ReplayPosition&);
+
+ // Calls from the Inspector frontend.
+ virtual void startCapturing(ErrorString*) override;
+ virtual void stopCapturing(ErrorString*) override;
+
+ virtual void replayToPosition(ErrorString*, const RefPtr<Inspector::InspectorObject>&, bool shouldFastForward) override;
+ virtual void replayToCompletion(ErrorString*, bool shouldFastForward) override;
+ virtual void pausePlayback(ErrorString*) override;
+ virtual void cancelPlayback(ErrorString*) override;
+
+ virtual void switchSession(ErrorString*, SessionIdentifier) override;
+ virtual void insertSessionSegment(ErrorString*, SessionIdentifier, SegmentIdentifier, int segmentIndex) override;
+ virtual void removeSessionSegment(ErrorString*, SessionIdentifier, int segmentIndex) override;
+
+ virtual void getAvailableSessions(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<SessionIdentifier>>&) override;
+ virtual void getSerializedSession(ErrorString*, SessionIdentifier, RefPtr<Inspector::TypeBuilder::Replay::ReplaySession>&) override;
+ virtual void getSerializedSegment(ErrorString*, SegmentIdentifier, RefPtr<Inspector::TypeBuilder::Replay::SessionSegment>&) override;
+
+private:
+ PassRefPtr<ReplaySession> findSession(ErrorString*, SessionIdentifier);
+ PassRefPtr<ReplaySessionSegment> findSegment(ErrorString*, SegmentIdentifier);
+ SessionState sessionState() const;
+
+ std::unique_ptr<Inspector::InspectorReplayFrontendDispatcher> m_frontendDispatcher;
+ RefPtr<Inspector::InspectorReplayBackendDispatcher> m_backendDispatcher;
+ Page& m_page;
+
+ HashMap<int, RefPtr<ReplaySession>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> m_sessionsMap;
+ HashMap<int, RefPtr<ReplaySessionSegment>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> m_segmentsMap;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(INSPECTOR) && ENABLE(WEB_REPLAY)
+
+#endif // InspectorReplayAgent_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreinspectorInstrumentingAgentscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InstrumentingAgents.cpp (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InstrumentingAgents.cpp        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/inspector/InstrumentingAgents.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx"> * Copyright (C) 2011 Google Inc. All rights reserved.
</span><ins>+ * Copyright (C) 2014 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions are
</span><span class="lines">@@ -56,6 +57,9 @@
</span><span class="cx"> , m_workerRuntimeAgent(nullptr)
</span><span class="cx"> , m_inspectorTimelineAgent(nullptr)
</span><span class="cx"> , m_inspectorDOMStorageAgent(nullptr)
</span><ins>+#if ENABLE(WEB_REPLAY)
+ , m_inspectorReplayAgent(nullptr)
+#endif
</ins><span class="cx"> #if ENABLE(SQL_DATABASE)
</span><span class="cx"> , m_inspectorDatabaseAgent(nullptr)
</span><span class="cx"> #endif
</span><span class="lines">@@ -81,6 +85,9 @@
</span><span class="cx"> m_workerRuntimeAgent = nullptr;
</span><span class="cx"> m_inspectorTimelineAgent = nullptr;
</span><span class="cx"> m_inspectorDOMStorageAgent = nullptr;
</span><ins>+#if ENABLE(WEB_REPLAY)
+ m_inspectorReplayAgent = nullptr;
+#endif
</ins><span class="cx"> #if ENABLE(SQL_DATABASE)
</span><span class="cx"> m_inspectorDatabaseAgent = nullptr;
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInstrumentingAgentsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InstrumentingAgents.h (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InstrumentingAgents.h        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/inspector/InstrumentingAgents.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -1,5 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx"> * Copyright (C) 2011 Google Inc. All rights reserved.
</span><ins>+ * Copyright (C) 2014 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions are
</span><span class="lines">@@ -55,6 +56,7 @@
</span><span class="cx"> class InspectorPageAgent;
</span><span class="cx"> class InspectorProfilerAgent;
</span><span class="cx"> class InspectorResourceAgent;
</span><ins>+class InspectorReplayAgent;
</ins><span class="cx"> class InspectorTimelineAgent;
</span><span class="cx"> class InspectorWorkerAgent;
</span><span class="cx"> class Page;
</span><span class="lines">@@ -107,6 +109,11 @@
</span><span class="cx"> InspectorDOMStorageAgent* inspectorDOMStorageAgent() const { return m_inspectorDOMStorageAgent; }
</span><span class="cx"> void setInspectorDOMStorageAgent(InspectorDOMStorageAgent* agent) { m_inspectorDOMStorageAgent = agent; }
</span><span class="cx">
</span><ins>+#if ENABLE(WEB_REPLAY)
+ InspectorReplayAgent* inspectorReplayAgent() const { return m_inspectorReplayAgent; }
+ void setInspectorReplayAgent(InspectorReplayAgent* agent) { m_inspectorReplayAgent = agent; }
+#endif
+
</ins><span class="cx"> #if ENABLE(SQL_DATABASE)
</span><span class="cx"> InspectorDatabaseAgent* inspectorDatabaseAgent() const { return m_inspectorDatabaseAgent; }
</span><span class="cx"> void setInspectorDatabaseAgent(InspectorDatabaseAgent* agent) { m_inspectorDatabaseAgent = agent; }
</span><span class="lines">@@ -152,6 +159,9 @@
</span><span class="cx"> WorkerRuntimeAgent* m_workerRuntimeAgent;
</span><span class="cx"> InspectorTimelineAgent* m_inspectorTimelineAgent;
</span><span class="cx"> InspectorDOMStorageAgent* m_inspectorDOMStorageAgent;
</span><ins>+#if ENABLE(WEB_REPLAY)
+ InspectorReplayAgent* m_inspectorReplayAgent;
+#endif
</ins><span class="cx"> #if ENABLE(SQL_DATABASE)
</span><span class="cx"> InspectorDatabaseAgent* m_inspectorDatabaseAgent;
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorprotocolReplayjson"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/inspector/protocol/Replay.json (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/protocol/Replay.json         (rev 0)
+++ trunk/Source/WebCore/inspector/protocol/Replay.json        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,242 @@
</span><ins>+{
+ "domain": "Replay",
+ "description": "Controls web replay, and manages recording sessions and segments.",
+ "types": [
+ {
+ "id": "SessionIdentifier", "description": "Unique replay session identifier.",
+ "type": "integer"
+ },
+ {
+ "id": "SegmentIdentifier", "description": "Unique session segment identifier.",
+ "type": "integer"
+ },
+ {
+ "id": "ReplayPosition",
+ "type": "object",
+ "properties": [
+ { "name": "segmentOffset", "type": "integer", "description": "Offset for a segment within the currently-loaded replay session." },
+ { "name": "inputOffset", "type": "integer", "description": "Offset for an event loop input within the specified session segment." }
+ ]
+ },
+ {
+ "id": "ReplayInput",
+ "type": "object",
+ "properties": [
+ { "name": "type", "type": "string", "description": "Input type." },
+ { "name": "offset", "type": "integer", "description": "Offset of this input in its respective queue."},
+ { "name": "timestamp", "type": "number", "optional": true, "description": "The timestamp of this input." },
+ { "name": "data", "type": "object", "description": "Per-input payload." }
+ ]
+ },
+ {
+ "id": "ReplayInputQueue",
+ "type": "object",
+ "properties": [
+ { "name": "type", "type": "string", "description": "Queue type" },
+ { "name": "inputs", "type": "array", "items": { "$ref": "ReplayInput"}, "description": "Inputs belonging to this queue." }
+ ]
+ },
+ {
+ "id": "SessionSegment", "description": "A standalone segment of a replay session that corresponds to a single main frame navigation and execution.",
+ "type": "object",
+ "properties": [
+ { "name": "id", "$ref": "SegmentIdentifier", "description": "Unique session segment identifier." },
+ { "name": "timestamp", "type": "number", "description": "Start time of the segment, in milliseconds since the epoch." },
+ { "name": "queues", "type": "array", "items": { "$ref": "ReplayInputQueue"} }
+ ]
+ },
+ {
+ "id": "ReplaySession", "description": "An ordered collection of replay session segments.",
+ "type": "object",
+ "properties": [
+ { "name": "id", "$ref": "SessionIdentifier", "description": "Unique replay session identifier." },
+ { "name": "timestamp", "type": "number", "description": "Creation time of session, in milliseconds since the epoch." },
+ { "name": "segments", "type": "array", "items": { "$ref": "SegmentIdentifier" }, "description": "An ordered list identifiers for the segments that comprise this replay session." }
+ ]
+ }
+ ],
+ "commands": [
+ {
+ "name": "startCapturing",
+ "description": "Starts capture of a new replay session."
+ },
+ {
+ "name": "stopCapturing",
+ "description": "Stops capture of the currently recording replay session."
+ },
+ {
+ "name": "replayToPosition",
+ "description": "Seek execution to a specific position within the replay session.",
+ "parameters": [
+ { "name": "position", "$ref": "ReplayPosition" },
+ { "name": "shouldFastForward", "type": "boolean" }
+ ]
+ },
+ {
+ "name": "replayToCompletion",
+ "description": "Replay all session segments completely.",
+ "parameters": [
+ { "name": "shouldFastForward", "type": "boolean" }
+ ]
+ },
+ {
+ "name": "pausePlayback",
+ "description": "Pauses playback in the current segment. Can be resumed by using a replay command."
+ },
+ {
+ "name": "cancelPlayback",
+ "description": "Cancels playback of the current segment. Further replaying will start from the beginning of the current segment."
+ },
+ {
+ "name": "switchSession",
+ "description": "Unloads the current replay session and loads the specified session",
+ "parameters": [
+ { "name": "sessionIdentifier", "$ref": "SessionIdentifier" }
+ ]
+ },
+ {
+ "name": "insertSessionSegment",
+ "description": "Splices the specified session segment into the session at the specified index.",
+ "parameters": [
+ { "name": "sessionIdentifier", "$ref": "SessionIdentifier" },
+ { "name": "segmentIdentifier", "$ref": "SegmentIdentifier" },
+ { "name": "segmentIndex", "type": "integer" }
+ ]
+ },
+ {
+ "name": "removeSessionSegment",
+ "description": "Removes the session segment at the specified position from the session.",
+ "parameters": [
+ { "name": "sessionIdentifier", "$ref": "SessionIdentifier" },
+ { "name": "segmentIndex", "type": "integer" }
+ ]
+ },
+ {
+ "name": "getAvailableSessions",
+ "description": "Returns identifiers of all available sessions.",
+ "returns": [
+ { "name": "ids", "type": "array", "items": { "$ref": "SessionIdentifier" } }
+ ]
+ },
+ {
+ "name": "getSerializedSession",
+ "description": "Returns the specified session serialized to a JSON object.",
+ "parameters": [
+ { "name": "sessionIdentifier", "$ref": "SessionIdentifier" }
+ ],
+ "returns": [
+ { "name": "session", "$ref": "ReplaySession", "optional": true, "description": "The requested serialized replay session." }
+ ]
+ },
+ {
+ "name": "getSerializedSegment",
+ "description": "Returns the session segment serialized to a JSON object.",
+ "parameters": [
+ { "name": "id", "$ref": "SegmentIdentifier" }
+ ],
+ "returns": [
+ { "name": "segment", "$ref": "SessionSegment", "optional": true, "description": "The requested serialized session segment." }
+ ]
+ }
+ ],
+ "events": [
+ {
+ "name": "captureStarted",
+ "description": "Fired when capture has started."
+ },
+ {
+ "name": "captureStopped",
+ "description": "Fired when capture has stopped."
+ },
+ {
+ "name": "playbackHitPosition",
+ "description": "A position was reached during playback of the session.",
+ "parameters": [
+ { "name": "position", "$ref": "ReplayPosition", "description": "The playback position that was hit." },
+ { "name": "timestamp", "type": "number", "description": "A timestamp for the event." }
+ ]
+ },
+ {
+ "name": "playbackStarted",
+ "description": "Fired when session playback has started."
+ },
+ {
+ "name": "playbackPaused",
+ "description": "Fired when session playback has paused, but not finished.",
+ "parameters": [
+ { "name": "position", "$ref": "ReplayPosition", "description": "The playback position immediately prior to where playback is paused." }
+ ]
+ },
+ {
+ "name": "playbackFinished",
+ "description": "Fired when session playback has stopped."
+ },
+ {
+ "name": "inputSuppressionChanged",
+ "description": "Fired when the replay controller starts or stops suppressing user inputs.",
+ "parameters": [
+ { "name": "willSuppress", "type": "boolean", "description": "Whether user inputs will be suppressed during playback." }
+ ]
+ },
+ {
+ "name": "sessionCreated",
+ "description": "Fired when a new replay session is created",
+ "parameters": [
+ { "name": "id", "$ref": "SessionIdentifier", "description": "Identifier for the created session." }
+ ]
+ },
+ {
+ "name": "sessionModified",
+ "description": "Fired when a session's segments have changed.",
+ "parameters": [
+ { "name": "id", "$ref": "SessionIdentifier", "description": "Identifier for the session the segment was added to." }
+ ]
+ },
+ {
+ "name": "sessionRemoved",
+ "description": "Fired when a replay session is removed and can no longer be loaded.",
+ "parameters": [
+ { "name": "id", "$ref": "SessionIdentifier", "description": "Identifier for the removed session." }
+ ]
+ },
+ {
+ "name": "sessionLoaded",
+ "description": "Fired when a replay session is loaded.",
+ "parameters": [
+ { "name": "id", "$ref": "SessionIdentifier", "description": "Identifier for the loaded session." }
+ ]
+ },
+ {
+ "name": "segmentCreated",
+ "description": "Fired when a new session segment is created.",
+ "parameters": [
+ { "name": "id", "$ref": "SegmentIdentifier", "description": "Identifier for the created session segment." }
+ ]
+ },
+ {
+ "name": "segmentRemoved",
+ "description": "Fired when a session segment is removed and can no longer be replayed as part of a session.",
+ "parameters": [
+ { "name": "id", "$ref": "SegmentIdentifier", "description": "Identifier for the removed session segment." }
+ ]
+ },
+ {
+ "name": "segmentCompleted",
+ "description": "Fired when a session segment is completed and can no longer have inputs added to it.",
+ "parameters": [
+ { "name": "id", "$ref": "SegmentIdentifier", "description": "Identifier for the completed session segment." }
+ ]
+ },
+ {
+ "name": "segmentLoaded",
+ "description": "Fired when a segment is loaded.",
+ "parameters": [
+ { "name": "segmentIdentifier", "$ref": "SegmentIdentifier", "description": "Id for the loaded segment." }
+ ]
+ },
+ {
+ "name": "segmentUnloaded",
+ "description": "Fired when a segment is unloaded."
+ }
+ ]
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoremakegeneratedsourcessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/make-generated-sources.sh (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/make-generated-sources.sh        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/make-generated-sources.sh        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -3,6 +3,7 @@
</span><span class="cx"> export SRCROOT=$PWD
</span><span class="cx"> export WebCore=$PWD
</span><span class="cx"> export InspectorScripts=$PWD/../JavaScriptCore/inspector/scripts
</span><ins>+export WebReplayScripts=$PWD/../JavaScriptCore/replay/scripts
</ins><span class="cx">
</span><span class="cx"> mkdir -p DerivedSources/WebCore &&
</span><span class="cx"> make -C DerivedSources/WebCore -f ../../DerivedSources.make $@
</span></span></pre></div>
<a id="trunkSourceWebCorepagePagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Page.cpp (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Page.cpp        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/page/Page.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -94,6 +94,10 @@
</span><span class="cx"> #include <wtf/text/Base64.h>
</span><span class="cx"> #include <wtf/text/StringHash.h>
</span><span class="cx">
</span><ins>+#if ENABLE(WEB_REPLAY)
+#include "ReplayController.h"
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> static HashSet<Page*>* allPages;
</span><span class="lines">@@ -129,6 +133,9 @@
</span><span class="cx"> , m_contextMenuController(std::make_unique<ContextMenuController>(*this, *pageClients.contextMenuClient))
</span><span class="cx"> #endif
</span><span class="cx"> , m_userInputBridge(std::make_unique<UserInputBridge>(*this))
</span><ins>+#if ENABLE(WEB_REPLAY)
+ , m_replayController(std::make_unique<ReplayController>(*this))
+#endif
</ins><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx"> , m_inspectorController(std::make_unique<InspectorController>(*this, pageClients.inspectorClient))
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorepagePageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Page.h (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Page.h        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/page/Page.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -99,6 +99,7 @@
</span><span class="cx"> class Range;
</span><span class="cx"> class RenderObject;
</span><span class="cx"> class RenderTheme;
</span><ins>+class ReplayController;
</ins><span class="cx"> class VisibleSelection;
</span><span class="cx"> class ScrollableArea;
</span><span class="cx"> class ScrollingCoordinator;
</span><span class="lines">@@ -199,6 +200,9 @@
</span><span class="cx"> ContextMenuController& contextMenuController() const { return *m_contextMenuController; }
</span><span class="cx"> #endif
</span><span class="cx"> UserInputBridge& userInputBridge() const { return *m_userInputBridge; }
</span><ins>+#if ENABLE(WEB_REPLAY)
+ ReplayController& replayController() const { return *m_replayController; }
+#endif
</ins><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx"> InspectorController& inspectorController() const { return *m_inspectorController; }
</span><span class="cx"> #endif
</span><span class="lines">@@ -447,6 +451,9 @@
</span><span class="cx"> const std::unique_ptr<ContextMenuController> m_contextMenuController;
</span><span class="cx"> #endif
</span><span class="cx"> const std::unique_ptr<UserInputBridge> m_userInputBridge;
</span><ins>+#if ENABLE(WEB_REPLAY)
+ const std::unique_ptr<ReplayController> m_replayController;
+#endif
</ins><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx"> const std::unique_ptr<InspectorController> m_inspectorController;
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformLoggingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/Logging.h (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/Logging.h        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/platform/Logging.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -70,6 +70,7 @@
</span><span class="cx"> M(Threading) \
</span><span class="cx"> M(WebAudio) \
</span><span class="cx"> M(WebGL) \
</span><ins>+ M(WebReplay) \
</ins><span class="cx">
</span><span class="cx"> #define DECLARE_LOG_CHANNEL(name) \
</span><span class="cx"> extern WTFLogChannel JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, name);
</span></span></pre></div>
<a id="trunkSourceWebCorereplayAllReplayInputshfromrev164983trunkSourceWebCorereplayReplayInputTypescpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/replay/AllReplayInputs.h (from rev 164983, trunk/Source/WebCore/replay/ReplayInputTypes.cpp) (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/AllReplayInputs.h         (rev 0)
+++ trunk/Source/WebCore/replay/AllReplayInputs.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+// This file is the include equivalent for WEB_REPLAY_INPUT_NAMES_FOR_EACH.
+// Note that there is not an exact correspondence between the two, since
+// Some input types reside in the same file.
+
+// Make sure that this stays in sync with ReplayInputTypes.h for custom inputs.
+
+#ifndef AllReplayInputs_h
+#define AllReplayInputs_h
+
+#if ENABLE(WEB_REPLAY)
+
+#include "WebReplayInputs.h"
+#include <JavaScriptCore/JSReplayInputs.h>
+
+#define IMPORT_FROM_JSC_NAMESPACE(name) \
+using JSC::name; \
+
+JS_REPLAY_INPUT_NAMES_FOR_EACH(IMPORT_FROM_JSC_NAMESPACE)
+
+#endif // ENABLE(WEB_REPLAY)
+
+#endif // AllReplayInputs_h
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayCapturingInputCursorcppfromrev164983trunkSourceWebCorereplayReplayInputTypescpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/replay/CapturingInputCursor.cpp (from rev 164983, trunk/Source/WebCore/replay/ReplayInputTypes.cpp) (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/CapturingInputCursor.cpp         (rev 0)
+++ trunk/Source/WebCore/replay/CapturingInputCursor.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,76 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#include "config.h"
+#include "CapturingInputCursor.h"
+
+#if ENABLE(WEB_REPLAY)
+
+#include "Logging.h"
+#include "SegmentedInputStorage.h"
+
+namespace WebCore {
+
+CapturingInputCursor::CapturingInputCursor(SegmentedInputStorage& storage)
+ : m_storage(storage)
+{
+ LOG(WebReplay, "%-30sCreated capture cursor=%p.\n", "[ReplayController]", this);
+}
+
+CapturingInputCursor::~CapturingInputCursor()
+{
+ LOG(WebReplay, "%-30sDestroyed capture cursor=%p.\n", "[ReplayController]", this);
+}
+
+PassRefPtr<CapturingInputCursor> CapturingInputCursor::create(SegmentedInputStorage& storage)
+{
+ return adoptRef(new CapturingInputCursor(storage));
+}
+
+void CapturingInputCursor::storeInput(std::unique_ptr<NondeterministicInputBase> input)
+{
+ ASSERT(input);
+ m_storage.store(std::move(input));
+}
+
+NondeterministicInputBase* CapturingInputCursor::loadInput(InputQueue, const AtomicString&)
+{
+ // Can't load inputs from capturing cursor.
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+NondeterministicInputBase* CapturingInputCursor::uncheckedLoadInput(InputQueue)
+{
+ // Can't load inputs from capturing cursor.
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+}; // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayCapturingInputCursorhfromrev164983trunkSourceWebCorereplayReplayInputTypesh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/replay/CapturingInputCursor.h (from rev 164983, trunk/Source/WebCore/replay/ReplayInputTypes.h) (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/CapturingInputCursor.h         (rev 0)
+++ trunk/Source/WebCore/replay/CapturingInputCursor.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#ifndef CapturingInputCursor_h
+#define CapturingInputCursor_h
+
+#if ENABLE(WEB_REPLAY)
+
+#include <replay/InputCursor.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class SegmentedInputStorage;
+
+class CapturingInputCursor final : public InputCursor {
+ WTF_MAKE_NONCOPYABLE(CapturingInputCursor);
+public:
+ static PassRefPtr<CapturingInputCursor> create(SegmentedInputStorage&);
+ virtual ~CapturingInputCursor();
+
+ virtual bool isCapturing() const override { return true; }
+ virtual bool isReplaying() const override { return false; }
+
+ virtual NondeterministicInputBase* uncheckedLoadInput(InputQueue) override;
+ virtual void storeInput(std::unique_ptr<NondeterministicInputBase>) override;
+protected:
+ virtual NondeterministicInputBase* loadInput(InputQueue, const AtomicString& type) override;
+private:
+ explicit CapturingInputCursor(SegmentedInputStorage&);
+
+ SegmentedInputStorage& m_storage;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
+
+#endif // CapturingInputCursor_h
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayEventLoopInputh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/replay/EventLoopInput.h (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/EventLoopInput.h        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/replay/EventLoopInput.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -37,38 +37,22 @@
</span><span class="cx">
</span><span class="cx"> class ReplayController;
</span><span class="cx">
</span><del>-struct ReplayPosition {
-public:
- ReplayPosition()
- : m_index(0)
- , m_time(0.0) { }
-
- explicit ReplayPosition(unsigned index)
- : m_index(index)
- , m_time(monotonicallyIncreasingTime()) { }
-
- unsigned index() const { return m_index; }
- double time() const { return m_time; }
-private:
- unsigned m_index;
- double m_time;
-};
-
</del><span class="cx"> class EventLoopInputBase : public NondeterministicInputBase {
</span><span class="cx"> public:
</span><span class="cx"> EventLoopInputBase()
</span><del>- : m_position(ReplayPosition()) { }
</del><ins>+ : m_timestamp(monotonicallyIncreasingTime())
+ {
+ }
</ins><span class="cx">
</span><span class="cx"> virtual ~EventLoopInputBase() { }
</span><span class="cx"> virtual InputQueue queue() const override final { return InputQueue::EventLoopInput; }
</span><span class="cx">
</span><span class="cx"> virtual void dispatch(ReplayController&) = 0;
</span><span class="cx">
</span><del>- // During capture, the position is set when the following event loop input is captured.
- void setPosition(const ReplayPosition& position) { m_position = position; }
- ReplayPosition position() const { return m_position; }
</del><ins>+ double timestamp() const { return m_timestamp; }
+ void setTimestamp(double timestamp) { m_timestamp = timestamp; }
</ins><span class="cx"> protected:
</span><del>- ReplayPosition m_position;
</del><ins>+ double m_timestamp;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> template <typename InputType>
</span></span></pre></div>
<a id="trunkSourceWebCorereplayEventLoopInputDispatchercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/replay/EventLoopInputDispatcher.cpp (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/EventLoopInputDispatcher.cpp         (rev 0)
+++ trunk/Source/WebCore/replay/EventLoopInputDispatcher.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,175 @@
</span><ins>+/*
+ * Copyright (C) 2011-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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#include "config.h"
+#include "EventLoopInputDispatcher.h"
+
+#if ENABLE(WEB_REPLAY)
+
+#include "Page.h"
+#include "ReplayInputTypes.h"
+#include "ReplayingInputCursor.h"
+#include <wtf/TemporaryChange.h>
+
+#if !LOG_DISABLED
+#include "Logging.h"
+#include "SerializationMethods.h"
+#include <replay/EncodedValue.h>
+#include <wtf/text/CString.h>
+#endif
+
+namespace WebCore {
+
+EventLoopInputDispatcher::EventLoopInputDispatcher(Page& page, ReplayingInputCursor& cursor, EventLoopInputDispatcherClient* client)
+ : m_page(page)
+ , m_client(client)
+ , m_cursor(cursor)
+ , m_timer(this, &EventLoopInputDispatcher::timerFired)
+ , m_runningInput(nullptr)
+ , m_dispatching(false)
+ , m_running(false)
+ , m_speed(DispatchSpeed::FastForward)
+ , m_previousDispatchStartTime(0.0)
+ , m_previousInputTimestamp(0.0)
+{
+}
+
+void EventLoopInputDispatcher::run()
+{
+ ASSERT(!m_running);
+ m_running = true;
+
+ LOG(WebReplay, "%-20s Starting dispatch of event loop inputs for page: %p\n", "ReplayEvents", &m_page);
+ dispatchInputSoon();
+}
+
+void EventLoopInputDispatcher::pause()
+{
+ ASSERT(!m_dispatching);
+ ASSERT(m_running);
+ m_running = false;
+
+ LOG(WebReplay, "%-20s Pausing dispatch of event loop inputs for page: %p\n", "ReplayEvents", &m_page);
+ if (m_timer.isActive())
+ m_timer.stop();
+}
+
+void EventLoopInputDispatcher::timerFired(Timer<EventLoopInputDispatcher>*)
+{
+ dispatchInput();
+}
+
+void EventLoopInputDispatcher::dispatchInputSoon()
+{
+ ASSERT(m_running);
+
+ // We may already have an input if replay was paused just before dispatching.
+ if (!m_runningInput)
+ m_runningInput = safeCast<EventLoopInputBase*>(m_cursor.uncheckedLoadInput(InputQueue::EventLoopInput));
+
+ if (m_timer.isActive())
+ m_timer.stop();
+
+ double waitInterval = 0;
+
+ if (m_speed == DispatchSpeed::RealTime) {
+ // The goal is to reproduce the dispatch delay between inputs as it was
+ // was observed during the recording. So, we need to compute how much time
+ // to wait such that the elapsed time plus the wait time will equal the
+ // observed delay between the previous and current input.
+
+ if (!m_previousInputTimestamp)
+ m_previousInputTimestamp = m_runningInput->timestamp();
+
+ double targetInterval = m_runningInput->timestamp() - m_previousInputTimestamp;
+ double elapsed = monotonicallyIncreasingTime() - m_previousDispatchStartTime;
+ waitInterval = targetInterval - elapsed;
+ }
+
+ // A negative wait time means that dispatch took longer on replay than on
+ // capture. In this case, proceed without waiting at all.
+ if (waitInterval < 0)
+ waitInterval = 0;
+
+ if (waitInterval > 1000.0) {
+ LOG_ERROR("%-20s Tried to wait for over 1000 seconds before dispatching next event loop input; this is probably a bug.", "ReplayEvents");
+ waitInterval = 0;
+ }
+
+ LOG(WebReplay, "%-20s (WAIT: %.3f ms)", "ReplayEvents", waitInterval * 1000.0);
+ m_timer.startOneShot(waitInterval);
+}
+
+void EventLoopInputDispatcher::dispatchInput()
+{
+ ASSERT(m_runningInput);
+ ASSERT(!m_dispatching);
+
+ if (m_speed == DispatchSpeed::RealTime) {
+ m_previousDispatchStartTime = monotonicallyIncreasingTime();
+ m_previousInputTimestamp = m_runningInput->timestamp();
+ }
+
+#if !LOG_DISABLED
+ EncodedValue encodedInput = EncodingTraits<NondeterministicInputBase>::encodeValue(*m_runningInput);
+ String jsonString = encodedInput.asObject()->toJSONString();
+
+ LOG(WebReplay, "%-20s ----------------------------------------------", "ReplayEvents");
+ LOG(WebReplay, "%-20s >DISPATCH: %s %s\n", "ReplayEvents", m_runningInput->type().string().utf8().data(), jsonString.utf8().data());
+#endif
+
+ m_client->willDispatchInput(*m_runningInput);
+ // Client could stop replay in the previous callback, so check again.
+ if (!m_running)
+ return;
+
+ {
+ TemporaryChange<bool> change(m_dispatching, true);
+ m_runningInput->dispatch(m_page.replayController());
+ }
+
+ EventLoopInputBase* dispatchedInput = m_runningInput;
+ m_runningInput = nullptr;
+
+ // Notify clients that the event was dispatched.
+ m_client->didDispatchInput(*dispatchedInput);
+ if (dispatchedInput->type() == inputTypes().EndSegmentSentinel) {
+ m_running = false;
+ m_client->didDispatchFinalInput();
+ return;
+ }
+
+ // Clients could stop replay during event dispatch, or from any callback above.
+ if (!m_running)
+ return;
+
+ dispatchInputSoon();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayEventLoopInputDispatcherh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/replay/EventLoopInputDispatcher.h (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/EventLoopInputDispatcher.h         (rev 0)
+++ trunk/Source/WebCore/replay/EventLoopInputDispatcher.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,95 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#ifndef EventLoopInputDispatcher_h
+#define EventLoopInputDispatcher_h
+
+#if ENABLE(WEB_REPLAY)
+
+#include "EventLoopInput.h"
+#include "Timer.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class Page;
+class ReplayingInputCursor;
+
+enum class DispatchSpeed {
+ RealTime,
+ FastForward,
+};
+
+class EventLoopInputDispatcherClient {
+public:
+ EventLoopInputDispatcherClient() { }
+ virtual ~EventLoopInputDispatcherClient() { }
+
+ virtual void willDispatchInput(const EventLoopInputBase&) =0;
+ virtual void didDispatchInput(const EventLoopInputBase&) =0;
+ virtual void didDispatchFinalInput() =0;
+};
+
+class EventLoopInputDispatcher {
+ WTF_MAKE_NONCOPYABLE(EventLoopInputDispatcher);
+public:
+ EventLoopInputDispatcher(Page&, ReplayingInputCursor&, EventLoopInputDispatcherClient*);
+
+ void run();
+ void pause();
+
+ void setDispatchSpeed(DispatchSpeed speed) { m_speed = speed; }
+ DispatchSpeed dispatchSpeed() const { return m_speed; }
+private:
+ void dispatchInputSoon();
+ void dispatchInput();
+ void timerFired(Timer<EventLoopInputDispatcher>*);
+
+ Page& m_page;
+ EventLoopInputDispatcherClient* m_client;
+ ReplayingInputCursor& m_cursor;
+ Timer<EventLoopInputDispatcher> m_timer;
+
+ // This pointer is valid when an event loop input is presently dispatching.
+ EventLoopInputBase* m_runningInput;
+ bool m_dispatching;
+ bool m_running;
+
+ DispatchSpeed m_speed;
+ // The time at which the last input dispatch() method was called.
+ double m_previousDispatchStartTime;
+ // The timestamp specified by the last dispatched input.
+ double m_previousInputTimestamp;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
+
+#endif // EventLoopInputDispatcher_h
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayFunctorInputCursorh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/replay/FunctorInputCursor.h (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/FunctorInputCursor.h         (rev 0)
+++ trunk/Source/WebCore/replay/FunctorInputCursor.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#ifndef FunctorInputCursor_h
+#define FunctorInputCursor_h
+
+#if ENABLE(WEB_REPLAY)
+
+#include "SegmentedInputStorage.h"
+#include <replay/InputCursor.h>
+#include <replay/NondeterministicInput.h>
+#include <wtf/Assertions.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class FunctorInputCursor final : public InputCursor {
+ WTF_MAKE_NONCOPYABLE(FunctorInputCursor);
+public:
+ FunctorInputCursor(SegmentedInputStorage&);
+ virtual ~FunctorInputCursor() { }
+
+ // InputCursor
+ virtual bool isCapturing() const override { return false; }
+ virtual bool isReplaying() const override { return false; }
+
+ virtual void storeInput(std::unique_ptr<NondeterministicInputBase>) override;
+ virtual NondeterministicInputBase* uncheckedLoadInput(InputQueue) override;
+
+ template<typename Functor>
+ typename Functor::ReturnType forEachInputInQueue(InputQueue, Functor&);
+protected:
+ virtual NondeterministicInputBase* loadInput(InputQueue, const AtomicString&) override;
+private:
+ SegmentedInputStorage& m_storage;
+};
+
+template<typename Functor> inline
+typename Functor::ReturnType FunctorInputCursor::forEachInputInQueue(InputQueue queue, Functor& functor)
+{
+ for (size_t i = 0; i < m_storage.queueSize(queue); i++)
+ functor(i, m_storage.queue(queue).at(i).get());
+
+ return functor.returnValue();
+}
+
+inline FunctorInputCursor::FunctorInputCursor(SegmentedInputStorage& storage)
+ : m_storage(storage)
+{
+}
+
+inline void FunctorInputCursor::storeInput(std::unique_ptr<NondeterministicInputBase>)
+{
+ ASSERT_NOT_REACHED();
+}
+
+inline NondeterministicInputBase* FunctorInputCursor::loadInput(InputQueue, const AtomicString&)
+{
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+inline NondeterministicInputBase* FunctorInputCursor::uncheckedLoadInput(InputQueue)
+{
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
+
+#endif // FunctorInputCursor_h
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayReplayControllercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/replay/ReplayController.cpp (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/ReplayController.cpp         (rev 0)
+++ trunk/Source/WebCore/replay/ReplayController.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,363 @@
</span><ins>+/*
+ * Copyright (C) 2011-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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#include "config.h"
+#include "ReplayController.h"
+
+#if ENABLE(WEB_REPLAY)
+
+#include "AllReplayInputs.h"
+#include "CapturingInputCursor.h"
+#include "DOMWindow.h"
+#include "DocumentLoader.h"
+#include "Frame.h"
+#include "FrameTree.h"
+#include "InspectorInstrumentation.h"
+#include "Logging.h"
+#include "MainFrame.h"
+#include "Page.h"
+#include "ReplaySession.h"
+#include "ReplaySessionSegment.h"
+#include "ReplayingInputCursor.h"
+#include "ScriptController.h"
+#include "WebReplayInputs.h"
+#include <replay/EmptyInputCursor.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+ReplayController::ReplayController(Page& page)
+ : m_page(page)
+ , m_loadedSegment(nullptr)
+ , m_loadedSession(ReplaySession::create())
+ , m_emptyCursor(EmptyInputCursor::create())
+ , m_activeCursor(nullptr)
+ , m_targetPosition(ReplayPosition(0, 0))
+ , m_currentPosition(ReplayPosition(0, 0))
+ , m_segmentState(SegmentState::Unloaded)
+ , m_sessionState(SessionState::Inactive)
+ , m_dispatchSpeed(DispatchSpeed::FastForward)
+{
+}
+
+void ReplayController::switchSession(PassRefPtr<ReplaySession> session)
+{
+ ASSERT(m_segmentState == SegmentState::Unloaded);
+ ASSERT(m_sessionState == SessionState::Inactive);
+
+ m_loadedSession = session;
+ m_currentPosition = ReplayPosition(0, 0);
+
+ LOG(WebReplay, "%-20sSwitching sessions from %p to %p.\n", "ReplayController", m_loadedSession.get(), session.get());
+ InspectorInstrumentation::sessionLoaded(&m_page, m_loadedSession);
+}
+
+void ReplayController::createSegment()
+{
+ ASSERT(m_sessionState == SessionState::Capturing);
+ ASSERT(m_segmentState == SegmentState::Unloaded);
+
+ m_segmentState = SegmentState::Appending;
+
+ // Create a new segment but don't associate it with the current session
+ // until we stop appending to it. This preserves the invariant that
+ // segments associated with a replay session have immutable data.
+ m_loadedSegment = ReplaySessionSegment::create();
+
+ LOG(WebReplay, "%-20s Created segment: %p.\n", "ReplayController", m_loadedSegment.get());
+ InspectorInstrumentation::segmentCreated(&m_page, m_loadedSegment);
+
+ m_activeCursor = m_loadedSegment->createCapturingCursor(m_page);
+ m_activeCursor->appendInput<BeginSegmentSentinel>();
+
+ std::unique_ptr<InitialNavigation> navigationInput = InitialNavigation::createFromPage(m_page);
+ // Dispatching this input schedules navigation of the main frame, causing a refresh.
+ navigationInput->dispatch(*this);
+ m_activeCursor->storeInput(std::move(navigationInput));
+}
+
+void ReplayController::completeSegment()
+{
+ ASSERT(m_sessionState == SessionState::Capturing);
+ ASSERT(m_segmentState == SegmentState::Appending);
+
+ m_activeCursor->appendInput<EndSegmentSentinel>();
+
+ // Hold on to a reference so unloading the segment doesn't deallocate it.
+ RefPtr<ReplaySessionSegment> segment = m_loadedSegment;
+ m_segmentState = SegmentState::Loaded;
+ bool shouldSuppressNotifications = true;
+ unloadSegment(shouldSuppressNotifications);
+
+ LOG(WebReplay, "%-20s Completed segment: %p.\n", "ReplayController", segment.get());
+ InspectorInstrumentation::segmentCompleted(&m_page, segment);
+
+ m_loadedSession->appendSegment(segment);
+ InspectorInstrumentation::sessionModified(&m_page, m_loadedSession);
+}
+
+void ReplayController::loadSegment(PassRefPtr<ReplaySessionSegment> prpSegment)
+{
+ RefPtr<ReplaySessionSegment> segment = prpSegment;
+
+ ASSERT(m_sessionState == SessionState::Replaying);
+ ASSERT(m_segmentState == SegmentState::Unloaded);
+ ASSERT(segment);
+ ASSERT(!m_loadedSegment);
+
+ m_loadedSegment = segment;
+ m_segmentState = SegmentState::Loaded;
+
+ m_activeCursor = m_loadedSegment->createReplayingCursor(m_page, this);
+ dispatcher().setDispatchSpeed(m_dispatchSpeed);
+
+ LOG(WebReplay, "%-20sLoading segment: %p.\n", "ReplayController", segment.get());
+ InspectorInstrumentation::segmentLoaded(&m_page, segment);
+}
+
+void ReplayController::unloadSegment(bool suppressNotifications)
+{
+ ASSERT(m_sessionState != SessionState::Inactive);
+ ASSERT(m_segmentState == SegmentState::Loaded);
+
+ m_segmentState = SegmentState::Unloaded;
+
+ LOG(WebReplay, "%-20s Clearing input cursors for page: %p\n", "ReplayController", &m_page);
+
+ m_activeCursor = nullptr;
+ RefPtr<ReplaySessionSegment> unloadedSegment = m_loadedSegment.release();
+ for (Frame* frame = &m_page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ frame->script().globalObject(mainThreadNormalWorld())->setInputCursor(m_emptyCursor);
+ frame->document()->setInputCursor(m_emptyCursor);
+ }
+
+ // When we stop capturing, don't send out segment unloaded events since we
+ // didn't send out the corresponding segmentLoaded event at the start of capture.
+ if (!suppressNotifications) {
+ LOG(WebReplay, "%-20sUnloading segment: %p.\n", "ReplayController", unloadedSegment.get());
+ InspectorInstrumentation::segmentUnloaded(&m_page);
+ }
+}
+
+void ReplayController::startCapturing()
+{
+ ASSERT(m_sessionState == SessionState::Inactive);
+ ASSERT(m_segmentState == SegmentState::Unloaded);
+
+ m_sessionState = SessionState::Capturing;
+
+ LOG(WebReplay, "%-20s Starting capture.\n", "ReplayController");
+ InspectorInstrumentation::captureStarted(&m_page);
+
+ m_currentPosition = ReplayPosition(0, 0);
+ createSegment();
+}
+
+void ReplayController::stopCapturing()
+{
+ ASSERT(m_sessionState == SessionState::Capturing);
+ ASSERT(m_segmentState == SegmentState::Appending);
+
+ completeSegment();
+
+ m_sessionState = SessionState::Inactive;
+
+ LOG(WebReplay, "%-20s Stopping capture.\n", "ReplayController");
+ InspectorInstrumentation::captureStopped(&m_page);
+}
+
+void ReplayController::startPlayback()
+{
+ ASSERT(m_sessionState == SessionState::Replaying);
+ ASSERT(m_segmentState == SegmentState::Loaded);
+
+ m_segmentState = SegmentState::Dispatching;
+
+ LOG(WebReplay, "%-20s Starting playback to position (segment: %d, input: %d).\n", "ReplayController", m_targetPosition.segmentOffset, m_targetPosition.inputOffset);
+ InspectorInstrumentation::playbackStarted(&m_page);
+
+ dispatcher().run();
+}
+
+void ReplayController::pausePlayback()
+{
+ ASSERT(m_sessionState == SessionState::Replaying);
+ ASSERT(m_segmentState == SegmentState::Dispatching);
+
+ m_segmentState = SegmentState::Loaded;
+
+ dispatcher().pause();
+
+ LOG(WebReplay, "%-20s Pausing playback at position (segment: %d, input: %d).\n", "ReplayController", m_currentPosition.segmentOffset, m_currentPosition.inputOffset);
+ InspectorInstrumentation::playbackPaused(&m_page, m_currentPosition);
+}
+
+void ReplayController::cancelPlayback()
+{
+ ASSERT(m_sessionState == SessionState::Replaying);
+ ASSERT(m_segmentState != SegmentState::Appending);
+
+ if (m_segmentState == SegmentState::Unloaded)
+ return;
+
+ if (m_segmentState == SegmentState::Dispatching)
+ pausePlayback();
+
+ ASSERT(m_segmentState == SegmentState::Loaded);
+ unloadSegment();
+ m_sessionState = SessionState::Inactive;
+}
+
+void ReplayController::replayToPosition(const ReplayPosition& position, DispatchSpeed speed)
+{
+ ASSERT(m_sessionState != SessionState::Capturing);
+ ASSERT(m_segmentState == SegmentState::Loaded || m_segmentState == SegmentState::Unloaded);
+ ASSERT(position.segmentOffset < m_loadedSession->size());
+
+ m_dispatchSpeed = speed;
+
+ if (m_sessionState != SessionState::Replaying)
+ m_sessionState = SessionState::Replaying;
+
+ if (m_segmentState == SegmentState::Unloaded)
+ loadSegment(m_loadedSession->at(position.segmentOffset));
+ else if (position.segmentOffset != m_currentPosition.segmentOffset || m_currentPosition.inputOffset > position.inputOffset) {
+ // If the desired segment is not loaded or we have gone past the desired input
+ // offset, then unload the current segment and load the appropriate segment.
+ unloadSegment();
+ loadSegment(m_loadedSession->at(position.segmentOffset));
+ }
+
+ ASSERT(m_currentPosition.segmentOffset == position.segmentOffset);
+ ASSERT(m_loadedSession->at(position.segmentOffset) == m_loadedSegment);
+
+ m_targetPosition = position;
+ startPlayback();
+}
+
+void ReplayController::frameNavigated(DocumentLoader* loader)
+{
+ ASSERT(m_sessionState != SessionState::Inactive);
+
+ // The initial capturing segment is created prior to main frame navigation.
+ // Otherwise, the prior capturing segment was completed when the frame detached,
+ // and it is now time to create a new segment.
+ if (m_sessionState == SessionState::Capturing && m_segmentState == SegmentState::Unloaded) {
+ m_currentPosition = ReplayPosition(m_currentPosition.segmentOffset + 1, 0);
+ createSegment();
+ }
+
+ // During playback, the next segment is loaded when the final input is dispatched,
+ // so nothing needs to be done here.
+
+ // We store the input cursor in both Document and JSDOMWindow, so that
+ // replay state is accessible from JavaScriptCore and script-free layout code.
+ loader->frame()->document()->setInputCursor(m_activeCursor.get());
+ loader->frame()->script().globalObject(mainThreadNormalWorld())->setInputCursor(m_activeCursor.get());
+}
+
+void ReplayController::frameDetached(Frame* frame)
+{
+ ASSERT(m_sessionState != SessionState::Inactive);
+ ASSERT(frame);
+
+ if (!frame->document())
+ return;
+
+ // If the frame's cursor isn't capturing or replaying, we should do nothing.
+ // This is the case for the "outbound" frame when starting capture, or when
+ // we clear the input cursor to finish or prematurely unload a segment.
+ if (frame->document()->inputCursor().isCapturing()) {
+ ASSERT(m_segmentState == SegmentState::Appending);
+ completeSegment();
+ }
+
+ // During playback, the segments are unloaded and loaded when the final
+ // input has been dispatched. So, nothing needs to be done here.
+}
+
+PassRefPtr<ReplaySession> ReplayController::loadedSession() const
+{
+ return m_loadedSession;
+}
+
+PassRefPtr<ReplaySessionSegment> ReplayController::loadedSegment() const
+{
+ return m_loadedSegment;
+}
+
+InputCursor& ReplayController::activeInputCursor() const
+{
+ return m_activeCursor ? *m_activeCursor : *m_emptyCursor;
+}
+
+EventLoopInputDispatcher& ReplayController::dispatcher() const
+{
+ ASSERT(m_sessionState == SessionState::Replaying);
+ ASSERT(m_segmentState == SegmentState::Dispatching);
+ ASSERT(m_activeCursor);
+ ASSERT(m_activeCursor->isReplaying());
+
+ return static_cast<ReplayingInputCursor&>(*m_activeCursor).dispatcher();
+}
+
+void ReplayController::willDispatchInput(const EventLoopInputBase&)
+{
+ ASSERT(m_sessionState == SessionState::Replaying);
+ ASSERT(m_segmentState == SegmentState::Dispatching);
+
+ m_currentPosition.inputOffset++;
+ if (m_currentPosition == m_targetPosition)
+ pausePlayback();
+}
+
+void ReplayController::didDispatchInput(const EventLoopInputBase&)
+{
+ ASSERT(m_sessionState == SessionState::Replaying);
+ ASSERT(m_segmentState == SegmentState::Dispatching);
+
+ InspectorInstrumentation::playbackHitPosition(&m_page, m_currentPosition);
+}
+
+void ReplayController::didDispatchFinalInput()
+{
+ ASSERT(m_segmentState == SegmentState::Dispatching);
+
+ pause();
+ unloadSegment();
+
+ // No more segments left to replay; stop.
+ if (++m_currentPosition.segmentOffset == m_loadedSession->size())
+ return;
+
+ loadSegment(m_loadedSession->at(m_currentPosition.segmentOffset));
+ startPlayback();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayReplayControllerh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/replay/ReplayController.h (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/ReplayController.h         (rev 0)
+++ trunk/Source/WebCore/replay/ReplayController.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,177 @@
</span><ins>+/*
+ * Copyright (C) 2011-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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#ifndef ReplayController_h
+#define ReplayController_h
+
+#if ENABLE(WEB_REPLAY)
+
+#include "EventLoopInputDispatcher.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+class InputCursor;
+}
+
+namespace WebCore {
+
+class DOMWindow;
+class Document;
+class DocumentLoader;
+class Element;
+class Event;
+class EventLoopInputBase;
+class Frame;
+class Node;
+class Page;
+class ReplaySession;
+class ReplaySessionSegment;
+
+// Each state may transition to the state immediately above or below it.
+// SessionState transitions are only allowed when SegmentState is Unloaded.
+enum class SessionState {
+ Capturing,
+ // Neither capturing or replaying. m_currentPosition is not valid in this state.
+ Inactive,
+ Replaying,
+};
+
+// Each state may transition to the state immediately above or below it.
+enum class SegmentState {
+ // Inputs can be appended into an unassociated session segment.
+ // We can stop capturing, which reverts to the Unloaded state.
+ Appending,
+ // No session segment is loaded.
+ // We can start capturing, or load a segment (and then replay it).
+ Unloaded,
+ // A session segment is loaded.
+ // We can unload the segment, or begin playback from m_currentPosition.
+ Loaded,
+ // The controller is actively dispatching event loop inputs.
+ // We can pause or cancel playback, which reverts to the Loaded state.
+ Dispatching,
+};
+
+struct ReplayPosition {
+ ReplayPosition(unsigned segmentOffset, unsigned inputOffset)
+ : segmentOffset(segmentOffset)
+ , inputOffset(inputOffset)
+ {
+ }
+
+ // By convention, this position represents the end of the last segment of the session.
+ ReplayPosition()
+ : segmentOffset(0)
+ , inputOffset(0)
+ {
+ }
+
+ bool operator<(const ReplayPosition& other)
+ {
+ return segmentOffset <= other.segmentOffset && inputOffset < other.inputOffset;
+ }
+
+ bool operator==(const ReplayPosition& other)
+ {
+ return segmentOffset == other.segmentOffset && inputOffset == other.inputOffset;
+ }
+
+ unsigned segmentOffset;
+ unsigned inputOffset;
+};
+
+class ReplayController final : public EventLoopInputDispatcherClient {
+ WTF_MAKE_NONCOPYABLE(ReplayController);
+public:
+ ReplayController(Page&);
+
+ void startCapturing();
+ void stopCapturing();
+
+ // Start or resume playback with default speed and target replay position.
+ void startPlayback();
+ void pausePlayback();
+ void cancelPlayback();
+
+ void replayToPosition(const ReplayPosition&, DispatchSpeed = DispatchSpeed::FastForward);
+ void replayToCompletion(DispatchSpeed speed = DispatchSpeed::FastForward)
+ {
+ replayToPosition(ReplayPosition(), speed);
+ }
+
+ void switchSession(PassRefPtr<ReplaySession>);
+
+ // InspectorReplayAgent notifications.
+ void frameNavigated(DocumentLoader*);
+ void frameDetached(Frame*);
+
+ Page& page() const { return m_page; }
+ SessionState sessionState() const { return m_sessionState; }
+ PassRefPtr<ReplaySession> loadedSession() const;
+ PassRefPtr<ReplaySessionSegment> loadedSegment() const;
+ JSC::InputCursor& activeInputCursor() const;
+
+private:
+ // EventLoopInputDispatcherClient API
+ virtual void willDispatchInput(const EventLoopInputBase&) override;
+ virtual void didDispatchInput(const EventLoopInputBase&) override;
+ virtual void didDispatchFinalInput() override;
+
+ void createSegment();
+ void completeSegment();
+
+ void loadSegment(PassRefPtr<ReplaySessionSegment>);
+ void unloadSegment(bool suppressNotifications = false);
+
+ EventLoopInputDispatcher& dispatcher() const;
+
+ Page& m_page;
+
+ RefPtr<ReplaySessionSegment> m_loadedSegment;
+ RefPtr<ReplaySession> m_loadedSession;
+ const RefPtr<JSC::InputCursor> m_emptyCursor;
+ // The active cursor is set to nullptr when invalid.
+ RefPtr<JSC::InputCursor> m_activeCursor;
+
+ // This position is valid when SessionState == Replaying.
+ ReplayPosition m_targetPosition;
+ // This position is valid when SessionState != Inactive.
+ ReplayPosition m_currentPosition;
+ SegmentState m_segmentState;
+ // This tracks state across multiple segments. When navigating the main frame,
+ // there is a small interval during segment switching when no segment is loaded.
+ SessionState m_sessionState;
+
+ DispatchSpeed m_dispatchSpeed;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
+
+#endif // ReplayController_h
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayReplayInputCreationMethodscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/replay/ReplayInputCreationMethods.cpp (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/ReplayInputCreationMethods.cpp         (rev 0)
+++ trunk/Source/WebCore/replay/ReplayInputCreationMethods.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+/*
+ * Copyright (C) 2011-2013 University of Washington.
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_REPLAY)
+
+#include "Document.h"
+#include "MainFrame.h"
+#include "Page.h"
+#include "SecurityOrigin.h"
+#include "SerializationMethods.h"
+#include "WebReplayInputs.h"
+
+namespace WebCore {
+
+std::unique_ptr<InitialNavigation> InitialNavigation::createFromPage(const Page& page)
+{
+ const MainFrame& mainFrame = page.mainFrame();
+ ASSERT(mainFrame.document());
+
+ // Make sure that this is in sync with ReplayController::beginCapturing().
+ RefPtr<SecurityOrigin> originCopy = mainFrame.document()->securityOrigin()->isolatedCopy();
+ URL url = mainFrame.document()->url();
+ String referrer = mainFrame.loader().referrer();
+ return std::make_unique<InitialNavigation>(originCopy, url, referrer);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayReplayInputDispatchMethodscppfromrev164983trunkSourceWebCorereplayReplayInputTypescpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/replay/ReplayInputDispatchMethods.cpp (from rev 164983, trunk/Source/WebCore/replay/ReplayInputTypes.cpp) (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/ReplayInputDispatchMethods.cpp         (rev 0)
+++ trunk/Source/WebCore/replay/ReplayInputDispatchMethods.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+/*
+ * Copyright (C) 2011-2013 University of Washington.
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_REPLAY)
+
+#include "AllReplayInputs.h"
+#include "MainFrame.h"
+#include "NavigationScheduler.h"
+#include "Page.h"
+#include "ReplayController.h"
+#include "URL.h"
+
+namespace WebCore {
+
+// Sentinel inputs.
+void BeginSegmentSentinel::dispatch(ReplayController&)
+{
+}
+
+void EndSegmentSentinel::dispatch(ReplayController&)
+{
+}
+
+// Navigation inputs.
+void InitialNavigation::dispatch(ReplayController& controller)
+{
+ controller.page().mainFrame().navigationScheduler().scheduleLocationChange(m_securityOrigin.get(), m_url, m_referrer, true, true);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayReplayInputTypescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/replay/ReplayInputTypes.cpp (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/ReplayInputTypes.cpp        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/replay/ReplayInputTypes.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> ReplayInputTypes::ReplayInputTypes()
</span><span class="cx"> : dummy(0)
</span><span class="cx"> JS_REPLAY_INPUT_NAMES_FOR_EACH(INITIALIZE_INPUT_TYPE)
</span><ins>+WEB_REPLAY_INPUT_NAMES_FOR_EACH(INITIALIZE_INPUT_TYPE)
</ins><span class="cx"> {
</span><span class="cx"> UNUSED_PARAM(dummy);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorereplayReplayInputTypesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/replay/ReplayInputTypes.h (164985 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/ReplayInputTypes.h        2014-03-03 13:47:13 UTC (rev 164985)
+++ trunk/Source/WebCore/replay/ReplayInputTypes.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #if ENABLE(WEB_REPLAY)
</span><span class="cx">
</span><span class="cx"> #include "ThreadGlobalData.h"
</span><ins>+#include "WebReplayInputs.h"
</ins><span class="cx"> #include <JavaScriptCore/JSReplayInputs.h>
</span><span class="cx"> #include <wtf/text/AtomicString.h>
</span><span class="cx">
</span><span class="lines">@@ -44,6 +45,7 @@
</span><span class="cx">
</span><span class="cx"> #define DECLARE_REPLAY_INPUT_TYPES(name) AtomicString name;
</span><span class="cx"> JS_REPLAY_INPUT_NAMES_FOR_EACH(DECLARE_REPLAY_INPUT_TYPES)
</span><ins>+ WEB_REPLAY_INPUT_NAMES_FOR_EACH(DECLARE_REPLAY_INPUT_TYPES)
</ins><span class="cx"> #undef DECLARE_REPLAY_INPUT_TYPES
</span><span class="cx"> };
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorereplayReplaySessioncppfromrev164983trunkSourceWebCorereplayReplayInputTypescpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/replay/ReplaySession.cpp (from rev 164983, trunk/Source/WebCore/replay/ReplayInputTypes.cpp) (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/ReplaySession.cpp         (rev 0)
+++ trunk/Source/WebCore/replay/ReplaySession.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,89 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#include "config.h"
+#include "ReplaySession.h"
+
+#if ENABLE(WEB_REPLAY)
+
+#include "ReplaySessionSegment.h"
+#include <wtf/CurrentTime.h>
+
+namespace WebCore {
+
+static unsigned s_nextIdentifier = 1;
+
+PassRefPtr<ReplaySession> ReplaySession::create()
+{
+ return adoptRef(new ReplaySession());
+}
+
+ReplaySession::ReplaySession()
+ : m_identifier(s_nextIdentifier++)
+ , m_timestamp(currentTimeMS())
+{
+}
+
+ReplaySession::~ReplaySession()
+{
+}
+
+PassRefPtr<ReplaySessionSegment> ReplaySession::at(size_t position) const
+{
+ return m_segments.at(position);
+}
+
+void ReplaySession::appendSegment(PassRefPtr<ReplaySessionSegment> prpSegment)
+{
+ RefPtr<ReplaySessionSegment> segment = prpSegment;
+
+ // For now, only support one segment.
+ ASSERT(!m_segments.size());
+
+ // Since replay locations are specified with segment IDs, we can only
+ // have one instance of a segment in the session.
+ size_t offset = m_segments.find(segment);
+ ASSERT_UNUSED(offset, offset == notFound);
+
+ m_segments.append(segment.release());
+}
+
+void ReplaySession::insertSegment(size_t position, PassRefPtr<ReplaySessionSegment> segment)
+{
+ ASSERT(position < m_segments.size());
+ m_segments.insert(position, segment);
+}
+
+void ReplaySession::removeSegment(size_t position)
+{
+ ASSERT(position < m_segments.size());
+ m_segments.remove(position);
+}
+
+}; // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayReplaySessionhfromrev164983trunkSourceWebCorereplayReplayInputTypesh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/replay/ReplaySession.h (from rev 164983, trunk/Source/WebCore/replay/ReplayInputTypes.h) (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/ReplaySession.h         (rev 0)
+++ trunk/Source/WebCore/replay/ReplaySession.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#ifndef ReplaySession_h
+#define ReplaySession_h
+
+#if ENABLE(WEB_REPLAY)
+
+#include <wtf/Noncopyable.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class ReplaySessionSegment;
+
+typedef Vector<RefPtr<ReplaySessionSegment>>::const_iterator SegmentIterator;
+
+class ReplaySession : public RefCounted<ReplaySession> {
+ WTF_MAKE_NONCOPYABLE(ReplaySession);
+public:
+ static PassRefPtr<ReplaySession> create();
+ ~ReplaySession();
+
+ double timestamp() const { return m_timestamp; }
+ unsigned identifier() const { return m_identifier; }
+
+ size_t size() const { return m_segments.size(); }
+ PassRefPtr<ReplaySessionSegment> at(size_t position) const;
+
+ SegmentIterator begin() const { return m_segments.begin(); }
+ SegmentIterator end() const { return m_segments.end(); }
+
+ void appendSegment(PassRefPtr<ReplaySessionSegment>);
+ void insertSegment(size_t position, PassRefPtr<ReplaySessionSegment>);
+ void removeSegment(size_t position);
+
+private:
+ ReplaySession();
+
+ Vector<RefPtr<ReplaySessionSegment>> m_segments;
+ unsigned m_identifier;
+ double m_timestamp;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
+
+#endif // ReplaySession_h
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayReplaySessionSegmentcppfromrev164983trunkSourceWebCorereplayReplayInputTypescpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/replay/ReplaySessionSegment.cpp (from rev 164983, trunk/Source/WebCore/replay/ReplayInputTypes.cpp) (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/ReplaySessionSegment.cpp         (rev 0)
+++ trunk/Source/WebCore/replay/ReplaySessionSegment.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,79 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#include "config.h"
+#include "ReplaySessionSegment.h"
+
+#if ENABLE(WEB_REPLAY)
+
+#include "CapturingInputCursor.h"
+#include "FunctorInputCursor.h"
+#include "ReplayingInputCursor.h"
+#include "SegmentedInputStorage.h"
+#include <wtf/CurrentTime.h>
+
+namespace WebCore {
+
+static unsigned s_nextSegmentIdentifier = 1;
+
+PassRefPtr<ReplaySessionSegment> ReplaySessionSegment::create()
+{
+ return adoptRef(new ReplaySessionSegment);
+}
+
+ReplaySessionSegment::ReplaySessionSegment()
+ : m_storage(std::make_unique<SegmentedInputStorage>())
+ , m_identifier(s_nextSegmentIdentifier++)
+ , m_canCapture(true)
+ , m_timestamp(currentTimeMS())
+{
+}
+
+ReplaySessionSegment::~ReplaySessionSegment()
+{
+}
+
+PassRefPtr<CapturingInputCursor> ReplaySessionSegment::createCapturingCursor(Page&)
+{
+ ASSERT(m_canCapture);
+ m_canCapture = false;
+ return CapturingInputCursor::create(*m_storage);
+}
+
+PassRefPtr<ReplayingInputCursor> ReplaySessionSegment::createReplayingCursor(Page& page, EventLoopInputDispatcherClient* client)
+{
+ return ReplayingInputCursor::create(*m_storage, page, client);
+}
+
+std::unique_ptr<FunctorInputCursor> ReplaySessionSegment::createFunctorCursor()
+{
+ return std::make_unique<FunctorInputCursor>(*m_storage);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayReplaySessionSegmenthfromrev164983trunkSourceWebCorereplayReplayInputTypesh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/replay/ReplaySessionSegment.h (from rev 164983, trunk/Source/WebCore/replay/ReplayInputTypes.h) (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/ReplaySessionSegment.h         (rev 0)
+++ trunk/Source/WebCore/replay/ReplaySessionSegment.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#ifndef ReplaySessionSegment_h
+#define ReplaySessionSegment_h
+
+#if ENABLE(WEB_REPLAY)
+
+#include <replay/NondeterministicInput.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class CapturingInputCursor;
+class EventLoopInputDispatcherClient;
+class FunctorInputCursor;
+class Page;
+class ReplayingInputCursor;
+class SegmentedInputStorage;
+
+class ReplaySessionSegment : public RefCounted<ReplaySessionSegment> {
+public:
+ static PassRefPtr<ReplaySessionSegment> create();
+ ~ReplaySessionSegment();
+
+ unsigned identifier() const { return m_identifier; }
+ double timestamp() const { return m_timestamp; }
+
+ PassRefPtr<CapturingInputCursor> createCapturingCursor(Page&);
+ PassRefPtr<ReplayingInputCursor> createReplayingCursor(Page&, EventLoopInputDispatcherClient*);
+ std::unique_ptr<FunctorInputCursor> createFunctorCursor();
+private:
+ ReplaySessionSegment();
+
+ std::unique_ptr<SegmentedInputStorage> m_storage;
+ unsigned m_identifier;
+ bool m_canCapture;
+ double m_timestamp;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
+
+#endif // ReplaySessionSegment_h
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayReplayingInputCursorcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/replay/ReplayingInputCursor.cpp (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/ReplayingInputCursor.cpp         (rev 0)
+++ trunk/Source/WebCore/replay/ReplayingInputCursor.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,89 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#include "config.h"
+#include "ReplayingInputCursor.h"
+
+#if ENABLE(WEB_REPLAY)
+
+#include "EventLoopInputDispatcher.h"
+#include "SegmentedInputStorage.h"
+#include "SerializationMethods.h"
+#include "WebReplayInputs.h"
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+ReplayingInputCursor::ReplayingInputCursor(SegmentedInputStorage& storage, Page& page, EventLoopInputDispatcherClient* client)
+ : m_storage(storage)
+ , m_dispatcher(std::make_unique<EventLoopInputDispatcher>(page, *this, client))
+{
+ for (size_t i = 0; i < static_cast<size_t>(InputQueue::Count); i++)
+ m_positions.append(0);
+}
+
+ReplayingInputCursor::~ReplayingInputCursor()
+{
+}
+
+PassRefPtr<ReplayingInputCursor> ReplayingInputCursor::create(SegmentedInputStorage& storage, Page& page, EventLoopInputDispatcherClient* client)
+{
+ return adoptRef(new ReplayingInputCursor(storage, page, client));
+}
+
+void ReplayingInputCursor::storeInput(std::unique_ptr<NondeterministicInputBase>)
+{
+ // Cannot store inputs from a replaying input cursor.
+ ASSERT_NOT_REACHED();
+}
+
+NondeterministicInputBase* ReplayingInputCursor::loadInput(InputQueue queue, const AtomicString& type)
+{
+ NondeterministicInputBase* input = uncheckedLoadInput(queue);
+
+ if (input->type() != type) {
+ LOG_ERROR("%-25s ERROR: Expected replay input of type %s, but got type %s\n", "[ReplayingInputCursor]", type.string().ascii().data(), input->type().string().ascii().data());
+ return nullptr;
+ }
+
+ return input;
+}
+
+NondeterministicInputBase* ReplayingInputCursor::uncheckedLoadInput(InputQueue queue)
+{
+ if (m_positions[static_cast<size_t>(queue)] >= m_storage.queueSize(queue)) {
+ String queueString = EncodingTraits<InputQueue>::encodeValue(queue).convertTo<String>();
+ LOG_ERROR("%-30s ERROR No more inputs remain for determinism queue %s, but one was requested.", "[ReplayingInputCursor]", queueString.ascii().data());
+ return nullptr;
+ }
+
+ return m_storage.load(queue, m_positions[static_cast<size_t>(queue)]++);
+}
+
+}; // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayReplayingInputCursorhfromrev164983trunkSourceWebCorereplayReplayInputTypesh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/replay/ReplayingInputCursor.h (from rev 164983, trunk/Source/WebCore/replay/ReplayInputTypes.h) (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/ReplayingInputCursor.h         (rev 0)
+++ trunk/Source/WebCore/replay/ReplayingInputCursor.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#ifndef ReplayingInputCursor_h
+#define ReplayingInputCursor_h
+
+#if ENABLE(WEB_REPLAY)
+
+#include <replay/InputCursor.h>
+#include <wtf/Vector.h>
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+class EventLoopInputDispatcher;
+class EventLoopInputDispatcherClient;
+class Page;
+class SegmentedInputStorage;
+
+class ReplayingInputCursor final : public InputCursor {
+ WTF_MAKE_NONCOPYABLE(ReplayingInputCursor);
+public:
+ static PassRefPtr<ReplayingInputCursor> create(SegmentedInputStorage&, Page&, EventLoopInputDispatcherClient*);
+ virtual ~ReplayingInputCursor();
+
+ virtual bool isCapturing() const override { return false; }
+ virtual bool isReplaying() const override { return true; }
+
+ EventLoopInputDispatcher& dispatcher() const { return *m_dispatcher; }
+
+ virtual void storeInput(std::unique_ptr<NondeterministicInputBase>) override;
+ virtual NondeterministicInputBase* uncheckedLoadInput(InputQueue) override;
+protected:
+ virtual NondeterministicInputBase* loadInput(InputQueue, const AtomicString& type) override;
+private:
+ ReplayingInputCursor(SegmentedInputStorage&, Page&, EventLoopInputDispatcherClient*);
+
+ SegmentedInputStorage& m_storage;
+ std::unique_ptr<EventLoopInputDispatcher> m_dispatcher;
+ Vector<size_t> m_positions;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
+
+#endif // ReplayingInputCursor_h
</ins></span></pre></div>
<a id="trunkSourceWebCorereplaySegmentedInputStoragecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/replay/SegmentedInputStorage.cpp (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/SegmentedInputStorage.cpp         (rev 0)
+++ trunk/Source/WebCore/replay/SegmentedInputStorage.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,124 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#include "config.h"
+#include "SegmentedInputStorage.h"
+
+#if ENABLE(WEB_REPLAY)
+
+#if !LOG_DISABLED
+#include "Logging.h"
+#include "SerializationMethods.h"
+#include <replay/EncodedValue.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+#endif
+
+namespace WebCore {
+
+#if !LOG_DISABLED
+// These are used to make the log spew from LOG(WebReplay, ...) more readable.
+static const char* queueTypeToLogPrefix(InputQueue inputQueue, bool isLoad)
+{
+ if (isLoad) {
+ switch (inputQueue) {
+ case InputQueue::EventLoopInput: return "(DSPTCH-LOAD)";
+ case InputQueue::LoaderMemoizedData: return "<LDMEMO-LOAD";
+ case InputQueue::ScriptMemoizedData: return "<---<---<---JSMEMO-LOAD";
+ case InputQueue::Count: return "ERROR!";
+ }
+ } else {
+ switch (inputQueue) {
+ case InputQueue::EventLoopInput: return ">DSPTCH-STORE";
+ case InputQueue::LoaderMemoizedData: return "<LDMEMO-STORE";
+ case InputQueue::ScriptMemoizedData: return "<---<---<---JSMEMO-STORE";
+ case InputQueue::Count: return "ERROR!";
+ }
+ }
+}
+
+static String jsonStringForInput(const NondeterministicInputBase& input)
+{
+ EncodedValue encodedValue = EncodingTraits<NondeterministicInputBase>::encodeValue(input);
+ return encodedValue.asObject()->toJSONString();
+}
+#endif // !LOG_DISABLED
+
+static size_t offsetForInputQueue(InputQueue inputQueue)
+{
+ return static_cast<size_t>(inputQueue);
+}
+
+SegmentedInputStorage::SegmentedInputStorage()
+ : m_inputCount(0)
+{
+ for (size_t i = 0; i < offsetForInputQueue(InputQueue::Count); i++)
+ m_queues.append(new QueuedInputs);
+}
+
+SegmentedInputStorage::~SegmentedInputStorage()
+{
+ for (size_t i = 0; i < offsetForInputQueue(InputQueue::Count); i++)
+ delete m_queues.at(i);
+}
+
+NondeterministicInputBase* SegmentedInputStorage::load(InputQueue inputQueue, size_t offset)
+{
+ ASSERT(offset < queueSize(inputQueue));
+
+ NondeterministicInputBase* input = queue(inputQueue).at(offset).get();
+ ASSERT(input);
+
+ LOG(WebReplay, "%-20s %s: %s %s\n", "ReplayEvents", queueTypeToLogPrefix(inputQueue, true), input->type().string().utf8().data(), jsonStringForInput(*input).utf8().data());
+
+ return input;
+}
+
+void SegmentedInputStorage::store(std::unique_ptr<NondeterministicInputBase> input)
+{
+ ASSERT(input);
+ ASSERT(input->queue() < InputQueue::Count);
+
+ LOG(WebReplay, "%-14s#%-5u %s: %s %s\n", "ReplayEvents", m_inputCount++, queueTypeToLogPrefix(input->queue(), false), input->type().string().utf8().data(), jsonStringForInput(*input).utf8().data());
+
+ m_queues.at(offsetForInputQueue(input->queue()))->append(std::move(input));
+}
+
+size_t SegmentedInputStorage::queueSize(InputQueue inputQueue) const
+{
+ return queue(inputQueue).size();
+}
+
+const SegmentedInputStorage::QueuedInputs& SegmentedInputStorage::queue(InputQueue queue) const
+{
+ ASSERT(queue < InputQueue::Count);
+ return *m_queues.at(offsetForInputQueue(queue));
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
</ins></span></pre></div>
<a id="trunkSourceWebCorereplaySegmentedInputStoragehfromrev164983trunkSourceWebCorereplayReplayInputTypesh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/replay/SegmentedInputStorage.h (from rev 164983, trunk/Source/WebCore/replay/ReplayInputTypes.h) (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/SegmentedInputStorage.h         (rev 0)
+++ trunk/Source/WebCore/replay/SegmentedInputStorage.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,62 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#ifndef SegmentedInputStorage_h
+#define SegmentedInputStorage_h
+
+#if ENABLE(WEB_REPLAY)
+
+#include <replay/NondeterministicInput.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class SegmentedInputStorage {
+ WTF_MAKE_NONCOPYABLE(SegmentedInputStorage);
+ friend class FunctorInputCursor;
+public:
+ SegmentedInputStorage();
+ ~SegmentedInputStorage();
+
+ NondeterministicInputBase* load(InputQueue, size_t);
+ void store(std::unique_ptr<NondeterministicInputBase>);
+ size_t queueSize(InputQueue) const;
+
+private:
+ typedef Vector<std::unique_ptr<NondeterministicInputBase>> QueuedInputs;
+ const QueuedInputs& queue(InputQueue) const;
+
+ Vector<QueuedInputs*, 3> m_queues;
+ unsigned m_inputCount;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_REPLAY)
+
+#endif // SegmentedInputStorage_h
</ins></span></pre></div>
<a id="trunkSourceWebCorereplaySerializationMethodscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/replay/SerializationMethods.cpp (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/SerializationMethods.cpp         (rev 0)
+++ trunk/Source/WebCore/replay/SerializationMethods.cpp        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,117 @@
</span><ins>+/*
+ * Copyright (C) 2012 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#include "config.h"
+#include "SerializationMethods.h"
+
+#if ENABLE(WEB_REPLAY)
+
+#include "AllReplayInputs.h"
+#include "ReplayInputTypes.h"
+#include "SecurityOrigin.h"
+#include "URL.h"
+
+using WebCore::SecurityOrigin;
+using WebCore::URL;
+using WebCore::inputTypes;
+
+#define IMPORT_FROM_WEBCORE_NAMESPACE(name) \
+using WebCore::name; \
+
+WEB_REPLAY_INPUT_NAMES_FOR_EACH(IMPORT_FROM_WEBCORE_NAMESPACE)
+#undef IMPORT_FROM_WEBCORE_NAMESPACE
+
+namespace JSC {
+
+EncodedValue EncodingTraits<NondeterministicInputBase>::encodeValue(const NondeterministicInputBase& input)
+{
+ EncodedValue encodedValue = EncodedValue::createObject();
+ const AtomicString& type = input.type();
+ encodedValue.put<String>(ASCIILiteral("type"), type.string());
+
+#define ENCODE_IF_TYPE_TAG_MATCHES(name) \
+ if (type == inputTypes().name) { \
+ InputTraits<name>::encode(encodedValue, static_cast<const name&>(input)); \
+ return encodedValue; \
+ } \
+
+ JS_REPLAY_INPUT_NAMES_FOR_EACH(ENCODE_IF_TYPE_TAG_MATCHES)
+ WEB_REPLAY_INPUT_NAMES_FOR_EACH(ENCODE_IF_TYPE_TAG_MATCHES)
+#undef ENCODE_IF_TYPE_TAG_MATCHES
+
+ ASSERT_NOT_REACHED();
+ return EncodedValue();
+}
+
+bool EncodingTraits<NondeterministicInputBase>::decodeValue(EncodedValue& encodedValue, std::unique_ptr<NondeterministicInputBase>& input)
+{
+ String type;
+ if (!encodedValue.get<String>(ASCIILiteral("type"), type))
+ return false;
+
+#define DECODE_IF_TYPE_TAG_MATCHES(name) \
+ if (type == inputTypes().name) { \
+ std::unique_ptr<name> decodedInput; \
+ if (!InputTraits<name>::decode(encodedValue, decodedInput)) \
+ return false; \
+ \
+ input = std::move(decodedInput); \
+ return true; \
+ } \
+
+ JS_REPLAY_INPUT_NAMES_FOR_EACH(DECODE_IF_TYPE_TAG_MATCHES)
+ WEB_REPLAY_INPUT_NAMES_FOR_EACH(DECODE_IF_TYPE_TAG_MATCHES)
+#undef DECODE_IF_TYPE_TAG_MATCHES
+
+ return false;
+}
+
+EncodedValue EncodingTraits<SecurityOrigin>::encodeValue(RefPtr<SecurityOrigin> input)
+{
+ return EncodedValue::createString(input->toString());
+}
+
+bool EncodingTraits<SecurityOrigin>::decodeValue(EncodedValue& encodedValue, RefPtr<SecurityOrigin>& input)
+{
+ input = SecurityOrigin::createFromString(encodedValue.convertTo<String>());
+ return true;
+}
+
+EncodedValue EncodingTraits<URL>::encodeValue(const URL& input)
+{
+ return EncodedValue::createString(input.string());
+}
+
+bool EncodingTraits<URL>::decodeValue(EncodedValue& encodedValue, URL& input)
+{
+ input = URL(WebCore::ParsedURLString, encodedValue.convertTo<String>());
+ return true;
+}
+
+} // namespace JSC
+
+#endif // ENABLE(WEB_REPLAY)
</ins></span></pre></div>
<a id="trunkSourceWebCorereplaySerializationMethodshfromrev164983trunkSourceWebCorereplayReplayInputTypesh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/replay/SerializationMethods.h (from rev 164983, trunk/Source/WebCore/replay/ReplayInputTypes.h) (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/SerializationMethods.h         (rev 0)
+++ trunk/Source/WebCore/replay/SerializationMethods.h        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,72 @@
</span><ins>+/*
+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+#ifndef SerializationMethods_h
+#define SerializationMethods_h
+
+#if ENABLE(WEB_REPLAY)
+
+#include <replay/EncodedValue.h>
+#include <replay/NondeterministicInput.h>
+
+namespace WebCore {
+class Document;
+class Frame;
+class Page;
+class SecurityOrigin;
+class URL;
+} // namespace WebCore
+
+// Template specializations must be defined in the same namespace as the template declaration.
+namespace JSC {
+
+template<> struct EncodingTraits<NondeterministicInputBase> {
+ typedef NondeterministicInputBase DecodedType;
+
+ static EncodedValue encodeValue(const NondeterministicInputBase& value);
+ static bool decodeValue(EncodedValue&, std::unique_ptr<NondeterministicInputBase>& value);
+};
+
+template<> struct EncodingTraits<WebCore::URL> {
+ typedef WebCore::URL DecodedType;
+
+ static EncodedValue encodeValue(const WebCore::URL& value);
+ static bool decodeValue(EncodedValue&, WebCore::URL& value);
+};
+
+template<> struct EncodingTraits<WebCore::SecurityOrigin> {
+ typedef RefPtr<WebCore::SecurityOrigin> DecodedType;
+
+ static EncodedValue encodeValue(RefPtr<WebCore::SecurityOrigin> value);
+ static bool decodeValue(EncodedValue&, RefPtr<WebCore::SecurityOrigin>& value);
+};
+
+} // namespace JSC
+
+#endif // ENABLE(WEB_REPLAY)
+
+#endif // SerializationMethods_h
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayWebInputsjson"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/replay/WebInputs.json (0 => 164986)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/WebInputs.json         (rev 0)
+++ trunk/Source/WebCore/replay/WebInputs.json        2014-03-03 17:01:11 UTC (rev 164986)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+{
+ "types": {
+ "Global": [
+ { "name": "bool", "mode": "SCALAR" },
+ { "name": "double", "mode": "SCALAR" },
+ { "name": "int", "mode": "SCALAR" },
+ { "name": "unsigned", "mode": "SCALAR" },
+ { "name": "unsigned long", "mode": "SCALAR" },
+ { "name": "unsigned long long", "mode": "SCALAR" }
+ ],
+
+ "WTF": [
+ {
+ "name": "String", "mode": "HEAVY_SCALAR",
+ "header": "wtf/text/WTFString.h"
+ }
+ ],
+
+ "JavaScriptCore": [
+ {
+ "name": "InputQueue", "mode": "SCALAR", "storage": "uint8_t",
+ "flags": ["ENUM_CLASS"],
+ "values": ["EventLoopInput", "LoaderMemoizedData", "ScriptMemoizedData", "Count"],
+ "header": "replay/NondeterministicInput.h"
+ }
+ ],
+
+ "WebCore": [
+ {
+ "name": "URL", "mode": "HEAVY_SCALAR",
+ "header": "platform/URL.h"
+ },
+ {
+ "name": "SecurityOrigin", "mode": "SHARED",
+ "header": "page/SecurityOrigin.h"
+ },
+ {
+ "name": "Page", "mode": "OWNED",
+ "header": "page/Page.h"
+ }
+ ]
+ },
+
+ "inputs": [
+ {
+ "name": "BeginSegmentSentinel",
+ "description": "A sentinel input to signal the start of a segment.",
+ "queue": "EVENT_LOOP",
+ "members": [ ]
+ },
+ {
+ "name": "EndSegmentSentinel",
+ "description": "A sentinel input to signal the end of a segment.",
+ "queue": "EVENT_LOOP",
+ "members": [ ]
+ },
+ {
+ "name": "InitialNavigation",
+ "description": "Initiate the initial main frame navigation.",
+ "queue": "EVENT_LOOP",
+ "flags": ["HIDDEN", "CREATE_FROM_PAGE"],
+ "members": [
+ { "name": "securityOrigin", "type": "SecurityOrigin" },
+ { "name": "url", "type": "URL" },
+ { "name": "referrer", "type": "String" }
+ ]
+ }
+ ]
+}
</ins></span></pre>
</div>
</div>
</body>
</html>