<!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>[167085] trunk</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/167085">167085</a></dd>
<dt>Author</dt> <dd>burg@cs.washington.edu</dd>
<dt>Date</dt> <dd>2014-04-10 13:52:31 -0700 (Thu, 10 Apr 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Web Replay: memoize plugin data for navigator.mimeTypes and navigator.plugins
https://bugs.webkit.org/show_bug.cgi?id=131341
Reviewed by Timothy Hatcher.
Source/JavaScriptCore:
Add support for encoding/decoding unsigned long with EncodedValue.
It is a distinct type from uint32_t and uint64_t.
* replay/EncodedValue.cpp:
(JSC::EncodedValue::convertTo<unsigned long>):
* replay/EncodedValue.h:
Source/WebCore:
Information about plugins and mime types is nondeterministic and can change
at any time, whether by system events, browser settings changes, or
triggered by script. To avoid interposing on all those code paths, just
memoize the plugin data used by DOMPluginArray and DOMMimeTypeArray.
This is less efficient than controlling mutations to the underlying PluginData
of a Page, but that can be done later if better plugin support is desired.
The point of this change is to make analytics trackers deterministic across
enabling/disabling of plugins.
Test: LayoutTests/inspector/window-navigator-plugins-memoized.hml
* plugins/DOMMimeTypeArray.cpp:
(WebCore::DOMMimeTypeArray::getPluginData):
* plugins/DOMPluginArray.cpp:
(WebCore::DOMPluginArray::pluginData): Save or restore memoized plugin
data during capture and replay, respectively.
* plugins/PluginData.h:
(WebCore::PluginData::PluginData): Add a constructor that uses the
provided plugin data rather than fetching live plugin data. This is
marked protected so it's only used by a subclass specifically for
deserialization.
* replay/SerializationMethods.cpp: Add encoder specializations.
(JSC::EncodingTraits<MimeClassInfo>::encodeValue):
(JSC::EncodingTraits<MimeClassInfo>::decodeValue):
(JSC::EncodingTraits<PluginInfo>::encodeValue):
(JSC::EncodingTraits<PluginInfo>::decodeValue):
(JSC::EncodingTraits<PluginData>::encodeValue):
(JSC::DeserializedPluginData::DeserializedPluginData): Add a custom
subclass of PluginData that can be initialized from deserialized data.
(JSC::EncodingTraits<PluginData>::decodeValue):
* replay/SerializationMethods.h:
* replay/WebInputs.json: Add new input FetchPluginData.
LayoutTests:
Add support for different setup methods before the initial navigation of
capture and replay. This is necessary to test that the value of
navigator.plugins is the same on replay even if the underlying data changed.
* http/tests/inspector/replay/replay-test.js:
(InspectorTestProxy.runSingleSegmentRefTest): Add calls to optional setup
functions in the test page called setupPreCapture and setupPreReplay.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestshttptestsinspectorreplayreplaytestjs">trunk/LayoutTests/http/tests/inspector/replay/replay-test.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorereplayEncodedValuecpp">trunk/Source/JavaScriptCore/replay/EncodedValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorereplayEncodedValueh">trunk/Source/JavaScriptCore/replay/EncodedValue.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorepluginsDOMMimeTypeArraycpp">trunk/Source/WebCore/plugins/DOMMimeTypeArray.cpp</a></li>
<li><a href="#trunkSourceWebCorepluginsDOMPluginArraycpp">trunk/Source/WebCore/plugins/DOMPluginArray.cpp</a></li>
<li><a href="#trunkSourceWebCorepluginsPluginDatah">trunk/Source/WebCore/plugins/PluginData.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>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsinspectorreplaywindownavigatorpluginsmemoizedexpectedtxt">trunk/LayoutTests/inspector/replay/window-navigator-plugins-memoized-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorreplaywindownavigatorpluginsmemoizedhtml">trunk/LayoutTests/inspector/replay/window-navigator-plugins-memoized.html</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (167084 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-04-10 19:26:28 UTC (rev 167084)
+++ trunk/LayoutTests/ChangeLog        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2014-04-10 Brian J. Burg <burg@cs.washington.edu>
+
+ Web Replay: memoize plugin data for navigator.mimeTypes and navigator.plugins
+ https://bugs.webkit.org/show_bug.cgi?id=131341
+
+ Reviewed by Timothy Hatcher.
+
+ Add support for different setup methods before the initial navigation of
+ capture and replay. This is necessary to test that the value of
+ navigator.plugins is the same on replay even if the underlying data changed.
+
+ * http/tests/inspector/replay/replay-test.js:
+ (InspectorTestProxy.runSingleSegmentRefTest): Add calls to optional setup
+ functions in the test page called setupPreCapture and setupPreReplay.
+
</ins><span class="cx"> 2014-04-10 Carlos Alberto Lopez Perez <clopez@igalia.com>
</span><span class="cx">
</span><span class="cx"> [GTK] Unreviewed GTK gardening.
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsinspectorreplayreplaytestjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/inspector/replay/replay-test.js (167084 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/inspector/replay/replay-test.js        2014-04-10 19:26:28 UTC (rev 167084)
+++ trunk/LayoutTests/http/tests/inspector/replay/replay-test.js        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -17,6 +17,9 @@
</span><span class="cx"> })
</span><span class="cx"> .then(function() {
</span><span class="cx"> InspectorTest.log("Test page initial load done.");
</span><ins>+ return RuntimeAgent.evaluate.promise("if (typeof \"setupPreCapture\" === \"function\") setupPreCapture()");
+ })
+ .then(function() {
</ins><span class="cx"> return new Promise(function startCapturing(resolve, reject) {
</span><span class="cx"> InspectorTest.log("Waiting for capturing to start...");
</span><span class="cx"> WebInspector.replayManager.startCapturing();
</span><span class="lines">@@ -42,6 +45,9 @@
</span><span class="cx"> });
</span><span class="cx"> })
</span><span class="cx"> .then(function() {
</span><ins>+ return RuntimeAgent.evaluate.promise("if (typeof \"setupPreCapture\" === \"function\") setupPreReplay()");
+ })
+ .then(function() {
</ins><span class="cx"> InspectorTest.log("Capture stopped, now starting replay to completion...")
</span><span class="cx"> return new Promise(function startPlayback(resolve, reject) {
</span><span class="cx"> WebInspector.replayManager.replayToCompletion();
</span><span class="lines">@@ -76,4 +82,4 @@
</span><span class="cx"> });
</span><span class="cx"> };
</span><span class="cx">
</span><del>-});
</del><span class="cx">\ No newline at end of file
</span><ins>+});
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorreplaywindownavigatorpluginsmemoizedexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/replay/window-navigator-plugins-memoized-expected.txt (0 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/replay/window-navigator-plugins-memoized-expected.txt         (rev 0)
+++ trunk/LayoutTests/inspector/replay/window-navigator-plugins-memoized-expected.txt        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+Tests that we can capture and replay nondeterminism in window.navigator.plugins and window.navigator.mimeTypes.
+
+ Waiting for test page to finish its initial load...
+Test page initial load done.
+Waiting for capturing to start...
+Capturing has started.
+Waiting to capture initial navigation...
+Initial navigation captured. Dumping state....
+Capture stopped, now starting replay to completion...
+Playback has started.
+Waiting to replay initial navigation...
+Initial navigation replayed. Dumping state...
+PASS: Nondeterministic state should not differ during capture and replay.
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorreplaywindownavigatorpluginsmemoizedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/replay/window-navigator-plugins-memoized.html (0 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/replay/window-navigator-plugins-memoized.html         (rev 0)
+++ trunk/LayoutTests/inspector/replay/window-navigator-plugins-memoized.html        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -0,0 +1,104 @@
</span><ins>+<html>
+<head>
+<script type="text/javascript" src="../../http/tests/inspector/inspector-test.js"></script>
+<script type="text/javascript" src="../../http/tests/inspector/replay/replay-test.js"></script>
+<script>
+function shallowCopy(object, properties) {
+ var copiedObject = {};
+ for (var prop of properties)
+ copiedObject[prop] = object[prop];
+
+ return copiedObject;
+}
+
+function shallowIndexOf(candidates, objectToFind, properties) {
+ if (!objectToFind || !candidates.length)
+ return -1;
+
+ for (var i = 0; i < candidates.length; ++i) {
+ var objectCandidate = candidates[i];
+ var propIsEqual = function(prop) {
+ return objectCandidate[prop] === objectToFind[prop];
+ };
+
+ if (properties.every(propIsEqual))
+ return i;
+ }
+
+ return -1;
+}
+
+function dumpNondeterministicState()
+{
+ var mimeKeys = ["type", "suffixes", "description"];
+ var pluginKeys = ["name", "filename", "description", "length"];
+
+ var mimeTypes = [];
+ var plugins = [];
+
+ var pluginArray = window.navigator.plugins;
+ var mimesArray = window.navigator.mimeTypes;
+
+ // First gather all of the instances into an array.
+ for (var i = 0; i < pluginArray.length; ++i)
+ plugins.push(pluginArray.item(i));
+
+ for (var i = 0; i < mimesArray.length; ++i)
+ mimeTypes.push(mimesArray.item(i));
+
+ function serializePlugin(object) {
+ console.assert(object instanceof window.Plugin);
+
+ // Copy shallow properties and find indices for cross-references.
+ var data = shallowCopy(object, pluginKeys);
+ var mimeIndices = [];
+ for (var i = 0; i < object.length; ++i)
+ mimeIndices.push(shallowIndexOf(mimeTypes, object.item(i), mimeKeys));
+
+ data.mimeIndices = mimeIndices;
+ return data;
+ }
+
+ function serializeMimeType(object) {
+ console.assert(object instanceof window.MimeType);
+
+ // Copy shallow properties and find indices for cross-references.
+ var data = shallowCopy(object, mimeKeys);
+ data.pluginIndex = shallowIndexOf(plugins, object.enabledPlugin, pluginKeys);
+ return data;
+ }
+
+ return {
+ "plugins": plugins.map(serializePlugin),
+ "mimeTypes": mimeTypes.map(serializeMimeType)
+ };
+}
+
+// These functions are called in the previous main frame prior to the initial
+// navigation that begins capturing or replaying. Careful, heap state will be lost.
+function setupPreCapture() {
+ InspectorTestProxy.addResult("Enabling plugins before capture.");
+ testRunner.setPluginsEnabled(false);
+}
+
+function setupPreReplay() {
+ InspectorTestProxy.addResult("Disabling plugins before replay.");
+ testRunner.setPluginsEnabled(true);
+}
+
+function test()
+{
+ function statesAreEqual(a, b)
+ {
+ return a === b;
+ }
+
+ InspectorTest.Replay.runSingleSegmentRefTest(statesAreEqual);
+}
+
+</script>
+</head>
+<body onload="runTest()">
+<p>Tests that we can capture and replay nondeterminism in <tt>window.navigator.plugins<tt> and <tt>window.navigator.mimeTypes</tt>.</p>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (167084 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-04-10 19:26:28 UTC (rev 167084)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2014-04-10 Brian J. Burg <burg@cs.washington.edu>
+
+ Web Replay: memoize plugin data for navigator.mimeTypes and navigator.plugins
+ https://bugs.webkit.org/show_bug.cgi?id=131341
+
+ Reviewed by Timothy Hatcher.
+
+ Add support for encoding/decoding unsigned long with EncodedValue.
+ It is a distinct type from uint32_t and uint64_t.
+
+ * replay/EncodedValue.cpp:
+ (JSC::EncodedValue::convertTo<unsigned long>):
+ * replay/EncodedValue.h:
+
</ins><span class="cx"> 2014-04-10 Mark Lam <mark.lam@apple.com>
</span><span class="cx">
</span><span class="cx"> LLINT loadisFromInstruction should handle the big endian case.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorereplayEncodedValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/replay/EncodedValue.cpp (167084 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/replay/EncodedValue.cpp        2014-04-10 19:26:28 UTC (rev 167084)
+++ trunk/Source/JavaScriptCore/replay/EncodedValue.cpp        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -158,6 +158,15 @@
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+template<> unsigned long EncodedValue::convertTo<unsigned long>()
+{
+ unsigned long result;
+ bool castSucceeded = m_value->asNumber(&result);
+ ASSERT_UNUSED(castSucceeded, castSucceeded);
+
+ return result;
+}
+
</ins><span class="cx"> template<> String EncodedValue::convertTo<String>()
</span><span class="cx"> {
</span><span class="cx"> String result;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorereplayEncodedValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/replay/EncodedValue.h (167084 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/replay/EncodedValue.h        2014-04-10 19:26:28 UTC (rev 167084)
+++ trunk/Source/JavaScriptCore/replay/EncodedValue.h        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -92,13 +92,13 @@
</span><span class="cx"> template<> JS_EXPORT_PRIVATE int64_t EncodedValue::convertTo<int64_t>();
</span><span class="cx"> template<> JS_EXPORT_PRIVATE uint32_t EncodedValue::convertTo<uint32_t>();
</span><span class="cx"> template<> JS_EXPORT_PRIVATE uint64_t EncodedValue::convertTo<uint64_t>();
</span><ins>+template<> JS_EXPORT_PRIVATE unsigned long EncodedValue::convertTo<unsigned long>();
</ins><span class="cx"> template<> JS_EXPORT_PRIVATE String EncodedValue::convertTo<String>();
</span><span class="cx">
</span><span class="cx"> template<typename T>
</span><span class="cx"> struct EncodingTraits {
</span><span class="cx"> typedef T DecodedType;
</span><span class="cx">
</span><del>- static EncodedValue encodeValue(DecodedType);
</del><span class="cx"> static EncodedValue encodeValue(const DecodedType&);
</span><span class="cx">
</span><span class="cx"> static bool decodeValue(EncodedValue&, DecodedType&);
</span><span class="lines">@@ -156,6 +156,7 @@
</span><span class="cx"> template<> struct EncodingTraits<int64_t> : public ScalarEncodingTraits<int64_t> { };
</span><span class="cx"> template<> struct EncodingTraits<uint32_t> : public ScalarEncodingTraits<uint32_t> { };
</span><span class="cx"> template<> struct EncodingTraits<uint64_t> : public ScalarEncodingTraits<uint64_t> { };
</span><ins>+template<> struct EncodingTraits<unsigned long> : public ScalarEncodingTraits<unsigned long> { };
</ins><span class="cx">
</span><span class="cx"> template<> struct EncodingTraits<String> : public ScalarEncodingTraits<String> {
</span><span class="cx"> static EncodedValue encodeValue(const String& value)
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (167084 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-04-10 19:26:28 UTC (rev 167084)
+++ trunk/Source/WebCore/ChangeLog        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -1,3 +1,46 @@
</span><ins>+2014-04-10 Brian J. Burg <burg@cs.washington.edu>
+
+ Web Replay: memoize plugin data for navigator.mimeTypes and navigator.plugins
+ https://bugs.webkit.org/show_bug.cgi?id=131341
+
+ Reviewed by Timothy Hatcher.
+
+ Information about plugins and mime types is nondeterministic and can change
+ at any time, whether by system events, browser settings changes, or
+ triggered by script. To avoid interposing on all those code paths, just
+ memoize the plugin data used by DOMPluginArray and DOMMimeTypeArray.
+
+ This is less efficient than controlling mutations to the underlying PluginData
+ of a Page, but that can be done later if better plugin support is desired.
+ The point of this change is to make analytics trackers deterministic across
+ enabling/disabling of plugins.
+
+ Test: LayoutTests/inspector/window-navigator-plugins-memoized.hml
+
+ * plugins/DOMMimeTypeArray.cpp:
+ (WebCore::DOMMimeTypeArray::getPluginData):
+ * plugins/DOMPluginArray.cpp:
+ (WebCore::DOMPluginArray::pluginData): Save or restore memoized plugin
+ data during capture and replay, respectively.
+
+ * plugins/PluginData.h:
+ (WebCore::PluginData::PluginData): Add a constructor that uses the
+ provided plugin data rather than fetching live plugin data. This is
+ marked protected so it's only used by a subclass specifically for
+ deserialization.
+
+ * replay/SerializationMethods.cpp: Add encoder specializations.
+ (JSC::EncodingTraits<MimeClassInfo>::encodeValue):
+ (JSC::EncodingTraits<MimeClassInfo>::decodeValue):
+ (JSC::EncodingTraits<PluginInfo>::encodeValue):
+ (JSC::EncodingTraits<PluginInfo>::decodeValue):
+ (JSC::EncodingTraits<PluginData>::encodeValue):
+ (JSC::DeserializedPluginData::DeserializedPluginData): Add a custom
+ subclass of PluginData that can be initialized from deserialized data.
+ (JSC::EncodingTraits<PluginData>::decodeValue):
+ * replay/SerializationMethods.h:
+ * replay/WebInputs.json: Add new input FetchPluginData.
+
</ins><span class="cx"> 2014-04-10 Myles C. Maxfield <mmaxfield@apple.com>
</span><span class="cx">
</span><span class="cx"> Remove "System Font" from character width calculations
</span></span></pre></div>
<a id="trunkSourceWebCorepluginsDOMMimeTypeArraycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/plugins/DOMMimeTypeArray.cpp (167084 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/plugins/DOMMimeTypeArray.cpp        2014-04-10 19:26:28 UTC (rev 167084)
+++ trunk/Source/WebCore/plugins/DOMMimeTypeArray.cpp        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -26,6 +26,12 @@
</span><span class="cx"> #include "PluginData.h"
</span><span class="cx"> #include <wtf/text/AtomicString.h>
</span><span class="cx">
</span><ins>+#if ENABLE(WEB_REPLAY)
+#include "Document.h"
+#include "WebReplayInputs.h"
+#include <replay/InputCursor.h>
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> DOMMimeTypeArray::DOMMimeTypeArray(Frame* frame)
</span><span class="lines">@@ -85,11 +91,28 @@
</span><span class="cx"> PluginData* DOMMimeTypeArray::getPluginData() const
</span><span class="cx"> {
</span><span class="cx"> if (!m_frame)
</span><del>- return 0;
</del><ins>+ return nullptr;
+
</ins><span class="cx"> Page* page = m_frame->page();
</span><span class="cx"> if (!page)
</span><del>- return 0;
- return &page->pluginData();
</del><ins>+ return nullptr;
+
+ PluginData* pluginData = &page->pluginData();
+
+#if ENABLE(WEB_REPLAY)
+ if (!m_frame->document())
+ return pluginData;
+
+ InputCursor& cursor = m_frame->document()->inputCursor();
+ if (cursor.isCapturing())
+ cursor.appendInput<FetchPluginData>(pluginData);
+ else if (cursor.isReplaying()) {
+ if (FetchPluginData* input = cursor.fetchInput<FetchPluginData>())
+ pluginData = input->pluginData().get();
+ }
+#endif
+
+ return pluginData;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorepluginsDOMPluginArraycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/plugins/DOMPluginArray.cpp (167084 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/plugins/DOMPluginArray.cpp        2014-04-10 19:26:28 UTC (rev 167084)
+++ trunk/Source/WebCore/plugins/DOMPluginArray.cpp        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -26,6 +26,12 @@
</span><span class="cx"> #include "PluginData.h"
</span><span class="cx"> #include <wtf/text/AtomicString.h>
</span><span class="cx">
</span><ins>+#if ENABLE(WEB_REPLAY)
+#include "Document.h"
+#include "WebReplayInputs.h"
+#include <replay/InputCursor.h>
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> DOMPluginArray::DOMPluginArray(Frame* frame)
</span><span class="lines">@@ -90,11 +96,28 @@
</span><span class="cx"> PluginData* DOMPluginArray::pluginData() const
</span><span class="cx"> {
</span><span class="cx"> if (!m_frame)
</span><del>- return 0;
</del><ins>+ return nullptr;
+
</ins><span class="cx"> Page* page = m_frame->page();
</span><span class="cx"> if (!page)
</span><del>- return 0;
- return &page->pluginData();
</del><ins>+ return nullptr;
+
+ PluginData* pluginData = &page->pluginData();
+
+#if ENABLE(WEB_REPLAY)
+ if (!m_frame->document())
+ return pluginData;
+
+ InputCursor& cursor = m_frame->document()->inputCursor();
+ if (cursor.isCapturing())
+ cursor.appendInput<FetchPluginData>(pluginData);
+ else if (cursor.isReplaying()) {
+ if (FetchPluginData* input = cursor.fetchInput<FetchPluginData>())
+ pluginData = input->pluginData().get();
+ }
+#endif
+
+ return pluginData;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorepluginsPluginDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/plugins/PluginData.h (167084 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/plugins/PluginData.h        2014-04-10 19:26:28 UTC (rev 167084)
+++ trunk/Source/WebCore/plugins/PluginData.h        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -73,6 +73,16 @@
</span><span class="cx"> void initPlugins(const Page*);
</span><span class="cx"> const PluginInfo* pluginInfoForMimeType(const String& mimeType) const;
</span><span class="cx">
</span><ins>+protected:
+#if ENABLE(WEB_REPLAY)
+ PluginData(Vector<PluginInfo> plugins, Vector<MimeClassInfo> mimes, Vector<size_t> indices)
+ : m_plugins(plugins)
+ , m_mimes(mimes)
+ , m_mimePluginIndices(indices)
+ {
+ }
+#endif
+
</ins><span class="cx"> Vector<PluginInfo> m_plugins;
</span><span class="cx"> Vector<MimeClassInfo> m_mimes;
</span><span class="cx"> Vector<size_t> m_mimePluginIndices;
</span></span></pre></div>
<a id="trunkSourceWebCorereplaySerializationMethodscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/replay/SerializationMethods.cpp (167084 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/SerializationMethods.cpp        2014-04-10 19:26:28 UTC (rev 167084)
+++ trunk/Source/WebCore/replay/SerializationMethods.cpp        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> #include "PlatformKeyboardEvent.h"
</span><span class="cx"> #include "PlatformMouseEvent.h"
</span><span class="cx"> #include "PlatformWheelEvent.h"
</span><ins>+#include "PluginData.h"
</ins><span class="cx"> #include "ReplayInputTypes.h"
</span><span class="cx"> #include "SecurityOrigin.h"
</span><span class="cx"> #include "URL.h"
</span><span class="lines">@@ -46,12 +47,15 @@
</span><span class="cx">
</span><span class="cx"> using WebCore::KeypressCommand;
</span><span class="cx"> using WebCore::IntPoint;
</span><ins>+using WebCore::MimeClassInfo;
</ins><span class="cx"> using WebCore::MouseButton;
</span><span class="cx"> using WebCore::PlatformEvent;
</span><span class="cx"> using WebCore::PlatformKeyboardEvent;
</span><span class="cx"> using WebCore::PlatformMouseEvent;
</span><span class="cx"> using WebCore::PlatformWheelEvent;
</span><span class="cx"> using WebCore::PlatformWheelEventGranularity;
</span><ins>+using WebCore::PluginData;
+using WebCore::PluginInfo;
</ins><span class="cx"> using WebCore::SecurityOrigin;
</span><span class="cx"> using WebCore::URL;
</span><span class="cx"> using WebCore::inputTypes;
</span><span class="lines">@@ -147,6 +151,31 @@
</span><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="cx">
</span><ins>+template<>
+EncodedValue EncodingTraits<MimeClassInfo>::encodeValue(const MimeClassInfo& input)
+{
+ EncodedValue encodedData = EncodedValue::createObject();
+
+ ENCODE_TYPE_WITH_KEY(encodedData, String, type, input.type);
+ ENCODE_TYPE_WITH_KEY(encodedData, String, desc, input.desc);
+ ENCODE_TYPE_WITH_KEY(encodedData, Vector<String>, extensions, input.extensions);
+
+ return encodedData;
+}
+
+template<>
+bool EncodingTraits<MimeClassInfo>::decodeValue(EncodedValue& encodedData, MimeClassInfo& input)
+{
+ MimeClassInfo info;
+
+ DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, type, info.type);
+ DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, desc, info.desc);
+ DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, Vector<String>, extensions, info.extensions);
+
+ input = info;
+ return true;
+}
+
</ins><span class="cx"> EncodedValue EncodingTraits<NondeterministicInputBase>::encodeValue(const NondeterministicInputBase& input)
</span><span class="cx"> {
</span><span class="cx"> EncodedValue encodedValue = EncodedValue::createObject();
</span><span class="lines">@@ -424,6 +453,65 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+EncodedValue EncodingTraits<PluginData>::encodeValue(RefPtr<PluginData> input)
+{
+ EncodedValue encodedData = EncodedValue::createObject();
+
+ ENCODE_TYPE_WITH_KEY(encodedData, Vector<PluginInfo>, plugins, input->plugins());
+ ENCODE_TYPE_WITH_KEY(encodedData, Vector<MimeClassInfo>, mimes, input->mimes());
+ ENCODE_TYPE_WITH_KEY(encodedData, Vector<size_t>, mimePluginIndices, input->mimePluginIndices());
+
+ return encodedData;
+}
+
+class DeserializedPluginData : public PluginData {
+public:
+ DeserializedPluginData(Vector<PluginInfo> plugins, Vector<MimeClassInfo> mimes, Vector<size_t> indices)
+ : PluginData(plugins, mimes, indices)
+ {
+ }
+};
+
+bool EncodingTraits<PluginData>::decodeValue(EncodedValue& encodedData, RefPtr<PluginData>& input)
+{
+ DECODE_SCALAR_TYPE_WITH_KEY(encodedData, Vector<PluginInfo>, plugins);
+ DECODE_SCALAR_TYPE_WITH_KEY(encodedData, Vector<MimeClassInfo>, mimes);
+ DECODE_SCALAR_TYPE_WITH_KEY(encodedData, Vector<size_t>, mimePluginIndices);
+
+ input = adoptRef(new DeserializedPluginData(plugins, mimes, mimePluginIndices));
+
+ return true;
+}
+
+template<>
+EncodedValue EncodingTraits<PluginInfo>::encodeValue(const PluginInfo& input)
+{
+ EncodedValue encodedData = EncodedValue::createObject();
+
+ ENCODE_TYPE_WITH_KEY(encodedData, String, name, input.name);
+ ENCODE_TYPE_WITH_KEY(encodedData, String, file, input.file);
+ ENCODE_TYPE_WITH_KEY(encodedData, String, desc, input.desc);
+ ENCODE_TYPE_WITH_KEY(encodedData, Vector<MimeClassInfo>, mimes, input.mimes);
+ ENCODE_TYPE_WITH_KEY(encodedData, bool, isApplicationPlugin, input.isApplicationPlugin);
+
+ return encodedData;
+}
+
+template<>
+bool EncodingTraits<PluginInfo>::decodeValue(EncodedValue& encodedData, PluginInfo& input)
+{
+ PluginInfo info;
+
+ DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, name, info.name);
+ DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, file, info.file);
+ DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, desc, info.desc);
+ DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, Vector<MimeClassInfo>, mimes, info.mimes);
+ DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, bool, isApplicationPlugin, info.isApplicationPlugin);
+
+ input = info;
+ return true;
+}
+
</ins><span class="cx"> EncodedValue EncodingTraits<SecurityOrigin>::encodeValue(RefPtr<SecurityOrigin> input)
</span><span class="cx"> {
</span><span class="cx"> return EncodedValue::createString(input->toString());
</span></span></pre></div>
<a id="trunkSourceWebCorereplaySerializationMethodsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/replay/SerializationMethods.h (167084 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/SerializationMethods.h        2014-04-10 19:26:28 UTC (rev 167084)
+++ trunk/Source/WebCore/replay/SerializationMethods.h        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -42,6 +42,7 @@
</span><span class="cx"> class PlatformKeyboardEvent;
</span><span class="cx"> class PlatformMouseEvent;
</span><span class="cx"> class PlatformWheelEvent;
</span><ins>+class PluginData;
</ins><span class="cx"> class SecurityOrigin;
</span><span class="cx"> class URL;
</span><span class="cx">
</span><span class="lines">@@ -96,6 +97,13 @@
</span><span class="cx"> static bool decodeValue(EncodedValue&, std::unique_ptr<WebCore::PlatformWheelEvent>& value);
</span><span class="cx"> };
</span><span class="cx">
</span><ins>+template<> struct EncodingTraits<WebCore::PluginData> {
+ typedef RefPtr<WebCore::PluginData> DecodedType;
+
+ static EncodedValue encodeValue(RefPtr<WebCore::PluginData> value);
+ static bool decodeValue(EncodedValue&, RefPtr<WebCore::PluginData>& value);
+};
+
</ins><span class="cx"> template<> struct EncodingTraits<WebCore::URL> {
</span><span class="cx"> typedef WebCore::URL DecodedType;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorereplayWebInputsjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/replay/WebInputs.json (167084 => 167085)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/replay/WebInputs.json        2014-04-10 19:26:28 UTC (rev 167084)
+++ trunk/Source/WebCore/replay/WebInputs.json        2014-04-10 20:52:31 UTC (rev 167085)
</span><span class="lines">@@ -88,6 +88,10 @@
</span><span class="cx"> "header": "platform/PlatformWheelEvent.h"
</span><span class="cx"> },
</span><span class="cx"> {
</span><ins>+ "name": "PluginData", "mode": "SHARED",
+ "header": "plugins/PluginData.h"
+ },
+ {
</ins><span class="cx"> "name": "ScrollDirection", "mode": "SCALAR", "storage": "uint64_t",
</span><span class="cx"> "flags": ["ENUM"],
</span><span class="cx"> "values": ["ScrollUp", "ScrollDown", "ScrollLeft", "ScrollRight"],
</span><span class="lines">@@ -219,6 +223,14 @@
</span><span class="cx"> ]
</span><span class="cx"> },
</span><span class="cx"> {
</span><ins>+ "name": "FetchPluginData",
+ "description": "Plugin data was requested through DOMPluginArray or DOMMimeTypeArray.",
+ "queue": "SCRIPT_MEMOIZED",
+ "members": [
+ { "name": "pluginData", "type": "PluginData" }
+ ]
+ },
+ {
</ins><span class="cx"> "name": "LogicalScrollPage",
</span><span class="cx"> "description": "The embedder signalled a logical scroll event.",
</span><span class="cx"> "queue": "EVENT_LOOP",
</span></span></pre>
</div>
</div>
</body>
</html>