Add WTF::move()
[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 "ReplayInputTypes.h"
44 #include "SecurityOrigin.h"
45 #include "URL.h"
46 #include <wtf/text/Base64.h>
47
48 using WebCore::IntPoint;
49 using WebCore::MimeClassInfo;
50 using WebCore::MouseButton;
51 using WebCore::PlatformEvent;
52 using WebCore::PlatformKeyboardEvent;
53 using WebCore::PlatformMouseEvent;
54 using WebCore::PlatformWheelEvent;
55 using WebCore::PlatformWheelEventGranularity;
56 using WebCore::PluginData;
57 using WebCore::PluginInfo;
58 using WebCore::SecurityOrigin;
59 using WebCore::URL;
60 using WebCore::inputTypes;
61
62 #if PLATFORM(COCOA)
63 using WebCore::KeypressCommand;
64 using WebCore::PlatformWheelEventPhase;
65 #endif
66
67 #define IMPORT_FROM_WEBCORE_NAMESPACE(name) \
68 using WebCore::name; \
69
70 WEB_REPLAY_INPUT_NAMES_FOR_EACH(IMPORT_FROM_WEBCORE_NAMESPACE)
71 #undef IMPORT_FROM_WEBCORE_NAMESPACE
72
73 namespace WebCore {
74
75 unsigned long frameIndexFromDocument(const Document* document)
76 {
77     ASSERT(document);
78     ASSERT(document->frame());
79     return frameIndexFromFrame(document->frame());
80 }
81
82 unsigned long frameIndexFromFrame(const Frame* targetFrame)
83 {
84     ASSERT(targetFrame);
85
86     unsigned long currentIndex = 0;
87     const Frame* mainFrame = &targetFrame->tree().top();
88     for (const Frame* frame = mainFrame; frame; ++currentIndex, frame = frame->tree().traverseNext(mainFrame)) {
89         if (frame == targetFrame)
90             return currentIndex;
91     }
92
93     ASSERT_NOT_REACHED();
94     return 0;
95 }
96
97 Document* documentFromFrameIndex(Page* page, unsigned long frameIndex)
98 {
99     Frame* frame = frameFromFrameIndex(page, frameIndex);
100     return frame ? frame->document() : nullptr;
101 }
102
103 Frame* frameFromFrameIndex(Page* page, unsigned long frameIndex)
104 {
105     ASSERT(page);
106     ASSERT(frameIndex >= 0);
107
108     MainFrame* mainFrame = &page->mainFrame();
109     Frame* frame = mainFrame;
110     unsigned long currentIndex = 0;
111     for (; currentIndex < frameIndex && frame; ++currentIndex, frame = frame->tree().traverseNext(mainFrame)) { }
112
113     return frame;
114 }
115
116 } // namespace WebCore
117
118 #define ENCODE_TYPE_WITH_KEY(_encodedValue, _type, _key, _value) \
119     _encodedValue.put<_type>(ASCIILiteral(#_key), _value)
120
121 #define ENCODE_OPTIONAL_TYPE_WITH_KEY(_encodedValue, _type, _key, _value, condition) \
122     if (condition) \
123         ENCODE_TYPE_WITH_KEY(_encodedValue, _type, _key, _value)
124
125 #define DECODE_TYPE_WITH_KEY_TO_LVALUE(_encodedValue, _type, _key, _lvalue) \
126     if (!_encodedValue.get<_type>(ASCIILiteral(#_key), _lvalue)) \
127         return false
128
129 #define DECODE_TYPE_WITH_KEY(_encodedValue, _type, _key) \
130     EncodingTraits<_type>::DecodedType _key; \
131     DECODE_TYPE_WITH_KEY_TO_LVALUE(_encodedValue, _type, _key, _key)
132
133 #define DECODE_OPTIONAL_TYPE_WITH_KEY_TO_LVALUE(_encodedValue, _type, _key, _lvalue) \
134     bool _key ## WasDecoded = _encodedValue.get<_type>(ASCIILiteral(#_key), _lvalue)
135
136 #define DECODE_OPTIONAL_TYPE_WITH_KEY(_encodedValue, _type, _key) \
137     EncodingTraits<_type>::DecodedType _key; \
138     DECODE_OPTIONAL_TYPE_WITH_KEY_TO_LVALUE(_encodedValue, _type, _key, _key)
139
140 namespace JSC {
141
142 template<>
143 EncodedValue EncodingTraits<MimeClassInfo>::encodeValue(const MimeClassInfo& input)
144 {
145     EncodedValue encodedData = EncodedValue::createObject();
146
147     ENCODE_TYPE_WITH_KEY(encodedData, String, type, input.type);
148     ENCODE_TYPE_WITH_KEY(encodedData, String, desc, input.desc);
149     ENCODE_TYPE_WITH_KEY(encodedData, Vector<String>, extensions, input.extensions);
150
151     return encodedData;
152 }
153
154 template<>
155 bool EncodingTraits<MimeClassInfo>::decodeValue(EncodedValue& encodedData, MimeClassInfo& input)
156 {
157     MimeClassInfo info;
158
159     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, type, info.type);
160     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, String, desc, info.desc);
161     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, Vector<String>, extensions, info.extensions);
162
163     input = info;
164     return true;
165 }
166
167 EncodedValue EncodingTraits<NondeterministicInputBase>::encodeValue(const NondeterministicInputBase& input)
168 {
169     EncodedValue encodedValue = EncodedValue::createObject();
170     const AtomicString& type = input.type();
171
172     ENCODE_TYPE_WITH_KEY(encodedValue, String, type, type.string());
173
174 #define ENCODE_IF_TYPE_TAG_MATCHES(name) \
175     if (type == inputTypes().name) { \
176         InputTraits<name>::encode(encodedValue, static_cast<const name&>(input)); \
177         return encodedValue; \
178     } \
179
180     JS_REPLAY_INPUT_NAMES_FOR_EACH(ENCODE_IF_TYPE_TAG_MATCHES)
181     WEB_REPLAY_INPUT_NAMES_FOR_EACH(ENCODE_IF_TYPE_TAG_MATCHES)
182 #undef ENCODE_IF_TYPE_TAG_MATCHES
183
184     // The macro won't work here because of the class template argument.
185     if (type == inputTypes().MemoizedDOMResult) {
186         InputTraits<MemoizedDOMResultBase>::encode(encodedValue, static_cast<const MemoizedDOMResultBase&>(input));
187         return encodedValue;
188     }
189
190     ASSERT_NOT_REACHED();
191     return EncodedValue();
192 }
193
194 bool EncodingTraits<NondeterministicInputBase>::decodeValue(EncodedValue& encodedValue, std::unique_ptr<NondeterministicInputBase>& input)
195 {
196     DECODE_TYPE_WITH_KEY(encodedValue, String, type);
197
198 #define DECODE_IF_TYPE_TAG_MATCHES(name) \
199     if (type == inputTypes().name) { \
200         std::unique_ptr<name> decodedInput; \
201         if (!InputTraits<name>::decode(encodedValue, decodedInput)) \
202             return false; \
203         \
204         input = WTF::move(decodedInput); \
205         return true; \
206     } \
207
208     JS_REPLAY_INPUT_NAMES_FOR_EACH(DECODE_IF_TYPE_TAG_MATCHES)
209     WEB_REPLAY_INPUT_NAMES_FOR_EACH(DECODE_IF_TYPE_TAG_MATCHES)
210 #undef DECODE_IF_TYPE_TAG_MATCHES
211
212     if (type == inputTypes().MemoizedDOMResult) {
213         std::unique_ptr<MemoizedDOMResultBase> decodedInput;
214         if (!InputTraits<MemoizedDOMResultBase>::decode(encodedValue, decodedInput))
215             return false;
216
217         input = WTF::move(decodedInput);
218         return true;
219     }
220
221     return false;
222 }
223
224 #if USE(APPKIT)
225 EncodedValue EncodingTraits<KeypressCommand>::encodeValue(const KeypressCommand& command)
226 {
227     EncodedValue encodedValue = EncodedValue::createObject();
228
229     ENCODE_TYPE_WITH_KEY(encodedValue, String, commandName, command.commandName);
230     ENCODE_OPTIONAL_TYPE_WITH_KEY(encodedValue, String, text, command.text, !command.text.isEmpty());
231
232     return encodedValue;
233 }
234
235 bool EncodingTraits<KeypressCommand>::decodeValue(EncodedValue& encodedValue, KeypressCommand& decodedValue)
236 {
237     DECODE_TYPE_WITH_KEY(encodedValue, String, commandName);
238     DECODE_OPTIONAL_TYPE_WITH_KEY(encodedValue, String, text);
239
240     decodedValue = textWasDecoded ? KeypressCommand(commandName, text) : KeypressCommand(commandName);
241     return true;
242 }
243
244 class PlatformKeyboardEventAppKit : public WebCore::PlatformKeyboardEvent {
245 public:
246     PlatformKeyboardEventAppKit(const PlatformKeyboardEvent& event, bool handledByInputMethod, Vector<KeypressCommand>& commands)
247         : PlatformKeyboardEvent(event)
248     {
249         m_handledByInputMethod = handledByInputMethod;
250         m_commands = commands;
251     }
252 };
253 #endif // USE(APPKIT)
254
255 EncodedValue EncodingTraits<PlatformKeyboardEvent>::encodeValue(const PlatformKeyboardEvent& input)
256 {
257     EncodedValue encodedValue = EncodedValue::createObject();
258
259     ENCODE_TYPE_WITH_KEY(encodedValue, double, timestamp, input.timestamp());
260     ENCODE_TYPE_WITH_KEY(encodedValue, PlatformEvent::Type, type, input.type());
261     ENCODE_TYPE_WITH_KEY(encodedValue, PlatformEvent::Modifiers, modifiers, static_cast<PlatformEvent::Modifiers>(input.modifiers()));
262     ENCODE_TYPE_WITH_KEY(encodedValue, String, text, input.text());
263     ENCODE_TYPE_WITH_KEY(encodedValue, String, unmodifiedText, input.unmodifiedText());
264     ENCODE_TYPE_WITH_KEY(encodedValue, String, keyIdentifier, input.keyIdentifier());
265     ENCODE_TYPE_WITH_KEY(encodedValue, int, windowsVirtualKeyCode, input.windowsVirtualKeyCode());
266     ENCODE_TYPE_WITH_KEY(encodedValue, int, nativeVirtualKeyCode, input.nativeVirtualKeyCode());
267     ENCODE_TYPE_WITH_KEY(encodedValue, int, macCharCode, input.macCharCode());
268     ENCODE_TYPE_WITH_KEY(encodedValue, bool, autoRepeat, input.isAutoRepeat());
269     ENCODE_TYPE_WITH_KEY(encodedValue, bool, keypad, input.isKeypad());
270     ENCODE_TYPE_WITH_KEY(encodedValue, bool, systemKey, input.isSystemKey());
271 #if USE(APPKIT)
272     ENCODE_TYPE_WITH_KEY(encodedValue, bool, handledByInputMethod, input.handledByInputMethod());
273     ENCODE_TYPE_WITH_KEY(encodedValue, Vector<KeypressCommand>, commands, input.commands());
274 #endif
275     return encodedValue;
276 }
277
278 bool EncodingTraits<PlatformKeyboardEvent>::decodeValue(EncodedValue& encodedValue, std::unique_ptr<PlatformKeyboardEvent>& input)
279 {
280     DECODE_TYPE_WITH_KEY(encodedValue, double, timestamp);
281     DECODE_TYPE_WITH_KEY(encodedValue, PlatformEvent::Type, type);
282     DECODE_TYPE_WITH_KEY(encodedValue, PlatformEvent::Modifiers, modifiers);
283     DECODE_TYPE_WITH_KEY(encodedValue, String, text);
284     DECODE_TYPE_WITH_KEY(encodedValue, String, unmodifiedText);
285     DECODE_TYPE_WITH_KEY(encodedValue, String, keyIdentifier);
286     DECODE_TYPE_WITH_KEY(encodedValue, int, windowsVirtualKeyCode);
287     DECODE_TYPE_WITH_KEY(encodedValue, int, nativeVirtualKeyCode);
288     DECODE_TYPE_WITH_KEY(encodedValue, int, macCharCode);
289     DECODE_TYPE_WITH_KEY(encodedValue, bool, autoRepeat);
290     DECODE_TYPE_WITH_KEY(encodedValue, bool, keypad);
291     DECODE_TYPE_WITH_KEY(encodedValue, bool, systemKey);
292 #if USE(APPKIT)
293     DECODE_TYPE_WITH_KEY(encodedValue, bool, handledByInputMethod);
294     DECODE_TYPE_WITH_KEY(encodedValue, Vector<KeypressCommand>, commands);
295 #endif
296
297     PlatformKeyboardEvent platformEvent = PlatformKeyboardEvent(type, text, unmodifiedText, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, macCharCode, autoRepeat, keypad, systemKey, modifiers, timestamp);
298 #if USE(APPKIT)
299     input = std::make_unique<PlatformKeyboardEventAppKit>(platformEvent, handledByInputMethod, commands);
300 #else
301     input = std::make_unique<PlatformKeyboardEvent>(platformEvent);
302 #endif
303     return true;
304 }
305
306 EncodedValue EncodingTraits<PlatformMouseEvent>::encodeValue(const PlatformMouseEvent& input)
307 {
308     EncodedValue encodedValue = EncodedValue::createObject();
309
310     ENCODE_TYPE_WITH_KEY(encodedValue, int, positionX, input.position().x());
311     ENCODE_TYPE_WITH_KEY(encodedValue, int, positionY, input.position().y());
312     ENCODE_TYPE_WITH_KEY(encodedValue, int, globalPositionX, input.globalPosition().x());
313     ENCODE_TYPE_WITH_KEY(encodedValue, int, globalPositionY, input.globalPosition().y());
314     ENCODE_TYPE_WITH_KEY(encodedValue, MouseButton, button, input.button());
315     ENCODE_TYPE_WITH_KEY(encodedValue, PlatformEvent::Type, type, input.type());
316     ENCODE_TYPE_WITH_KEY(encodedValue, int, clickCount, input.clickCount());
317     ENCODE_TYPE_WITH_KEY(encodedValue, bool, shiftKey, input.shiftKey());
318     ENCODE_TYPE_WITH_KEY(encodedValue, bool, ctrlKey, input.ctrlKey());
319     ENCODE_TYPE_WITH_KEY(encodedValue, bool, altKey, input.altKey());
320     ENCODE_TYPE_WITH_KEY(encodedValue, bool, metaKey, input.metaKey());
321     ENCODE_TYPE_WITH_KEY(encodedValue, int, timestamp, input.timestamp());
322
323     return encodedValue;
324 }
325
326 bool EncodingTraits<PlatformMouseEvent>::decodeValue(EncodedValue& encodedValue, std::unique_ptr<PlatformMouseEvent>& input)
327 {
328     DECODE_TYPE_WITH_KEY(encodedValue, int, positionX);
329     DECODE_TYPE_WITH_KEY(encodedValue, int, positionY);
330     DECODE_TYPE_WITH_KEY(encodedValue, int, globalPositionX);
331     DECODE_TYPE_WITH_KEY(encodedValue, int, globalPositionY);
332     DECODE_TYPE_WITH_KEY(encodedValue, MouseButton, button);
333     DECODE_TYPE_WITH_KEY(encodedValue, PlatformEvent::Type, type);
334     DECODE_TYPE_WITH_KEY(encodedValue, int, clickCount);
335     DECODE_TYPE_WITH_KEY(encodedValue, bool, shiftKey);
336     DECODE_TYPE_WITH_KEY(encodedValue, bool, ctrlKey);
337     DECODE_TYPE_WITH_KEY(encodedValue, bool, altKey);
338     DECODE_TYPE_WITH_KEY(encodedValue, bool, metaKey);
339     DECODE_TYPE_WITH_KEY(encodedValue, int, timestamp);
340
341     input = std::make_unique<PlatformMouseEvent>(IntPoint(positionX, positionY),
342         IntPoint(globalPositionX, globalPositionY),
343         button, type, clickCount,
344         shiftKey, ctrlKey, altKey, metaKey, timestamp);
345     return true;
346 }
347
348 #if PLATFORM(COCOA)
349 struct PlatformWheelEventCocoaArguments {
350     bool directionInvertedFromDevice;
351     bool hasPreciseScrollingDeltas;
352     PlatformWheelEventPhase phase;
353     PlatformWheelEventPhase momentumPhase;
354     int scrollCount;
355     float unacceleratedScrollingDeltaX;
356     float unacceleratedScrollingDeltaY;
357 };
358
359 class PlatformWheelEventCocoa : public PlatformWheelEvent {
360 public:
361     PlatformWheelEventCocoa(PlatformWheelEvent& event, PlatformWheelEventCocoaArguments& arguments)
362         : PlatformWheelEvent(event)
363     {
364         m_directionInvertedFromDevice = arguments.directionInvertedFromDevice;
365         m_hasPreciseScrollingDeltas = arguments.hasPreciseScrollingDeltas;
366         m_phase = arguments.phase;
367         m_momentumPhase = arguments.momentumPhase;
368         m_scrollCount = arguments.scrollCount;
369         m_unacceleratedScrollingDeltaX = arguments.unacceleratedScrollingDeltaX;
370         m_unacceleratedScrollingDeltaY = arguments.unacceleratedScrollingDeltaY;
371     }
372 };
373 #endif // PLATFORM(COCOA)
374
375 EncodedValue EncodingTraits<PlatformWheelEvent>::encodeValue(const PlatformWheelEvent& input)
376 {
377     EncodedValue encodedData = EncodedValue::createObject();
378
379     ENCODE_TYPE_WITH_KEY(encodedData, int, positionX, input.position().x());
380     ENCODE_TYPE_WITH_KEY(encodedData, int, positionY, input.position().y());
381     ENCODE_TYPE_WITH_KEY(encodedData, int, globalPositionX, input.globalPosition().x());
382     ENCODE_TYPE_WITH_KEY(encodedData, int, globalPositionY, input.globalPosition().y());
383     ENCODE_TYPE_WITH_KEY(encodedData, bool, shiftKey, input.shiftKey());
384     ENCODE_TYPE_WITH_KEY(encodedData, bool, ctrlKey, input.ctrlKey());
385     ENCODE_TYPE_WITH_KEY(encodedData, bool, altKey, input.altKey());
386     ENCODE_TYPE_WITH_KEY(encodedData, bool, metaKey, input.metaKey());
387     ENCODE_TYPE_WITH_KEY(encodedData, float, deltaX, input.deltaX());
388     ENCODE_TYPE_WITH_KEY(encodedData, float, deltaY, input.deltaY());
389     ENCODE_TYPE_WITH_KEY(encodedData, float, wheelTicksX, input.wheelTicksX());
390     ENCODE_TYPE_WITH_KEY(encodedData, float, wheelTicksY, input.wheelTicksY());
391     ENCODE_TYPE_WITH_KEY(encodedData, PlatformWheelEventGranularity, granularity, static_cast<PlatformWheelEventGranularity>(input.granularity()));
392
393 #if PLATFORM(COCOA)
394     ENCODE_TYPE_WITH_KEY(encodedData, bool, directionInvertedFromDevice, input.directionInvertedFromDevice());
395     ENCODE_TYPE_WITH_KEY(encodedData, bool, hasPreciseScrollingDeltas, input.hasPreciseScrollingDeltas());
396     ENCODE_TYPE_WITH_KEY(encodedData, PlatformWheelEventPhase, phase, static_cast<PlatformWheelEventPhase>(input.phase()));
397     ENCODE_TYPE_WITH_KEY(encodedData, PlatformWheelEventPhase, momentumPhase, static_cast<PlatformWheelEventPhase>(input.momentumPhase()));
398     ENCODE_TYPE_WITH_KEY(encodedData, int, scrollCount, input.scrollCount());
399     ENCODE_TYPE_WITH_KEY(encodedData, float, unacceleratedScrollingDeltaX, input.unacceleratedScrollingDeltaX());
400     ENCODE_TYPE_WITH_KEY(encodedData, float, unacceleratedScrollingDeltaY, input.unacceleratedScrollingDeltaY());
401 #endif
402
403     return encodedData;
404 }
405
406 bool EncodingTraits<PlatformWheelEvent>::decodeValue(EncodedValue& encodedData, std::unique_ptr<PlatformWheelEvent>& input)
407 {
408     DECODE_TYPE_WITH_KEY(encodedData, int, positionX);
409     DECODE_TYPE_WITH_KEY(encodedData, int, positionY);
410     DECODE_TYPE_WITH_KEY(encodedData, int, globalPositionX);
411     DECODE_TYPE_WITH_KEY(encodedData, int, globalPositionY);
412     DECODE_TYPE_WITH_KEY(encodedData, bool, shiftKey);
413     DECODE_TYPE_WITH_KEY(encodedData, bool, ctrlKey);
414     DECODE_TYPE_WITH_KEY(encodedData, bool, altKey);
415     DECODE_TYPE_WITH_KEY(encodedData, bool, metaKey);
416     DECODE_TYPE_WITH_KEY(encodedData, float, deltaX);
417     DECODE_TYPE_WITH_KEY(encodedData, float, deltaY);
418     DECODE_TYPE_WITH_KEY(encodedData, float, wheelTicksX);
419     DECODE_TYPE_WITH_KEY(encodedData, float, wheelTicksY);
420     DECODE_TYPE_WITH_KEY(encodedData, PlatformWheelEventGranularity, granularity);
421
422 #if PLATFORM(COCOA)
423     PlatformWheelEventCocoaArguments arguments;
424     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, bool, directionInvertedFromDevice, arguments.directionInvertedFromDevice);
425     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, bool, hasPreciseScrollingDeltas, arguments.hasPreciseScrollingDeltas);
426     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, PlatformWheelEventPhase, phase, arguments.phase);
427     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, PlatformWheelEventPhase, momentumPhase, arguments.momentumPhase);
428     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, int, scrollCount, arguments.scrollCount);
429     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, float, unacceleratedScrollingDeltaX, arguments.unacceleratedScrollingDeltaX);
430     DECODE_TYPE_WITH_KEY_TO_LVALUE(encodedData, float, unacceleratedScrollingDeltaY, arguments.unacceleratedScrollingDeltaY);
431 #endif
432
433     PlatformWheelEvent event(IntPoint(positionX, positionY), IntPoint(globalPositionX, globalPositionY),
434         deltaX, deltaY, wheelTicksX, wheelTicksY, granularity, shiftKey, ctrlKey, altKey, metaKey);
435
436 #if PLATFORM(COCOA)
437     input = std::make_unique<PlatformWheelEventCocoa>(event, arguments);
438 #else
439     input = std::make_unique<PlatformWheelEvent>(event);
440 #endif
441     return true;
442 }
443
444 EncodedValue EncodingTraits<PluginData>::encodeValue(RefPtr<PluginData> input)
445 {
446     EncodedValue encodedData = EncodedValue::createObject();
447
448     ENCODE_TYPE_WITH_KEY(encodedData, Vector<PluginInfo>, plugins, input->plugins());
449     ENCODE_TYPE_WITH_KEY(encodedData, Vector<MimeClassInfo>, mimes, input->mimes());
450     ENCODE_TYPE_WITH_KEY(encodedData, Vector<size_t>, mimePluginIndices, input->mimePluginIndices());
451
452     return encodedData;
453 }
454
455 class DeserializedPluginData : public PluginData {
456 public:
457     DeserializedPluginData(Vector<PluginInfo> plugins, Vector<MimeClassInfo> mimes, Vector<size_t> indices)
458         : PluginData(plugins, mimes, indices)
459     {
460     }
461 };
462
463 bool EncodingTraits<PluginData>::decodeValue(EncodedValue& encodedData, RefPtr<PluginData>& input)
464 {
465     DECODE_TYPE_WITH_KEY(encodedData, Vector<PluginInfo>, plugins);
466     DECODE_TYPE_WITH_KEY(encodedData, Vector<MimeClassInfo>, mimes);
467     DECODE_TYPE_WITH_KEY(encodedData, Vector<size_t>, mimePluginIndices);
468
469     input = adoptRef(new DeserializedPluginData(plugins, mimes, mimePluginIndices));
470
471     return true;
472 }
473
474 template<>
475 EncodedValue EncodingTraits<PluginInfo>::encodeValue(const PluginInfo& input)
476 {
477     EncodedValue encodedData = EncodedValue::createObject();
478
479     ENCODE_TYPE_WITH_KEY(encodedData, String, name, input.name);
480     ENCODE_TYPE_WITH_KEY(encodedData, String, file, input.file);
481     ENCODE_TYPE_WITH_KEY(encodedData, String, desc, input.desc);
482     ENCODE_TYPE_WITH_KEY(encodedData, Vector<MimeClassInfo>, mimes, input.mimes);
483     ENCODE_TYPE_WITH_KEY(encodedData, bool, isApplicationPlugin, input.isApplicationPlugin);
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
499     input = info;
500     return true;
501 }
502
503 EncodedValue EncodingTraits<SecurityOrigin>::encodeValue(RefPtr<SecurityOrigin> input)
504 {
505     return EncodedValue::createString(input->toString());
506 }
507
508 bool EncodingTraits<SecurityOrigin>::decodeValue(EncodedValue& encodedValue, RefPtr<SecurityOrigin>& input)
509 {
510     input = SecurityOrigin::createFromString(encodedValue.convertTo<String>());
511     return true;
512 }
513
514 EncodedValue EncodingTraits<URL>::encodeValue(const URL& input)
515 {
516     return EncodedValue::createString(input.string());
517 }
518
519 bool EncodingTraits<URL>::decodeValue(EncodedValue& encodedValue, URL& input)
520 {
521     input = URL(WebCore::ParsedURLString, encodedValue.convertTo<String>());
522     return true;
523 }
524
525 } // namespace JSC
526
527 #endif // ENABLE(WEB_REPLAY)