<!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>[164745] 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/164745">164745</a></dd>
<dt>Author</dt> <dd>bburg@apple.com</dd>
<dt>Date</dt> <dd>2014-02-26 13:41:30 -0800 (Wed, 26 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Replay: route through UserInputBridge when delivering user inputs to WebCore
https://bugs.webkit.org/show_bug.cgi?id=128150

Reviewed by Timothy Hatcher.

Source/WebCore:

Add an UserInputBridge instance to each Page. WebKit2 routes a page's user inputs through
the WebCore page's user input bridge so that the inputs can be selectively captured, filtered,
and replayed using instrumentation inside the UserInputBridge.

For now, the routing methods of UserInputBridge have no replay-specific code paths, and just
put the input delivery code inside WebCore rather than its external clients. Replay-specific
code paths will be added once https://bugs.webkit.org/show_bug.cgi?id=128782 is fixed. However,
once complete the code will work as follows:

- When neither capturing or replaying, behavior is unchanged.

- When capturing user inputs, each external input is saved into a replay log as it crosses
the bridge from outside WebCore.

- When replaying, the bridge closes and user inputs from WebKit2 are not accepted. Instead,
the saved inputs from the replay log are re-dispatched as if they had crossed the bridge.

* CMakeLists.txt:
* GNUmakefile.am:
* GNUmakefile.list.am:
* WebCore.exp.in: Add symbols for input routing methods.
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:
* page/Page.cpp:
(WebCore::Page::Page): Initialize the owned UserInputBridge in the Page constructor.
* page/Page.h:
(WebCore::Page::inputBridge): Added a by-reference getter.
* replay/UserInputBridge.cpp: Added.
(WebCore::UserInputBridge::UserInputBridge):
(WebCore::UserInputBridge::~UserInputBridge):
(WebCore::UserInputBridge::handleContextMenuEvent):
(WebCore::UserInputBridge::handleMousePressEvent):
(WebCore::UserInputBridge::handleMouseReleaseEvent):
(WebCore::UserInputBridge::handleMouseMoveEvent):
(WebCore::UserInputBridge::handleMouseMoveOnScrollbarEvent):
(WebCore::UserInputBridge::handleKeyEvent):
(WebCore::UserInputBridge::handleAccessKeyEvent):
(WebCore::UserInputBridge::handleWheelEvent):
(WebCore::UserInputBridge::focusSetActive):
(WebCore::UserInputBridge::focusSetFocused):
(WebCore::UserInputBridge::scrollRecursively):
(WebCore::UserInputBridge::logicalScrollRecursively):
(WebCore::UserInputBridge::loadRequest):
(WebCore::UserInputBridge::reloadFrame):
(WebCore::UserInputBridge::stopLoadingFrame):
(WebCore::UserInputBridge::tryClosePage):
* replay/UserInputBridge.h: Added.

Source/WebKit2:

When delivering user inputs to WebCore, route calls through the page's UserInputBridge.
This allows us to capture and replay user inputs from WebKit2 solely within WebCore.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::tryClose):
(WebKit::WebPage::loadRequest):
(WebKit::WebPage::stopLoadingFrame):
(WebKit::WebPage::stopLoading):
(WebKit::WebPage::reload):
(WebKit::WebPage::contextMenuAtPointInWindow):
(WebKit::handleContextMenuEvent):
(WebKit::handleMouseEvent):
(WebKit::handleWheelEvent):
(WebKit::handleKeyEvent):
(WebKit::WebPage::scroll):
(WebKit::WebPage::logicalScroll):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreGNUmakefileam">trunk/Source/WebCore/GNUmakefile.am</a></li>
<li><a href="#trunkSourceWebCoreGNUmakefilelistam">trunk/Source/WebCore/GNUmakefile.list.am</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCoreWebCoreorder">trunk/Source/WebCore/WebCore.order</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxproj">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</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="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagecpp">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorereplayUserInputBridgecpp">trunk/Source/WebCore/replay/UserInputBridge.cpp</a></li>
<li><a href="#trunkSourceWebCorereplayUserInputBridgeh">trunk/Source/WebCore/replay/UserInputBridge.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (164744 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2014-02-26 21:31:38 UTC (rev 164744)
+++ trunk/Source/WebCore/CMakeLists.txt        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -86,6 +86,7 @@
</span><span class="cx">     &quot;${WEBCORE_DIR}/rendering/shapes&quot;
</span><span class="cx">     &quot;${WEBCORE_DIR}/rendering/style&quot;
</span><span class="cx">     &quot;${WEBCORE_DIR}/rendering/svg&quot;
</span><ins>+    &quot;${WEBCORE_DIR}/replay&quot;
</ins><span class="cx">     &quot;${WEBCORE_DIR}/storage&quot;
</span><span class="cx">     &quot;${WEBCORE_DIR}/style&quot;
</span><span class="cx">     &quot;${WEBCORE_DIR}/svg&quot;
</span><span class="lines">@@ -2297,6 +2298,8 @@
</span><span class="cx">     rendering/svg/SVGTextQuery.cpp
</span><span class="cx">     rendering/svg/SVGTextRunRenderingContext.cpp
</span><span class="cx"> 
</span><ins>+    replay/UserInputBridge.cpp
+
</ins><span class="cx">     storage/Storage.cpp
</span><span class="cx">     storage/StorageAreaImpl.cpp
</span><span class="cx">     storage/StorageAreaSync.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (164744 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-02-26 21:31:38 UTC (rev 164744)
+++ trunk/Source/WebCore/ChangeLog        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -1,3 +1,59 @@
</span><ins>+2014-02-26  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Replay: route through UserInputBridge when delivering user inputs to WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=128150
+
+        Reviewed by Timothy Hatcher.
+
+        Add an UserInputBridge instance to each Page. WebKit2 routes a page's user inputs through
+        the WebCore page's user input bridge so that the inputs can be selectively captured, filtered,
+        and replayed using instrumentation inside the UserInputBridge.
+
+        For now, the routing methods of UserInputBridge have no replay-specific code paths, and just
+        put the input delivery code inside WebCore rather than its external clients. Replay-specific
+        code paths will be added once https://bugs.webkit.org/show_bug.cgi?id=128782 is fixed. However,
+        once complete the code will work as follows:
+
+        - When neither capturing or replaying, behavior is unchanged.
+
+        - When capturing user inputs, each external input is saved into a replay log as it crosses
+        the bridge from outside WebCore.
+
+        - When replaying, the bridge closes and user inputs from WebKit2 are not accepted. Instead,
+        the saved inputs from the replay log are re-dispatched as if they had crossed the bridge.
+
+        * CMakeLists.txt:
+        * GNUmakefile.am:
+        * GNUmakefile.list.am:
+        * WebCore.exp.in: Add symbols for input routing methods.
+        * WebCore.vcxproj/WebCore.vcxproj:
+        * WebCore.vcxproj/WebCore.vcxproj.filters:
+        * WebCore.xcodeproj/project.pbxproj:
+        * page/Page.cpp:
+        (WebCore::Page::Page): Initialize the owned UserInputBridge in the Page constructor.
+        * page/Page.h:
+        (WebCore::Page::inputBridge): Added a by-reference getter.
+        * replay/UserInputBridge.cpp: Added.
+        (WebCore::UserInputBridge::UserInputBridge):
+        (WebCore::UserInputBridge::~UserInputBridge):
+        (WebCore::UserInputBridge::handleContextMenuEvent):
+        (WebCore::UserInputBridge::handleMousePressEvent):
+        (WebCore::UserInputBridge::handleMouseReleaseEvent):
+        (WebCore::UserInputBridge::handleMouseMoveEvent):
+        (WebCore::UserInputBridge::handleMouseMoveOnScrollbarEvent):
+        (WebCore::UserInputBridge::handleKeyEvent):
+        (WebCore::UserInputBridge::handleAccessKeyEvent):
+        (WebCore::UserInputBridge::handleWheelEvent):
+        (WebCore::UserInputBridge::focusSetActive):
+        (WebCore::UserInputBridge::focusSetFocused):
+        (WebCore::UserInputBridge::scrollRecursively):
+        (WebCore::UserInputBridge::logicalScrollRecursively):
+        (WebCore::UserInputBridge::loadRequest):
+        (WebCore::UserInputBridge::reloadFrame):
+        (WebCore::UserInputBridge::stopLoadingFrame):
+        (WebCore::UserInputBridge::tryClosePage):
+        * replay/UserInputBridge.h: Added.
+
</ins><span class="cx"> 2014-02-26  Dean Jackson  &lt;dino@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [WebGL] Protect more WebGL entry points for pending contexts
</span></span></pre></div>
<a id="trunkSourceWebCoreGNUmakefileam"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/GNUmakefile.am (164744 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/GNUmakefile.am        2014-02-26 21:31:38 UTC (rev 164744)
+++ trunk/Source/WebCore/GNUmakefile.am        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -102,6 +102,7 @@
</span><span class="cx">         -I$(srcdir)/Source/WebCore/rendering/shapes \
</span><span class="cx">         -I$(srcdir)/Source/WebCore/rendering/style \
</span><span class="cx">         -I$(srcdir)/Source/WebCore/rendering/svg \
</span><ins>+        -I$(srcdir)/Source/WebCore/replay \
</ins><span class="cx">         -I$(srcdir)/Source/WebCore/storage \
</span><span class="cx">         -I$(srcdir)/Source/WebCore/style \
</span><span class="cx">         -I$(srcdir)/Source/WebCore/svg \
</span></span></pre></div>
<a id="trunkSourceWebCoreGNUmakefilelistam"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/GNUmakefile.list.am (164744 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/GNUmakefile.list.am        2014-02-26 21:31:38 UTC (rev 164744)
+++ trunk/Source/WebCore/GNUmakefile.list.am        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -4618,6 +4618,8 @@
</span><span class="cx">         Source/WebCore/rendering/style/StyleVisualData.h \
</span><span class="cx">         Source/WebCore/rendering/TableLayout.h \
</span><span class="cx">         Source/WebCore/rendering/TrailingFloatsRootInlineBox.h \
</span><ins>+        Source/WebCore/replay/UserInputBridge.cpp \
+        Source/WebCore/replay/UserInputBridge.h \
</ins><span class="cx">         Source/WebCore/storage/StorageThread.cpp \
</span><span class="cx">         Source/WebCore/storage/StorageThread.h \
</span><span class="cx">         Source/WebCore/storage/StorageArea.h \
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (164744 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2014-02-26 21:31:38 UTC (rev 164744)
+++ trunk/Source/WebCore/WebCore.exp.in        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -644,6 +644,19 @@
</span><span class="cx"> __ZN7WebCore15StringTruncator13rightTruncateERKN3WTF6StringEfRKNS_4FontENS0_24EnableRoundingHacksOrNotE
</span><span class="cx"> __ZN7WebCore15StringTruncator14centerTruncateERKN3WTF6StringEfRKNS_4FontENS0_24EnableRoundingHacksOrNotE
</span><span class="cx"> __ZN7WebCore15StringTruncator5widthERKN3WTF6StringERKNS_4FontENS0_24EnableRoundingHacksOrNotE
</span><ins>+__ZN7WebCore15UserInputBridge20handleAccessKeyEventERKNS_21PlatformKeyboardEventENS_11InputSourceE
+__ZN7WebCore15UserInputBridge14handleKeyEventERKNS_21PlatformKeyboardEventENS_11InputSourceE
+__ZN7WebCore15UserInputBridge16stopLoadingFrameEPNS_5FrameENS_11InputSourceE
+__ZN7WebCore15UserInputBridge16handleWheelEventERKNS_18PlatformWheelEventENS_11InputSourceE
+__ZN7WebCore15UserInputBridge23handleMouseReleaseEventERKNS_18PlatformMouseEventENS_11InputSourceE
+__ZN7WebCore15UserInputBridge31handleMouseMoveOnScrollbarEventERKNS_18PlatformMouseEventENS_11InputSourceE
+__ZN7WebCore15UserInputBridge21handleMousePressEventERKNS_18PlatformMouseEventENS_11InputSourceE
+__ZN7WebCore15UserInputBridge11reloadFrameEPNS_5FrameEbNS_11InputSourceE
+__ZN7WebCore15UserInputBridge20handleMouseMoveEventERKNS_18PlatformMouseEventENS_11InputSourceE
+__ZN7WebCore15UserInputBridge17scrollRecursivelyENS_15ScrollDirectionENS_17ScrollGranularityENS_11InputSourceE
+__ZN7WebCore15UserInputBridge11loadRequestERKNS_16FrameLoadRequestENS_11InputSourceE
+__ZN7WebCore15UserInputBridge22handleContextMenuEventERKNS_18PlatformMouseEventEPKNS_5FrameENS_11InputSourceE
+__ZN7WebCore15UserInputBridge12tryClosePageENS_11InputSourceE
</ins><span class="cx"> __ZN7WebCore15VisiblePositionC1ERKNS_8PositionENS_9EAffinityE
</span><span class="cx"> __ZN7WebCore15defaultLanguageEv
</span><span class="cx"> __ZN7WebCore15localizedStringEPKc
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreorder"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.order (164744 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.order        2014-02-26 21:31:38 UTC (rev 164744)
+++ trunk/Source/WebCore/WebCore.order        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -14993,6 +14993,7 @@
</span><span class="cx"> __ZN7WebCore10TreeWalker6createEN3WTF10PassRefPtrINS_4NodeEEEjNS2_INS_10NodeFilterEEEb
</span><span class="cx"> __ZN7WebCore10TreeWalkerC1EN3WTF10PassRefPtrINS_4NodeEEEjNS2_INS_10NodeFilterEEEb
</span><span class="cx"> __ZN7WebCore10TreeWalkerC2EN3WTF10PassRefPtrINS_4NodeEEEjNS2_INS_10NodeFilterEEEb
</span><ins>+__ZN7WebCore10InputProxyC1ERNS_4PageE
</ins><span class="cx"> __ZN7WebCore9TraversalC2EN3WTF10PassRefPtrINS_4NodeEEEjNS2_INS_10NodeFilterEEEb
</span><span class="cx"> __ZN7WebCore4toJSEPN3JSC9ExecStateEPNS_17JSDOMGlobalObjectEPNS_10TreeWalkerE
</span><span class="cx"> __ZN7WebCore15getDOMStructureINS_12JSTreeWalkerEEEPN3JSC9StructureEPNS2_9ExecStateEPNS_17JSDOMGlobalObjectE
</span><span class="lines">@@ -30878,4 +30879,3 @@
</span><span class="cx"> __ZN7WebCoreL12gFunctionMapE
</span><span class="cx"> __ZN7WebCoreL12gFunctionMapE
</span><span class="cx"> __ZN7WebCore6Editor26toggleOverwriteModeEnabledEv
</span><del>-
</del></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (164744 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2014-02-26 21:31:38 UTC (rev 164744)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -11906,6 +11906,7 @@
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|Win32'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">       &lt;ExcludedFromBuild Condition=&quot;'$(Configuration)|$(Platform)'=='Production|x64'&quot;&gt;true&lt;/ExcludedFromBuild&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\replay\UserInputBridge.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\workers\SharedWorkerRepository.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\xml\DOMParser.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\xml\NativeXPathNSResolver.cpp&quot; /&gt;
</span><span class="lines">@@ -19889,6 +19890,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\rendering\svg\SVGTextMetricsBuilder.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\rendering\svg\SVGTextQuery.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\rendering\svg\SVGTextRunRenderingContext.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\replay\UserInputBridge.h&quot; /&gt;   
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\xml\DOMParser.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\xml\NativeXPathNSResolver.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\xml\XMLErrors.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters (164744 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2014-02-26 21:31:38 UTC (rev 164744)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -193,6 +193,9 @@
</span><span class="cx">     &lt;Filter Include=&quot;rendering\svg&quot;&gt;
</span><span class="cx">       &lt;UniqueIdentifier&gt;{76d4960a-59c1-42de-bc37-cf4dba01b7a3}&lt;/UniqueIdentifier&gt;
</span><span class="cx">     &lt;/Filter&gt;
</span><ins>+    &lt;Filter Include=&quot;replay&quot;&gt;
+      &lt;UniqueIdentifier&gt;{1fac2980-eaa4-4245-8073-90b55475479f}&lt;/UniqueIdentifier&gt;
+    &lt;/Filter&gt;
</ins><span class="cx">     &lt;Filter Include=&quot;xml&quot;&gt;
</span><span class="cx">       &lt;UniqueIdentifier&gt;{7bf95243-bb51-49a0-8e4f-173242e5fc4e}&lt;/UniqueIdentifier&gt;
</span><span class="cx">     &lt;/Filter&gt;
</span><span class="lines">@@ -2913,6 +2916,9 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\rendering\TextPainter.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;rendering&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\replay\UserInputBridge.cpp&quot;&gt;
+      &lt;Filter&gt;replay&lt;/Filter&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\xml\DOMParser.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;xml&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -9785,6 +9791,9 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\rendering\svg\SVGTextRunRenderingContext.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;rendering\svg&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\replay\UserInputBridge.h&quot;&gt;
+      &lt;Filter&gt;replay&lt;/Filter&gt;
+    &lt;/ClInclude&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\xml\DOMParser.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;xml&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (164744 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-02-26 21:31:38 UTC (rev 164744)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -3494,6 +3494,8 @@
</span><span class="cx">                 98EB1F951313FE0500D0E1EA /* NotImplemented.h in Headers */ = {isa = PBXBuildFile; fileRef = 98EB1F941313FE0500D0E1EA /* NotImplemented.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 990A1A0418ADA48400183FD1 /* ReplayInputTypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 990A19F418ADA48400183FD1 /* ReplayInputTypes.cpp */; };
</span><span class="cx">                 990A1A0518ADA48400183FD1 /* ReplayInputTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 990A19F518ADA48400183FD1 /* ReplayInputTypes.h */; };
</span><ins>+                9920398218B95BC600B39AF9 /* UserInputBridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9920398018B95BC600B39AF9 /* UserInputBridge.cpp */; };
+                9920398318B95BC600B39AF9 /* UserInputBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 9920398118B95BC600B39AF9 /* UserInputBridge.h */; settings = {ATTRIBUTES = (Private, ); }; };
</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">@@ -10453,6 +10455,8 @@
</span><span class="cx">                 98EB1F941313FE0500D0E1EA /* NotImplemented.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotImplemented.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 990A19F418ADA48400183FD1 /* ReplayInputTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReplayInputTypes.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 990A19F518ADA48400183FD1 /* ReplayInputTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReplayInputTypes.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                9920398018B95BC600B39AF9 /* UserInputBridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserInputBridge.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                9920398118B95BC600B39AF9 /* UserInputBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserInputBridge.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 99E45A1618A063BE0026D88F /* EventLoopInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventLoopInput.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9A1142031832D134000BB8AD /* ValueToString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueToString.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9A1B6F96158869C80011A8C4 /* JSDOMStringListCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMStringListCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -17846,6 +17850,8 @@
</span><span class="cx">                                 99E45A1618A063BE0026D88F /* EventLoopInput.h */,
</span><span class="cx">                                 990A19F418ADA48400183FD1 /* ReplayInputTypes.cpp */,
</span><span class="cx">                                 990A19F518ADA48400183FD1 /* ReplayInputTypes.h */,
</span><ins>+                                9920398018B95BC600B39AF9 /* UserInputBridge.cpp */,
+                                9920398118B95BC600B39AF9 /* UserInputBridge.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = replay;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -23706,6 +23712,7 @@
</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><ins>+                                9920398318B95BC600B39AF9 /* UserInputBridge.h in Headers */,
</ins><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">@@ -28251,6 +28258,7 @@
</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><ins>+                                9920398218B95BC600B39AF9 /* UserInputBridge.cpp in Sources */,
</ins><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></pre></div>
<a id="trunkSourceWebCorepagePagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Page.cpp (164744 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Page.cpp        2014-02-26 21:31:38 UTC (rev 164744)
+++ trunk/Source/WebCore/page/Page.cpp        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -83,6 +83,7 @@
</span><span class="cx"> #include &quot;SubframeLoader.h&quot;
</span><span class="cx"> #include &quot;TextResourceDecoder.h&quot;
</span><span class="cx"> #include &quot;UserContentController.h&quot;
</span><ins>+#include &quot;UserInputBridge.h&quot;
</ins><span class="cx"> #include &quot;VisitedLinkState.h&quot;
</span><span class="cx"> #include &quot;VisitedLinkStore.h&quot;
</span><span class="cx"> #include &quot;VoidCallback.h&quot;
</span><span class="lines">@@ -127,6 +128,7 @@
</span><span class="cx"> #if ENABLE(CONTEXT_MENUS)
</span><span class="cx">     , m_contextMenuController(std::make_unique&lt;ContextMenuController&gt;(*this, *pageClients.contextMenuClient))
</span><span class="cx"> #endif
</span><ins>+    , m_userInputBridge(std::make_unique&lt;UserInputBridge&gt;(*this))
</ins><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx">     , m_inspectorController(std::make_unique&lt;InspectorController&gt;(*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 (164744 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Page.h        2014-02-26 21:31:38 UTC (rev 164744)
+++ trunk/Source/WebCore/page/Page.h        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -80,6 +80,7 @@
</span><span class="cx"> class FrameSelection;
</span><span class="cx"> class HaltablePlugin;
</span><span class="cx"> class HistoryItem;
</span><ins>+class UserInputBridge;
</ins><span class="cx"> class InspectorClient;
</span><span class="cx"> class InspectorController;
</span><span class="cx"> class MainFrame;
</span><span class="lines">@@ -198,6 +199,7 @@
</span><span class="cx"> #if ENABLE(CONTEXT_MENUS)
</span><span class="cx">     ContextMenuController&amp; contextMenuController() const { return *m_contextMenuController; }
</span><span class="cx"> #endif
</span><ins>+    UserInputBridge&amp; userInputBridge() const { return *m_userInputBridge; }
</ins><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx">     InspectorController&amp; inspectorController() const { return *m_inspectorController; }
</span><span class="cx"> #endif
</span><span class="lines">@@ -447,6 +449,7 @@
</span><span class="cx"> #if ENABLE(CONTEXT_MENUS)
</span><span class="cx">     const std::unique_ptr&lt;ContextMenuController&gt; m_contextMenuController;
</span><span class="cx"> #endif
</span><ins>+    const std::unique_ptr&lt;UserInputBridge&gt; m_userInputBridge;
</ins><span class="cx"> #if ENABLE(INSPECTOR)
</span><span class="cx">     const std::unique_ptr&lt;InspectorController&gt; m_inspectorController;
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorereplayUserInputBridgecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/replay/UserInputBridge.cpp (0 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/UserInputBridge.cpp                                (rev 0)
+++ trunk/Source/WebCore/replay/UserInputBridge.cpp        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -0,0 +1,128 @@
</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 &quot;AS
+ * IS&quot; 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 &quot;config.h&quot;
+#include &quot;UserInputBridge.h&quot;
+
+#include &quot;EventHandler.h&quot;
+#include &quot;FocusController.h&quot;
+#include &quot;Frame.h&quot;
+#include &quot;FrameLoadRequest.h&quot;
+#include &quot;MainFrame.h&quot;
+#include &quot;Page.h&quot;
+#include &quot;PlatformKeyboardEvent.h&quot;
+#include &quot;PlatformMouseEvent.h&quot;
+#include &quot;PlatformWheelEvent.h&quot;
+
+namespace WebCore {
+
+UserInputBridge::UserInputBridge(Page&amp; page)
+    : m_page(page)
+{
+}
+
+bool UserInputBridge::handleContextMenuEvent(const PlatformMouseEvent&amp; mouseEvent, const Frame* frame, InputSource)
+{
+    return frame-&gt;eventHandler().sendContextMenuEvent(mouseEvent);
+}
+
+bool UserInputBridge::handleMousePressEvent(const PlatformMouseEvent&amp; mouseEvent, InputSource)
+{
+    return m_page.mainFrame().eventHandler().handleMousePressEvent(mouseEvent);
+}
+
+bool UserInputBridge::handleMouseReleaseEvent(const PlatformMouseEvent&amp; mouseEvent, InputSource)
+{
+    return m_page.mainFrame().eventHandler().handleMouseReleaseEvent(mouseEvent);
+}
+
+bool UserInputBridge::handleMouseMoveEvent(const PlatformMouseEvent&amp; mouseEvent, InputSource)
+{
+    return m_page.mainFrame().eventHandler().mouseMoved(mouseEvent);
+}
+
+bool UserInputBridge::handleMouseMoveOnScrollbarEvent(const PlatformMouseEvent&amp; mouseEvent, InputSource)
+{
+    return m_page.mainFrame().eventHandler().passMouseMovedEventToScrollbars(mouseEvent);
+}
+
+bool UserInputBridge::handleKeyEvent(const PlatformKeyboardEvent&amp; keyEvent, InputSource)
+{
+    return m_page.focusController().focusedOrMainFrame().eventHandler().keyEvent(keyEvent);
+}
+
+bool UserInputBridge::handleAccessKeyEvent(const PlatformKeyboardEvent&amp; keyEvent, InputSource)
+{
+    return m_page.focusController().focusedOrMainFrame().eventHandler().handleAccessKey(keyEvent);
+}
+
+bool UserInputBridge::handleWheelEvent(const PlatformWheelEvent&amp; wheelEvent, InputSource)
+{
+    return m_page.mainFrame().eventHandler().handleWheelEvent(wheelEvent);
+}
+
+void UserInputBridge::focusSetActive(bool active, InputSource)
+{
+    m_page.focusController().setActive(active);
+}
+
+void UserInputBridge::focusSetFocused(bool focused, InputSource)
+{
+    m_page.focusController().setFocused(focused);
+}
+
+bool UserInputBridge::scrollRecursively(ScrollDirection direction, ScrollGranularity granularity, InputSource)
+{
+    return m_page.focusController().focusedOrMainFrame().eventHandler().scrollRecursively(direction, granularity, nullptr);
+}
+
+bool UserInputBridge::logicalScrollRecursively(ScrollLogicalDirection direction, ScrollGranularity granularity, InputSource)
+{
+    return m_page.focusController().focusedOrMainFrame().eventHandler().logicalScrollRecursively(direction, granularity, nullptr);
+}
+
+void UserInputBridge::loadRequest(const FrameLoadRequest&amp; request, InputSource)
+{
+    m_page.mainFrame().loader().load(request);
+}
+
+void UserInputBridge::reloadFrame(Frame* frame, bool endToEndReload, InputSource)
+{
+    frame-&gt;loader().reload(endToEndReload);
+}
+
+void UserInputBridge::stopLoadingFrame(Frame* frame, InputSource)
+{
+    frame-&gt;loader().stopForUserCancel();
+}
+
+bool UserInputBridge::tryClosePage(InputSource)
+{
+    return m_page.mainFrame().loader().shouldClose();
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCorereplayUserInputBridgeh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/replay/UserInputBridge.h (0 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/UserInputBridge.h                                (rev 0)
+++ trunk/Source/WebCore/replay/UserInputBridge.h        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -0,0 +1,82 @@
</span><ins>+/*
+ * Copyright (C) 2012, 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 &quot;AS
+ * IS&quot; 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 UserInputBridge_h
+#define UserInputBridge_h
+
+#include &quot;ScrollTypes.h&quot;
+#include &lt;wtf/Noncopyable.h&gt;
+
+namespace WebCore {
+
+struct FrameLoadRequest;
+
+class Frame;
+class Page;
+class PlatformKeyboardEvent;
+class PlatformMouseEvent;
+class PlatformWheelEvent;
+
+// Real user inputs come from WebKit or WebKit2.
+// Synthetic inputs come from within WebCore (i.e., from web replay or fake mouse moves).
+enum class InputSource {
+    User,
+    Synthetic
+};
+
+class UserInputBridge {
+    WTF_MAKE_NONCOPYABLE(UserInputBridge);
+public:
+    UserInputBridge(Page&amp;);
+
+    // User input APIs.
+    bool handleContextMenuEvent(const PlatformMouseEvent&amp;, const Frame*, InputSource source = InputSource::User);
+    bool handleMousePressEvent(const PlatformMouseEvent&amp;, InputSource source = InputSource::User);
+    bool handleMouseReleaseEvent(const PlatformMouseEvent&amp;, InputSource source = InputSource::User);
+    bool handleMouseMoveEvent(const PlatformMouseEvent&amp;, InputSource source = InputSource::User);
+    bool handleMouseMoveOnScrollbarEvent(const PlatformMouseEvent&amp;, InputSource source = InputSource::User);
+    bool handleWheelEvent(const PlatformWheelEvent&amp;, InputSource source = InputSource::User);
+    bool handleKeyEvent(const PlatformKeyboardEvent&amp;, InputSource source = InputSource::User);
+    bool handleAccessKeyEvent(const PlatformKeyboardEvent&amp;, InputSource source = InputSource::User);
+    void focusSetActive(bool active, InputSource source = InputSource::User);
+    void focusSetFocused(bool focused, InputSource source = InputSource::User);
+    bool scrollRecursively(ScrollDirection, ScrollGranularity, InputSource source = InputSource::User);
+    bool logicalScrollRecursively(ScrollLogicalDirection, ScrollGranularity, InputSource source = InputSource::User);
+
+    // Navigation APIs.
+    void loadRequest(const FrameLoadRequest&amp;, InputSource source = InputSource::User);
+    void reloadFrame(Frame*, bool endToEndReload, InputSource source = InputSource::User);
+    void stopLoadingFrame(Frame*, InputSource source = InputSource::User);
+    bool tryClosePage(InputSource source = InputSource::User);
+
+private:
+    Page&amp; m_page;
+};
+
+} // namespace WebCore
+
+#endif // UserInputBridge_h
</ins></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (164744 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-02-26 21:31:38 UTC (rev 164744)
+++ trunk/Source/WebKit2/ChangeLog        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2014-02-26  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Replay: route through UserInputBridge when delivering user inputs to WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=128150
+
+        Reviewed by Timothy Hatcher.
+
+        When delivering user inputs to WebCore, route calls through the page's UserInputBridge.
+        This allows us to capture and replay user inputs from WebKit2 solely within WebCore.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::tryClose):
+        (WebKit::WebPage::loadRequest):
+        (WebKit::WebPage::stopLoadingFrame):
+        (WebKit::WebPage::stopLoading):
+        (WebKit::WebPage::reload):
+        (WebKit::WebPage::contextMenuAtPointInWindow):
+        (WebKit::handleContextMenuEvent):
+        (WebKit::handleMouseEvent):
+        (WebKit::handleWheelEvent):
+        (WebKit::handleKeyEvent):
+        (WebKit::WebPage::scroll):
+        (WebKit::WebPage::logicalScroll):
+
</ins><span class="cx"> 2014-02-26  Pratik Solanki  &lt;psolanki@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS][WebKit2] Adopt SPI for managing tabs
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (164744 => 164745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2014-02-26 21:31:38 UTC (rev 164744)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2014-02-26 21:41:30 UTC (rev 164745)
</span><span class="lines">@@ -141,6 +141,7 @@
</span><span class="cx"> #include &lt;WebCore/SubframeLoader.h&gt;
</span><span class="cx"> #include &lt;WebCore/SubstituteData.h&gt;
</span><span class="cx"> #include &lt;WebCore/TextIterator.h&gt;
</span><ins>+#include &lt;WebCore/UserInputBridge.h&gt;
</ins><span class="cx"> #include &lt;WebCore/VisiblePosition.h&gt;
</span><span class="cx"> #include &lt;WebCore/VisibleUnits.h&gt;
</span><span class="cx"> #include &lt;WebCore/markup.h&gt;
</span><span class="lines">@@ -892,7 +893,7 @@
</span><span class="cx"> {
</span><span class="cx">     SendStopResponsivenessTimer stopper(this);
</span><span class="cx"> 
</span><del>-    if (!m_mainFrame-&gt;coreFrame()-&gt;loader().shouldClose()) {
</del><ins>+    if (!corePage()-&gt;userInputBridge().tryClosePage()) {
</ins><span class="cx">         send(Messages::WebPageProxy::StopResponsivenessTimer());
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -933,7 +934,7 @@
</span><span class="cx">     m_loaderClient.willLoadURLRequest(this, request, userData.get());
</span><span class="cx"> 
</span><span class="cx">     // Initate the load in WebCore.
</span><del>-    m_mainFrame-&gt;coreFrame()-&gt;loader().load(FrameLoadRequest(m_mainFrame-&gt;coreFrame(), request));
</del><ins>+    corePage()-&gt;userInputBridge().loadRequest(FrameLoadRequest(m_mainFrame-&gt;coreFrame(), request));
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(!m_pendingNavigationID);
</span><span class="cx"> }
</span><span class="lines">@@ -1006,14 +1007,14 @@
</span><span class="cx">     if (!frame)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    frame-&gt;coreFrame()-&gt;loader().stopForUserCancel();
</del><ins>+    corePage()-&gt;userInputBridge().stopLoadingFrame(frame-&gt;coreFrame());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPage::stopLoading()
</span><span class="cx"> {
</span><span class="cx">     SendStopResponsivenessTimer stopper(this);
</span><span class="cx"> 
</span><del>-    m_mainFrame-&gt;coreFrame()-&gt;loader().stopForUserCancel();
</del><ins>+    corePage()-&gt;userInputBridge().stopLoadingFrame(m_mainFrame-&gt;coreFrame());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPage::setDefersLoading(bool defersLoading)
</span><span class="lines">@@ -1029,7 +1030,7 @@
</span><span class="cx">     m_pendingNavigationID = navigationID;
</span><span class="cx"> 
</span><span class="cx">     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
</span><del>-    m_mainFrame-&gt;coreFrame()-&gt;loader().reload(reloadFromOrigin);
</del><ins>+    corePage()-&gt;userInputBridge().reloadFrame(m_mainFrame-&gt;coreFrame(), reloadFromOrigin);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPage::goForward(uint64_t backForwardItemID)
</span><span class="lines">@@ -1583,7 +1584,7 @@
</span><span class="cx">     
</span><span class="cx">     // Simulate a mouse click to generate the correct menu.
</span><span class="cx">     PlatformMouseEvent mouseEvent(point, point, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime());
</span><del>-    bool handled = corePage()-&gt;mainFrame().eventHandler().sendContextMenuEvent(mouseEvent);
</del><ins>+    bool handled = corePage()-&gt;userInputBridge().handleContextMenuEvent(mouseEvent, &amp;corePage()-&gt;mainFrame());
</ins><span class="cx">     if (!handled)
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><span class="lines">@@ -1643,8 +1644,8 @@
</span><span class="cx">     Frame* frame = &amp;page-&gt;corePage()-&gt;mainFrame();
</span><span class="cx">     if (result.innerNonSharedNode())
</span><span class="cx">         frame = result.innerNonSharedNode()-&gt;document().frame();
</span><del>-    
-    bool handled = frame-&gt;eventHandler().sendContextMenuEvent(platformMouseEvent);
</del><ins>+
+    bool handled = page-&gt;corePage()-&gt;userInputBridge().handleContextMenuEvent(platformMouseEvent, frame);
</ins><span class="cx">     if (handled)
</span><span class="cx">         page-&gt;contextMenu()-&gt;show();
</span><span class="cx"> 
</span><span class="lines">@@ -1667,7 +1668,7 @@
</span><span class="cx">                 page-&gt;corePage()-&gt;contextMenuController().clearContextMenu();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-            bool handled = frame.eventHandler().handleMousePressEvent(platformMouseEvent);
</del><ins>+            bool handled = page-&gt;corePage()-&gt;userInputBridge().handleMousePressEvent(platformMouseEvent);
</ins><span class="cx"> #if ENABLE(CONTEXT_MENUS)
</span><span class="cx">             if (isContextClick(platformMouseEvent))
</span><span class="cx">                 handled = handleContextMenuEvent(platformMouseEvent, page);
</span><span class="lines">@@ -1675,12 +1676,12 @@
</span><span class="cx">             return handled;
</span><span class="cx">         }
</span><span class="cx">         case PlatformEvent::MouseReleased:
</span><del>-            return frame.eventHandler().handleMouseReleaseEvent(platformMouseEvent);
</del><ins>+            return page-&gt;corePage()-&gt;userInputBridge().handleMouseReleaseEvent(platformMouseEvent);
</ins><span class="cx"> 
</span><span class="cx">         case PlatformEvent::MouseMoved:
</span><span class="cx">             if (onlyUpdateScrollbars)
</span><del>-                return frame.eventHandler().passMouseMovedEventToScrollbars(platformMouseEvent);
-            return frame.eventHandler().mouseMoved(platformMouseEvent);
</del><ins>+                return page-&gt;corePage()-&gt;userInputBridge().handleMouseMoveOnScrollbarEvent(platformMouseEvent);
+            return page-&gt;corePage()-&gt;userInputBridge().handleMouseMoveEvent(platformMouseEvent);
</ins><span class="cx">         default:
</span><span class="cx">             ASSERT_NOT_REACHED();
</span><span class="cx">             return false;
</span><span class="lines">@@ -1766,7 +1767,7 @@
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
</span><del>-    return frame.eventHandler().handleWheelEvent(platformWheelEvent);
</del><ins>+    return page-&gt;userInputBridge().handleWheelEvent(platformWheelEvent);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPage::wheelEvent(const WebWheelEvent&amp; wheelEvent)
</span><span class="lines">@@ -1796,8 +1797,8 @@
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     if (keyboardEvent.type() == WebEvent::Char &amp;&amp; keyboardEvent.isSystemKey())
</span><del>-        return page-&gt;focusController().focusedOrMainFrame().eventHandler().handleAccessKey(platform(keyboardEvent));
-    return page-&gt;focusController().focusedOrMainFrame().eventHandler().keyEvent(platform(keyboardEvent));
</del><ins>+        return page-&gt;userInputBridge().handleAccessKeyEvent(platform(keyboardEvent));
+    return page-&gt;userInputBridge().handleKeyEvent(platform(keyboardEvent));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPage::keyEvent(const WebKeyboardEvent&amp; keyboardEvent)
</span><span class="lines">@@ -1936,12 +1937,12 @@
</span><span class="cx"> 
</span><span class="cx"> bool WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
</span><span class="cx"> {
</span><del>-    return page-&gt;focusController().focusedOrMainFrame().eventHandler().scrollRecursively(direction, granularity);
</del><ins>+    return page-&gt;userInputBridge().scrollRecursively(direction, granularity);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
</span><span class="cx"> {
</span><del>-    return page-&gt;focusController().focusedOrMainFrame().eventHandler().logicalScrollRecursively(direction, granularity);
</del><ins>+    return page-&gt;userInputBridge().logicalScrollRecursively(direction, granularity);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
</span></span></pre>
</div>
</div>

</body>
</html>