Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / replay / SerializationMethods.cpp
1 /*
2  * Copyright (C) 2012 University of Washington. All rights reserved.
3  * Copyright (C) 2014 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "config.h"
29 #include "SerializationMethods.h"
30
31 #if ENABLE(WEB_REPLAY)
32
33 #include "AllReplayInputs.h"
34 #include "Document.h"
35 #include "Frame.h"
36 #include "FrameTree.h"
37 #include "MainFrame.h"
38 #include "Page.h"
39 #include "PlatformKeyboardEvent.h"
40 #include "PlatformMouseEvent.h"
41 #include "PlatformWheelEvent.h"
42 #include "PluginData.h"
43 #include "SecurityOrigin.h"
44 #include "URL.h"
45 #include <wtf/text/Base64.h>
46
47 using WebCore::IntPoint;
48 using WebCore::MimeClassInfo;
49 using WebCore::MouseButton;
50 using WebCore::PlatformEvent;
51 using WebCore::PlatformKeyboardEvent;
52 using WebCore::PlatformMouseEvent;
53 using WebCore::PlatformWheelEvent;
54 using WebCore::PlatformWheelEventGranularity;
55 using WebCore::PluginData;
56 using WebCore::PluginLoadClientPolicy;
57 using WebCore::PluginInfo;
58 using WebCore::SecurityOrigin;
59 using WebCore::URL;
60
61 #if PLATFORM(COCOA)
62 using WebCore::KeypressCommand;
63 using WebCore::PlatformWheelEventPhase;
64 #endif
65
66 #define IMPORT_FROM_WEBCORE_NAMESPACE(name) \
67 using WebCore::name; \
68
69 WEB_REPLAY_INPUT_NAMES_FOR_EACH(IMPORT_FROM_WEBCORE_NAMESPACE)
70 #undef IMPORT_FROM_WEBCORE_NAMESPACE
71
72 namespace WebCore {
73
74 uint32_t frameIndexFromDocument(const Document* document)
75 {
76     ASSERT(document);
77     ASSERT(document->frame());
78     return frameIndexFromFrame(document->frame());
79 }
80
81 uint32_t frameIndexFromFrame(const Frame* targetFrame)
82 {
83     ASSERT(targetFrame);
84
85     uint32_t currentIndex = 0;
86     for (const Frame* frame = &targetFrame->tree().top(); frame; ++currentIndex, frame = frame->tree().traverseNext()) {
87         if (frame == targetFrame)
88             return currentIndex;
89     }
90
91     ASSERT_NOT_REACHED();
92     return 0;
93 }
94
95 Document* documentFromFrameIndex(Page* page, uint32_t frameIndex)
96 {
97     Frame* frame = frameFromFrameIndex(page, frameIndex);
98     return frame ? frame->document() : nullptr;
99 }
100
101 Frame* frameFromFrameIndex(Page* page, uint32_t frameIndex)
102 {
103     ASSERT(page);
104     ASSERT(frameIndex >= 0);
105
106     Frame* frame = &page->mainFrame();
107     uint32_t currentIndex = 0;
108     for (; currentIndex < frameIndex && frame; ++currentIndex, frame = frame->tree().traverseNext()) { }
109
110     return frame;
111 }
112
113 } // namespace WebCore
114
115 #define ENCODE_TYPE_WITH_KEY(_encodedValue, _type, _key, _value) \
116     _encodedValue.put<_type>(ASCIILiteral(#_key), _value)
117
118 #define ENCODE_OPTIONAL_TYPE_WITH_KEY(_encodedValue, _type, _key, _value, condition) \
119     if (condition) \
120         ENCODE_TYPE_WITH_KEY(_encodedValue, _type, _key, _value)
121
122 #define DECODE_TYPE_WITH_KEY_TO_LVALUE(_encodedValue, _type, _key, _lvalue) \
123     if (!_encodedValue.get<_type>(ASCIILiteral(#_key), _lvalue)) \
124         return false
125
126 #define DECODE_TYPE_WITH_KEY(_encodedValue, _type, _key) \
127     EncodingTraits<_type>::DecodedType _key; \
128     DECODE_TYPE_WITH_KEY_TO_LVALUE(_encodedValue, _type, _key, _key)
129
130 #define DECODE_OPTIONAL_TYPE_WITH_KEY_TO_LVALUE(_encodedValue, _type, _key, _lvalue) \
131     bool _key ## WasDecoded = _encodedValue.get<_type>(ASCIILiteral(#_key), _lvalue)
132
133 #define DECODE_OPTIONAL_TYPE_WITH_KEY(_encodedValue, _type, _key) \
134     EncodingTraits<_type>::DecodedType _key; \
135     DECODE_OPTIONAL_TYPE_WITH_KEY_TO_LVALUE(_encodedValue, _type, _key, _key)
136
137 namespace JSC {
138
139 template<>
140 EncodedValue EncodingTraits<MimeClassInfo>::encodeValue(const MimeClassInfo& input)
141 {
142     EncodedValue encodedData = EncodedValue::createObject();
143
144     ENCODE_TYPE_WITH_KEY(encodedData, String, type, input.type);
145     ENCODE_TYPE_WITH_KEY(encodedData, String, desc, input.desc);
146     ENCODE_TYPE_WITH_KEY(encodedData, Vector<String>, extensions, input.extensions);
147
148     return encodedData;
149 }
150
151 template<>
152 bool EncodingTraits<MimeClassInfo>::decodeValue(EncodedValue& encodedData, MimeClassInfo& input)
153 {
154     MimeClassInfo info;
155
156     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, type, info.type);
157     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, desc, info.desc);
158     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, Vector<String>, extensions, info.extensions);
159
160     input = info;
161     return true;
162 }
163
164 EncodedValue EncodingTraits<NondeterministicInputBase>::encodeValue(const NondeterministicInputBase& input)
165 {
166     EncodedValue encodedValue = EncodedValue::createObject();
167     ENCODE_TYPE_WITH_KEY(encodedValue, String, type, input.type());
168
169 #define ENCODE_IF_TYPE_TAG_MATCHES(name) \
170     if (is<name>(input)) { \
171         InputTraits<name>::encode(encodedValue, downcast<name>(input)); \
172         return encodedValue; \
173     } \
174
175     JS_REPLAY_INPUT_NAMES_FOR_EACH(ENCODE_IF_TYPE_TAG_MATCHES)
176     WEB_REPLAY_INPUT_NAMES_FOR_EACH(ENCODE_IF_TYPE_TAG_MATCHES)
177 #undef ENCODE_IF_TYPE_TAG_MATCHES
178
179     // The macro won't work here because of the class template argument.
180     if (is<MemoizedDOMResultBase>(input)) {
181         InputTraits<MemoizedDOMResultBase>::encode(encodedValue, downcast<MemoizedDOMResultBase>(input));
182         return encodedValue;
183     }
184
185     ASSERT_NOT_REACHED();
186     return EncodedValue();
187 }
188
189 bool EncodingTraits<NondeterministicInputBase>::decodeValue(EncodedValue& encodedValue, std::unique_ptr<NondeterministicInputBase>& input)
190 {
191     DECODE_TYPE_WITH_KEY(encodedValue, String, type);
192
193 #define DECODE_IF_TYPE_TAG_MATCHES(name) \
194     if (type == InputTraits<name>::type()) { \
195         std::unique_ptr<name> decodedInput; \
196         if (!InputTraits<name>::decode(encodedValue, decodedInput)) \
197             return false; \
198         \
199         input = WTFMove(decodedInput); \
200         return true; \
201     } \
202
203     JS_REPLAY_INPUT_NAMES_FOR_EACH(DECODE_IF_TYPE_TAG_MATCHES)
204     WEB_REPLAY_INPUT_NAMES_FOR_EACH(DECODE_IF_TYPE_TAG_MATCHES)
205 #undef DECODE_IF_TYPE_TAG_MATCHES
206
207     if (type == InputTraits<MemoizedDOMResultBase>::type()) {
208         std::unique_ptr<MemoizedDOMResultBase> decodedInput;
209         if (!InputTraits<MemoizedDOMResultBase>::decode(encodedValue, decodedInput))
210             return false;
211
212         input = WTFMove(decodedInput);
213         return true;
214     }
215
216     return false;
217 }
218
219 #if USE(APPKIT)
220 EncodedValue EncodingTraits<KeypressCommand>::encodeValue(const KeypressCommand& command)
221 {
222     EncodedValue encodedValue = EncodedValue::createObject();
223
224     ENCODE_TYPE_WITH_KEY(encodedValue, String, commandName, command.commandName);
225     ENCODE_OPTIONAL_TYPE_WITH_KEY(encodedValue, String, text, command.text, !command.text.isEmpty());
226
227     return encodedValue;
228 }
229
230 bool EncodingTraits<KeypressCommand>::decodeValue(EncodedValue& encodedValue, KeypressCommand& decodedValue)
231 {
232     DECODE_TYPE_WITH_KEY(encodedValue, String, commandName);
233     DECODE_OPTIONAL_TYPE_WITH_KEY(encodedValue, String, text);
234
235     decodedValue = textWasDecoded ? KeypressCommand(commandName, text) : KeypressCommand(commandName);
236     return true;
237 }
238
239 class PlatformKeyboardEventAppKit : public WebCore::PlatformKeyboardEvent {
240 public:
241     PlatformKeyboardEventAppKit(const PlatformKeyboardEvent& event, bool handledByInputMethod, Vector<KeypressCommand>& commands)
242         : PlatformKeyboardEvent(event)
243     {
244         m_handledByInputMethod = handledByInputMethod;
245         m_commands = commands;
246     }
247 };
248 #endif // USE(APPKIT)
249
250 EncodedValue EncodingTraits<PlatformKeyboardEvent>::encodeValue(const PlatformKeyboardEvent& input)
251 {
252     EncodedValue encodedValue = EncodedValue::createObject();
253
254     ENCODE_TYPE_WITH_KEY(encodedValue, double, timestamp, input.timestamp());
255     ENCODE_TYPE_WITH_KEY(encodedValue, PlatformEvent::Type, type, input.type());
256     ENCODE_TYPE_WITH_KEY(encodedValue, PlatformEvent::Modifiers, modifiers, static_cast<PlatformEvent::Modifiers>(input.modifiers()));
257     ENCODE_TYPE_WITH_KEY(encodedValue, String, text, input.text());
258     ENCODE_TYPE_WITH_KEY(encodedValue, String, unmodifiedText, input.unmodifiedText());
259     ENCODE_TYPE_WITH_KEY(encodedValue, String, keyIdentifier, input.keyIdentifier());
260     ENCODE_TYPE_WITH_KEY(encodedValue, int, windowsVirtualKeyCode, input.windowsVirtualKeyCode());
261     ENCODE_TYPE_WITH_KEY(encodedValue, int, nativeVirtualKeyCode, input.nativeVirtualKeyCode());
262     ENCODE_TYPE_WITH_KEY(encodedValue, int, macCharCode, input.macCharCode());
263     ENCODE_TYPE_WITH_KEY(encodedValue, bool, autoRepeat, input.isAutoRepeat());
264     ENCODE_TYPE_WITH_KEY(encodedValue, bool, keypad, input.isKeypad());
265     ENCODE_TYPE_WITH_KEY(encodedValue, bool, systemKey, input.isSystemKey());
266 #if USE(APPKIT)
267     ENCODE_TYPE_WITH_KEY(encodedValue, bool, handledByInputMethod, input.handledByInputMethod());
268     ENCODE_TYPE_WITH_KEY(encodedValue, Vector<KeypressCommand>, commands, input.commands());
269 #endif
270     return encodedValue;
271 }
272
273 bool EncodingTraits<PlatformKeyboardEvent>::decodeValue(EncodedValue& encodedValue, std::unique_ptr<PlatformKeyboardEvent>& input)
274 {
275     DECODE_TYPE_WITH_KEY(encodedValue, double, timestamp);
276     DECODE_TYPE_WITH_KEY(encodedValue, PlatformEvent::Type, type);
277     DECODE_TYPE_WITH_KEY(encodedValue, PlatformEvent::Modifiers, modifiers);
278     DECODE_TYPE_WITH_KEY(encodedValue, String, text);
279     DECODE_TYPE_WITH_KEY(encodedValue, String, unmodifiedText);
280     DECODE_TYPE_WITH_KEY(encodedValue, String, keyIdentifier);
281     DECODE_TYPE_WITH_KEY(encodedValue, int, windowsVirtualKeyCode);
282     DECODE_TYPE_WITH_KEY(encodedValue, int, nativeVirtualKeyCode);
283     DECODE_TYPE_WITH_KEY(encodedValue, int, macCharCode);
284     DECODE_TYPE_WITH_KEY(encodedValue, bool, autoRepeat);
285     DECODE_TYPE_WITH_KEY(encodedValue, bool, keypad);
286     DECODE_TYPE_WITH_KEY(encodedValue, bool, systemKey);
287 #if USE(APPKIT)
288     DECODE_TYPE_WITH_KEY(encodedValue, bool, handledByInputMethod);
289     DECODE_TYPE_WITH_KEY(encodedValue, Vector<KeypressCommand>, commands);
290 #endif
291
292     PlatformKeyboardEvent platformEvent = PlatformKeyboardEvent(type, text, unmodifiedText, keyIdentifier, WTF::safeCast<int>(windowsVirtualKeyCode), WTF::safeCast<int>(nativeVirtualKeyCode), WTF::safeCast<int>(macCharCode), autoRepeat, keypad, systemKey, modifiers, timestamp);
293 #if USE(APPKIT)
294     input = std::make_unique<PlatformKeyboardEventAppKit>(platformEvent, handledByInputMethod, commands);
295 #else
296     input = std::make_unique<PlatformKeyboardEvent>(platformEvent);
297 #endif
298     return true;
299 }
300
301 EncodedValue EncodingTraits<PlatformMouseEvent>::encodeValue(const PlatformMouseEvent& input)
302 {
303     EncodedValue encodedValue = EncodedValue::createObject();
304
305     ENCODE_TYPE_WITH_KEY(encodedValue, int, positionX, input.position().x());
306     ENCODE_TYPE_WITH_KEY(encodedValue, int, positionY, input.position().y());
307     ENCODE_TYPE_WITH_KEY(encodedValue, int, globalPositionX, input.globalPosition().x());
308     ENCODE_TYPE_WITH_KEY(encodedValue, int, globalPositionY, input.globalPosition().y());
309     ENCODE_TYPE_WITH_KEY(encodedValue, MouseButton, button, input.button());
310     ENCODE_TYPE_WITH_KEY(encodedValue, PlatformEvent::Type, type, input.type());
311     ENCODE_TYPE_WITH_KEY(encodedValue, int, clickCount, input.clickCount());
312     ENCODE_TYPE_WITH_KEY(encodedValue, bool, shiftKey, input.shiftKey());
313     ENCODE_TYPE_WITH_KEY(encodedValue, bool, ctrlKey, input.ctrlKey());
314     ENCODE_TYPE_WITH_KEY(encodedValue, bool, altKey, input.altKey());
315     ENCODE_TYPE_WITH_KEY(encodedValue, bool, metaKey, input.metaKey());
316     ENCODE_TYPE_WITH_KEY(encodedValue, int, timestamp, input.timestamp());
317     ENCODE_TYPE_WITH_KEY(encodedValue, double, force, input.force());
318
319     return encodedValue;
320 }
321
322 bool EncodingTraits<PlatformMouseEvent>::decodeValue(EncodedValue& encodedValue, std::unique_ptr<PlatformMouseEvent>& input)
323 {
324     DECODE_TYPE_WITH_KEY(encodedValue, int, positionX);
325     DECODE_TYPE_WITH_KEY(encodedValue, int, positionY);
326     DECODE_TYPE_WITH_KEY(encodedValue, int, globalPositionX);
327     DECODE_TYPE_WITH_KEY(encodedValue, int, globalPositionY);
328     DECODE_TYPE_WITH_KEY(encodedValue, MouseButton, button);
329     DECODE_TYPE_WITH_KEY(encodedValue, PlatformEvent::Type, type);
330     DECODE_TYPE_WITH_KEY(encodedValue, int, clickCount);
331     DECODE_TYPE_WITH_KEY(encodedValue, bool, shiftKey);
332     DECODE_TYPE_WITH_KEY(encodedValue, bool, ctrlKey);
333     DECODE_TYPE_WITH_KEY(encodedValue, bool, altKey);
334     DECODE_TYPE_WITH_KEY(encodedValue, bool, metaKey);
335     DECODE_TYPE_WITH_KEY(encodedValue, int, timestamp);
336     DECODE_TYPE_WITH_KEY(encodedValue, double, force);
337
338     input = std::make_unique<PlatformMouseEvent>(IntPoint(positionX, positionY),
339         IntPoint(globalPositionX, globalPositionY),
340         button, type, clickCount,
341         shiftKey, ctrlKey, altKey, metaKey, timestamp, force);
342     return true;
343 }
344
345 #if PLATFORM(COCOA)
346 struct PlatformWheelEventCocoaArguments {
347     bool directionInvertedFromDevice;
348     bool hasPreciseScrollingDeltas;
349     PlatformWheelEventPhase phase;
350     PlatformWheelEventPhase momentumPhase;
351     int scrollCount;
352     float unacceleratedScrollingDeltaX;
353     float unacceleratedScrollingDeltaY;
354 };
355
356 class PlatformWheelEventCocoa : public PlatformWheelEvent {
357 public:
358     PlatformWheelEventCocoa(PlatformWheelEvent& event, PlatformWheelEventCocoaArguments& arguments)
359         : PlatformWheelEvent(event)
360     {
361         m_directionInvertedFromDevice = arguments.directionInvertedFromDevice;
362         m_hasPreciseScrollingDeltas = arguments.hasPreciseScrollingDeltas;
363         m_phase = arguments.phase;
364         m_momentumPhase = arguments.momentumPhase;
365         m_scrollCount = arguments.scrollCount;
366         m_unacceleratedScrollingDeltaX = arguments.unacceleratedScrollingDeltaX;
367         m_unacceleratedScrollingDeltaY = arguments.unacceleratedScrollingDeltaY;
368     }
369 };
370 #endif // PLATFORM(COCOA)
371
372 EncodedValue EncodingTraits<PlatformWheelEvent>::encodeValue(const PlatformWheelEvent& input)
373 {
374     EncodedValue encodedData = EncodedValue::createObject();
375
376     ENCODE_TYPE_WITH_KEY(encodedData, int, positionX, input.position().x());
377     ENCODE_TYPE_WITH_KEY(encodedData, int, positionY, input.position().y());
378     ENCODE_TYPE_WITH_KEY(encodedData, int, globalPositionX, input.globalPosition().x());
379     ENCODE_TYPE_WITH_KEY(encodedData, int, globalPositionY, input.globalPosition().y());
380     ENCODE_TYPE_WITH_KEY(encodedData, bool, shiftKey, input.shiftKey());
381     ENCODE_TYPE_WITH_KEY(encodedData, bool, ctrlKey, input.ctrlKey());
382     ENCODE_TYPE_WITH_KEY(encodedData, bool, altKey, input.altKey());
383     ENCODE_TYPE_WITH_KEY(encodedData, bool, metaKey, input.metaKey());
384     ENCODE_TYPE_WITH_KEY(encodedData, float, deltaX, input.deltaX());
385     ENCODE_TYPE_WITH_KEY(encodedData, float, deltaY, input.deltaY());
386     ENCODE_TYPE_WITH_KEY(encodedData, float, wheelTicksX, input.wheelTicksX());
387     ENCODE_TYPE_WITH_KEY(encodedData, float, wheelTicksY, input.wheelTicksY());
388     ENCODE_TYPE_WITH_KEY(encodedData, PlatformWheelEventGranularity, granularity, static_cast<PlatformWheelEventGranularity>(input.granularity()));
389
390 #if PLATFORM(COCOA)
391     ENCODE_TYPE_WITH_KEY(encodedData, bool, directionInvertedFromDevice, input.directionInvertedFromDevice());
392     ENCODE_TYPE_WITH_KEY(encodedData, bool, hasPreciseScrollingDeltas, input.hasPreciseScrollingDeltas());
393     ENCODE_TYPE_WITH_KEY(encodedData, PlatformWheelEventPhase, phase, static_cast<PlatformWheelEventPhase>(input.phase()));
394     ENCODE_TYPE_WITH_KEY(encodedData, PlatformWheelEventPhase, momentumPhase, static_cast<PlatformWheelEventPhase>(input.momentumPhase()));
395     ENCODE_TYPE_WITH_KEY(encodedData, int, scrollCount, input.scrollCount());
396     ENCODE_TYPE_WITH_KEY(encodedData, float, unacceleratedScrollingDeltaX, input.unacceleratedScrollingDeltaX());
397     ENCODE_TYPE_WITH_KEY(encodedData, float, unacceleratedScrollingDeltaY, input.unacceleratedScrollingDeltaY());
398 #endif
399
400     return encodedData;
401 }
402
403 bool EncodingTraits<PlatformWheelEvent>::decodeValue(EncodedValue& encodedData, std::unique_ptr<PlatformWheelEvent>& input)
404 {
405     DECODE_TYPE_WITH_KEY(encodedData, int, positionX);
406     DECODE_TYPE_WITH_KEY(encodedData, int, positionY);
407     DECODE_TYPE_WITH_KEY(encodedData, int, globalPositionX);
408     DECODE_TYPE_WITH_KEY(encodedData, int, globalPositionY);
409     DECODE_TYPE_WITH_KEY(encodedData, bool, shiftKey);
410     DECODE_TYPE_WITH_KEY(encodedData, bool, ctrlKey);
411     DECODE_TYPE_WITH_KEY(encodedData, bool, altKey);
412     DECODE_TYPE_WITH_KEY(encodedData, bool, metaKey);
413     DECODE_TYPE_WITH_KEY(encodedData, float, deltaX);
414     DECODE_TYPE_WITH_KEY(encodedData, float, deltaY);
415     DECODE_TYPE_WITH_KEY(encodedData, float, wheelTicksX);
416     DECODE_TYPE_WITH_KEY(encodedData, float, wheelTicksY);
417     DECODE_TYPE_WITH_KEY(encodedData, PlatformWheelEventGranularity, granularity);
418
419 #if PLATFORM(COCOA)
420     PlatformWheelEventCocoaArguments arguments;
421     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, bool, directionInvertedFromDevice, arguments.directionInvertedFromDevice);
422     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, bool, hasPreciseScrollingDeltas, arguments.hasPreciseScrollingDeltas);
423     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, PlatformWheelEventPhase, phase, arguments.phase);
424     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, PlatformWheelEventPhase, momentumPhase, arguments.momentumPhase);
425     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, int, scrollCount, arguments.scrollCount);
426     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, float, unacceleratedScrollingDeltaX, arguments.unacceleratedScrollingDeltaX);
427     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, float, unacceleratedScrollingDeltaY, arguments.unacceleratedScrollingDeltaY);
428 #endif
429
430     PlatformWheelEvent event(IntPoint(positionX, positionY), IntPoint(globalPositionX, globalPositionY),
431         deltaX, deltaY, wheelTicksX, wheelTicksY, granularity, shiftKey, ctrlKey, altKey, metaKey);
432
433 #if PLATFORM(COCOA)
434     input = std::make_unique<PlatformWheelEventCocoa>(event, arguments);
435 #else
436     input = std::make_unique<PlatformWheelEvent>(event);
437 #endif
438     return true;
439 }
440
441 EncodedValue EncodingTraits<PluginData>::encodeValue(RefPtr<PluginData> input)
442 {
443     // FIXME: This needs to work in terms of web-visible plug-ins.
444     EncodedValue encodedData = EncodedValue::createObject();
445
446     ENCODE_TYPE_WITH_KEY(encodedData, Vector<PluginInfo>, plugins, input->plugins());
447
448     return encodedData;
449 }
450
451 class DeserializedPluginData : public PluginData {
452 public:
453     DeserializedPluginData(Vector<PluginInfo> plugins)
454         : PluginData(plugins)
455     {
456     }
457 };
458
459 bool EncodingTraits<PluginData>::decodeValue(EncodedValue& encodedData, RefPtr<PluginData>& input)
460 {
461     DECODE_TYPE_WITH_KEY(encodedData, Vector<PluginInfo>, plugins);
462
463     // FIXME: This needs to work in terms of web-visible plug-ins.
464     input = adoptRef(new DeserializedPluginData(plugins));
465
466     return true;
467 }
468
469 template<>
470 EncodedValue EncodingTraits<PluginInfo>::encodeValue(const PluginInfo& input)
471 {
472     EncodedValue encodedData = EncodedValue::createObject();
473
474     ENCODE_TYPE_WITH_KEY(encodedData, String, name, input.name);
475     ENCODE_TYPE_WITH_KEY(encodedData, String, file, input.file);
476     ENCODE_TYPE_WITH_KEY(encodedData, String, desc, input.desc);
477     ENCODE_TYPE_WITH_KEY(encodedData, Vector<MimeClassInfo>, mimes, input.mimes);
478     ENCODE_TYPE_WITH_KEY(encodedData, bool, isApplicationPlugin, input.isApplicationPlugin);
479     ENCODE_TYPE_WITH_KEY(encodedData, PluginLoadClientPolicy, clientLoadPolicy, static_cast<PluginLoadClientPolicy>(input.clientLoadPolicy));
480 #if PLATFORM(MAC)
481     ENCODE_TYPE_WITH_KEY(encodedData, String, bundleIdentifier, input.bundleIdentifier);
482     ENCODE_TYPE_WITH_KEY(encodedData, String, versionString, input.versionString);
483 #endif
484
485     return encodedData;
486 }
487
488 template<>
489 bool EncodingTraits<PluginInfo>::decodeValue(EncodedValue& encodedData, PluginInfo& input)
490 {
491     PluginInfo info;
492
493     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, name, info.name);
494     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, file, info.file);
495     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, desc, info.desc);
496     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, Vector<MimeClassInfo>, mimes, info.mimes);
497     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, bool, isApplicationPlugin, info.isApplicationPlugin);
498     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, PluginLoadClientPolicy, clientLoadPolicy, info.clientLoadPolicy);
499 #if PLATFORM(MAC)
500     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, bundleIdentifier, input.bundleIdentifier);
501     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, versionString, input.versionString);
502 #endif
503
504     input = info;
505     return true;
506 }
507
508 EncodedValue EncodingTraits<SecurityOrigin>::encodeValue(RefPtr<SecurityOrigin> input)
509 {
510     return EncodedValue::createString(input->toString());
511 }
512
513 bool EncodingTraits<SecurityOrigin>::decodeValue(EncodedValue& encodedValue, RefPtr<SecurityOrigin>& input)
514 {
515     input = SecurityOrigin::createFromString(encodedValue.convertTo<String>());
516     return true;
517 }
518
519 EncodedValue EncodingTraits<URL>::encodeValue(const URL& input)
520 {
521     return EncodedValue::createString(input.string());
522 }
523
524 bool EncodingTraits<URL>::decodeValue(EncodedValue& encodedValue, URL& input)
525 {
526     input = URL(WebCore::ParsedURLString, encodedValue.convertTo<String>());
527     return true;
528 }
529
530 } // namespace JSC
531
532 #endif // ENABLE(WEB_REPLAY)