Add completion handlers to TestRunner functions setStatisticsLastSeen(), setStatistic...
[WebKit-https.git] / Tools / WebKitTestRunner / InjectedBundle / EventSendingController.cpp
1 /*
2  * Copyright (C) 2010, 2011, 2014-2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "EventSendingController.h"
28
29 #include "InjectedBundle.h"
30 #include "InjectedBundlePage.h"
31 #include "JSEventSendingController.h"
32 #include "StringFunctions.h"
33 #include <WebKit/WKBundle.h>
34 #include <WebKit/WKBundleFrame.h>
35 #include <WebKit/WKBundlePagePrivate.h>
36 #include <WebKit/WKBundlePrivate.h>
37 #include <WebKit/WKContextMenuItem.h>
38 #include <WebKit/WKMutableDictionary.h>
39 #include <WebKit/WKNumber.h>
40 #include <wtf/StdLibExtras.h>
41
42 namespace WTR {
43
44 static const float ZoomMultiplierRatio = 1.2f;
45
46 struct MenuItemPrivateData {
47     MenuItemPrivateData(WKBundlePageRef page, WKContextMenuItemRef item) :
48         m_page(page),
49         m_item(item) { }
50     WKBundlePageRef m_page;
51     WKRetainPtr<WKContextMenuItemRef> m_item;
52 };
53
54 #if ENABLE(CONTEXT_MENUS)
55 static JSValueRef menuItemClickCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*)
56 {
57     MenuItemPrivateData* privateData = static_cast<MenuItemPrivateData*>(JSObjectGetPrivate(thisObject));
58     WKBundlePageClickMenuItem(privateData->m_page, privateData->m_item.get());
59     return JSValueMakeUndefined(context);
60 }
61
62 static JSValueRef getMenuItemTitleCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
63 {
64     MenuItemPrivateData* privateData = static_cast<MenuItemPrivateData*>(JSObjectGetPrivate(object));
65     WKRetainPtr<WKStringRef> wkTitle(AdoptWK, WKContextMenuItemCopyTitle(privateData->m_item.get()));
66     return JSValueMakeString(context, toJS(wkTitle).get());
67 }
68
69 static JSStaticFunction staticMenuItemFunctions[] = {
70     { "click", menuItemClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
71     { 0, 0, 0 }
72 };
73
74 static JSStaticValue staticMenuItemValues[] = {
75     { "title", getMenuItemTitleCallback, 0, kJSPropertyAttributeReadOnly },
76     { 0, 0, 0, 0 }
77 };
78
79 static void staticMenuItemFinalize(JSObjectRef object)
80 {
81     delete static_cast<MenuItemPrivateData*>(JSObjectGetPrivate(object));
82 }
83
84 static JSValueRef staticConvertMenuItemToType(JSContextRef context, JSObjectRef object, JSType type, JSValueRef*)
85 {
86     if (kJSTypeString == type)
87         return getMenuItemTitleCallback(context, object, 0, 0);
88     return 0;
89 }
90
91 static JSClassRef getMenuItemClass()
92 {
93     static JSClassRef menuItemClass = 0;
94
95     if (!menuItemClass) {
96         JSClassDefinition classDefinition = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
97         classDefinition.staticFunctions = staticMenuItemFunctions;
98         classDefinition.staticValues = staticMenuItemValues;
99         classDefinition.finalize = staticMenuItemFinalize;
100         classDefinition.convertToType = staticConvertMenuItemToType;
101
102         menuItemClass = JSClassCreate(&classDefinition);
103     }
104
105     return menuItemClass;
106 }
107 #endif
108
109 static WKEventModifiers parseModifier(JSStringRef modifier)
110 {
111     if (JSStringIsEqualToUTF8CString(modifier, "ctrlKey"))
112         return kWKEventModifiersControlKey;
113     if (JSStringIsEqualToUTF8CString(modifier, "shiftKey") || JSStringIsEqualToUTF8CString(modifier, "rangeSelectionKey"))
114         return kWKEventModifiersShiftKey;
115     if (JSStringIsEqualToUTF8CString(modifier, "altKey"))
116         return kWKEventModifiersAltKey;
117     if (JSStringIsEqualToUTF8CString(modifier, "metaKey"))
118         return kWKEventModifiersMetaKey;
119     if (JSStringIsEqualToUTF8CString(modifier, "capsLockKey"))
120         return kWKEventModifiersCapsLockKey;
121     if (JSStringIsEqualToUTF8CString(modifier, "addSelectionKey")) {
122 #if OS(MAC_OS_X)
123         return kWKEventModifiersMetaKey;
124 #else
125         return kWKEventModifiersControlKey;
126 #endif
127     }
128     return 0;
129 }
130
131 static unsigned arrayLength(JSContextRef context, JSObjectRef array)
132 {
133     JSRetainPtr<JSStringRef> lengthString(Adopt, JSStringCreateWithUTF8CString("length"));
134     JSValueRef lengthValue = JSObjectGetProperty(context, array, lengthString.get(), 0);
135     if (!lengthValue)
136         return 0;
137     return static_cast<unsigned>(JSValueToNumber(context, lengthValue, 0));
138 }
139
140 static WKEventModifiers parseModifierArray(JSContextRef context, JSValueRef arrayValue)
141 {
142     if (!arrayValue)
143         return 0;
144
145     // The value may either be a string with a single modifier or an array of modifiers.
146     if (JSValueIsString(context, arrayValue)) {
147         JSRetainPtr<JSStringRef> string(Adopt, JSValueToStringCopy(context, arrayValue, 0));
148         return parseModifier(string.get());
149     }
150
151     if (!JSValueIsObject(context, arrayValue))
152         return 0;
153     JSObjectRef array = const_cast<JSObjectRef>(arrayValue);
154     unsigned length = arrayLength(context, array);
155     WKEventModifiers modifiers = 0;
156     for (unsigned i = 0; i < length; i++) {
157         JSValueRef exception = 0;
158         JSValueRef value = JSObjectGetPropertyAtIndex(context, array, i, &exception);
159         if (exception)
160             continue;
161         JSRetainPtr<JSStringRef> string(Adopt, JSValueToStringCopy(context, value, &exception));
162         if (exception)
163             continue;
164         modifiers |= parseModifier(string.get());
165     }
166     return modifiers;
167 }
168
169 Ref<EventSendingController> EventSendingController::create()
170 {
171     return adoptRef(*new EventSendingController);
172 }
173
174 EventSendingController::EventSendingController()
175 {
176 }
177
178 EventSendingController::~EventSendingController()
179 {
180 }
181
182 JSClassRef EventSendingController::wrapperClass()
183 {
184     return JSEventSendingController::eventSendingControllerClass();
185 }
186
187 enum MouseState {
188     MouseUp,
189     MouseDown
190 };
191
192 static WKMutableDictionaryRef createMouseMessageBody(MouseState state, int button, WKEventModifiers modifiers)
193 {
194     WKMutableDictionaryRef EventSenderMessageBody = WKMutableDictionaryCreate();
195
196     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
197     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString(state == MouseUp ? "MouseUp" : "MouseDown"));
198     WKDictionarySetItem(EventSenderMessageBody, subMessageKey.get(), subMessageName.get());
199
200     WKRetainPtr<WKStringRef> buttonKey = adoptWK(WKStringCreateWithUTF8CString("Button"));
201     WKRetainPtr<WKUInt64Ref> buttonRef = adoptWK(WKUInt64Create(button));
202     WKDictionarySetItem(EventSenderMessageBody, buttonKey.get(), buttonRef.get());
203
204     WKRetainPtr<WKStringRef> modifiersKey = adoptWK(WKStringCreateWithUTF8CString("Modifiers"));
205     WKRetainPtr<WKUInt64Ref> modifiersRef = adoptWK(WKUInt64Create(modifiers));
206     WKDictionarySetItem(EventSenderMessageBody, modifiersKey.get(), modifiersRef.get());
207
208     return EventSenderMessageBody;
209 }
210
211 void EventSendingController::mouseDown(int button, JSValueRef modifierArray) 
212 {
213     auto& injectedBundle = InjectedBundle::singleton();
214     WKBundlePageRef page = injectedBundle.page()->page();
215     WKBundleFrameRef frame = WKBundlePageGetMainFrame(page);
216     JSContextRef context = WKBundleFrameGetJavaScriptContext(frame);
217     WKEventModifiers modifiers = parseModifierArray(context, modifierArray);
218
219     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
220     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, createMouseMessageBody(MouseDown, button, modifiers));
221
222     WKBundlePagePostSynchronousMessageForTesting(page, EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
223 }
224
225 void EventSendingController::mouseUp(int button, JSValueRef modifierArray)
226 {
227     WKBundlePageRef page = InjectedBundle::singleton().page()->page();
228     WKBundleFrameRef frame = WKBundlePageGetMainFrame(page);
229     JSContextRef context = WKBundleFrameGetJavaScriptContext(frame);
230     WKEventModifiers modifiers = parseModifierArray(context, modifierArray);
231
232     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
233     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, createMouseMessageBody(MouseUp, button, modifiers));
234
235     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
236 }
237
238 void EventSendingController::mouseMoveTo(int x, int y)
239 {
240     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
241     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
242
243     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
244     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseMoveTo"));
245     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
246
247     WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
248     WKRetainPtr<WKDoubleRef> xRef(AdoptWK, WKDoubleCreate(x));
249     WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
250
251     WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
252     WKRetainPtr<WKDoubleRef> yRef(AdoptWK, WKDoubleCreate(y));
253     WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
254
255     m_position = WKPointMake(x, y);
256     
257     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
258 }
259
260 void EventSendingController::mouseForceClick()
261 {
262     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
263     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
264
265     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
266     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseForceClick"));
267     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
268
269     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
270 }
271
272 void EventSendingController::startAndCancelMouseForceClick()
273 {
274     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
275     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
276
277     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
278     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("StartAndCancelMouseForceClick"));
279     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
280
281     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
282 }
283
284 void EventSendingController::mouseForceDown()
285 {
286     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
287     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
288
289     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
290     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseForceDown"));
291     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
292
293     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
294 }
295
296 void EventSendingController::mouseForceUp()
297 {
298     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
299     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
300
301     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
302     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseForceUp"));
303     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
304
305     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
306 }
307
308 void EventSendingController::mouseForceChanged(double force)
309 {
310     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
311     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
312
313     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
314     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseForceChanged"));
315     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
316
317     WKRetainPtr<WKStringRef> forceKey(AdoptWK, WKStringCreateWithUTF8CString("Force"));
318     WKRetainPtr<WKDoubleRef> forceRef(AdoptWK, WKDoubleCreate(force));
319     WKDictionarySetItem(EventSenderMessageBody.get(), forceKey.get(), forceRef.get());
320
321     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
322 }
323
324 void EventSendingController::leapForward(int milliseconds)
325 {
326     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
327     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
328
329     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
330     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("LeapForward"));
331     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
332
333     WKRetainPtr<WKStringRef> timeKey(AdoptWK, WKStringCreateWithUTF8CString("TimeInMilliseconds"));
334     WKRetainPtr<WKUInt64Ref> timeRef(AdoptWK, WKUInt64Create(milliseconds));
335     WKDictionarySetItem(EventSenderMessageBody.get(), timeKey.get(), timeRef.get());
336
337     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
338 }
339
340 void EventSendingController::scheduleAsynchronousClick()
341 {
342     WKEventModifiers modifiers = 0;
343     int button = 0;
344
345     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
346
347     // Asynchronous mouse down.
348     WKRetainPtr<WKMutableDictionaryRef> mouseDownMessageBody(AdoptWK, createMouseMessageBody(MouseDown, button, modifiers));
349     WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), mouseDownMessageBody.get());
350
351     // Asynchronous mouse up.
352     WKRetainPtr<WKMutableDictionaryRef> mouseUpMessageBody(AdoptWK, createMouseMessageBody(MouseUp, button, modifiers));
353     WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), mouseUpMessageBody.get());
354 }
355
356 static WKRetainPtr<WKMutableDictionaryRef> createKeyDownMessageBody(JSStringRef key, WKEventModifiers modifiers, int location)
357 {
358     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
359
360     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
361     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("KeyDown"));
362     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
363
364     WKRetainPtr<WKStringRef> keyKey(AdoptWK, WKStringCreateWithUTF8CString("Key"));
365     WKDictionarySetItem(EventSenderMessageBody.get(), keyKey.get(), toWK(key).get());
366
367     WKRetainPtr<WKStringRef> modifiersKey(AdoptWK, WKStringCreateWithUTF8CString("Modifiers"));
368     WKRetainPtr<WKUInt64Ref> modifiersRef(AdoptWK, WKUInt64Create(modifiers));
369     WKDictionarySetItem(EventSenderMessageBody.get(), modifiersKey.get(), modifiersRef.get());
370
371     WKRetainPtr<WKStringRef> locationKey(AdoptWK, WKStringCreateWithUTF8CString("Location"));
372     WKRetainPtr<WKUInt64Ref> locationRef(AdoptWK, WKUInt64Create(location));
373     WKDictionarySetItem(EventSenderMessageBody.get(), locationKey.get(), locationRef.get());
374
375     return EventSenderMessageBody;
376 }
377
378 void EventSendingController::keyDown(JSStringRef key, JSValueRef modifierArray, int location)
379 {
380     WKBundlePageRef page = InjectedBundle::singleton().page()->page();
381     WKBundleFrameRef frame = WKBundlePageGetMainFrame(page);
382     JSContextRef context = WKBundleFrameGetJavaScriptContext(frame);
383     WKEventModifiers modifiers = parseModifierArray(context, modifierArray);
384
385     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
386     WKRetainPtr<WKMutableDictionaryRef> keyDownMessageBody = createKeyDownMessageBody(key, modifiers, location);
387
388     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), keyDownMessageBody.get(), 0);
389 }
390
391 void EventSendingController::scheduleAsynchronousKeyDown(JSStringRef key)
392 {
393     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
394     WKRetainPtr<WKMutableDictionaryRef> keyDownMessageBody = createKeyDownMessageBody(key, 0 /* modifiers */, 0 /* location */);
395
396     WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), keyDownMessageBody.get());
397 }
398
399 void EventSendingController::mouseScrollBy(int x, int y)
400 {
401     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
402     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
403
404     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
405     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseScrollBy"));
406     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
407
408     WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
409     WKRetainPtr<WKDoubleRef> xRef(AdoptWK, WKDoubleCreate(x));
410     WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
411
412     WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
413     WKRetainPtr<WKDoubleRef> yRef(AdoptWK, WKDoubleCreate(y));
414     WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
415
416     WKBundlePageForceRepaint(InjectedBundle::singleton().page()->page()); // Triggers a scrolling tree commit.
417     WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get());
418 }
419
420 static uint64_t cgEventPhaseFromString(JSStringRef phaseStr)
421 {
422     if (JSStringIsEqualToUTF8CString(phaseStr, "none"))
423         return 0;
424     if (JSStringIsEqualToUTF8CString(phaseStr, "began"))
425         return 1; // kCGScrollPhaseBegan
426     if (JSStringIsEqualToUTF8CString(phaseStr, "changed"))
427         return 2; // kCGScrollPhaseChanged
428     if (JSStringIsEqualToUTF8CString(phaseStr, "ended"))
429         return 4; // kCGScrollPhaseEnded
430     if (JSStringIsEqualToUTF8CString(phaseStr, "cancelled"))
431         return 8; // kCGScrollPhaseCancelled
432     if (JSStringIsEqualToUTF8CString(phaseStr, "maybegin"))
433         return 128; // kCGScrollPhaseMayBegin
434
435     ASSERT_NOT_REACHED();
436     return 0;
437 }
438
439 static uint64_t cgEventMomentumPhaseFromString(JSStringRef phaseStr)
440 {
441     if (JSStringIsEqualToUTF8CString(phaseStr, "none"))
442         return 0; // kCGMomentumScrollPhaseNone
443     if (JSStringIsEqualToUTF8CString(phaseStr, "begin"))
444         return 1; // kCGMomentumScrollPhaseBegin
445     if (JSStringIsEqualToUTF8CString(phaseStr, "continue"))
446         return 2; // kCGMomentumScrollPhaseContinue
447     if (JSStringIsEqualToUTF8CString(phaseStr, "end"))
448         return 3; // kCGMomentumScrollPhaseEnd
449
450     ASSERT_NOT_REACHED();
451     return 0;
452 }
453
454 void EventSendingController::mouseScrollByWithWheelAndMomentumPhases(int x, int y, JSStringRef phaseStr, JSStringRef momentumStr)
455 {
456     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
457     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
458     
459     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
460     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseScrollByWithWheelAndMomentumPhases"));
461     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
462     
463     WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
464     WKRetainPtr<WKDoubleRef> xRef(AdoptWK, WKDoubleCreate(x));
465     WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
466     
467     WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
468     WKRetainPtr<WKDoubleRef> yRef(AdoptWK, WKDoubleCreate(y));
469     WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
470
471     uint64_t phase = cgEventPhaseFromString(phaseStr);
472     uint64_t momentum = cgEventMomentumPhaseFromString(momentumStr);
473
474     WKRetainPtr<WKStringRef> phaseKey(AdoptWK, WKStringCreateWithUTF8CString("Phase"));
475     WKRetainPtr<WKUInt64Ref> phaseRef(AdoptWK, WKUInt64Create(phase));
476     WKDictionarySetItem(EventSenderMessageBody.get(), phaseKey.get(), phaseRef.get());
477
478     WKRetainPtr<WKStringRef> momentumKey(AdoptWK, WKStringCreateWithUTF8CString("Momentum"));
479     WKRetainPtr<WKUInt64Ref> momentumRef(AdoptWK, WKUInt64Create(momentum));
480     WKDictionarySetItem(EventSenderMessageBody.get(), momentumKey.get(), momentumRef.get());
481
482     WKBundlePageForceRepaint(InjectedBundle::singleton().page()->page()); // Triggers a scrolling tree commit.
483     WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get());
484 }
485
486 void EventSendingController::continuousMouseScrollBy(int x, int y, bool paged)
487 {
488     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
489     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
490
491     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
492     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("ContinuousMouseScrollBy"));
493     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
494
495     WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
496     WKRetainPtr<WKDoubleRef> xRef(AdoptWK, WKDoubleCreate(x));
497     WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
498
499     WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
500     WKRetainPtr<WKDoubleRef> yRef(AdoptWK, WKDoubleCreate(y));
501     WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
502
503     WKRetainPtr<WKStringRef> pagedKey(AdoptWK, WKStringCreateWithUTF8CString("Paged"));
504     WKRetainPtr<WKUInt64Ref> pagedRef(AdoptWK, WKUInt64Create(paged));
505     WKDictionarySetItem(EventSenderMessageBody.get(), pagedKey.get(), pagedRef.get());
506
507     // FIXME: This message should be asynchronous, as scrolling is intrinsically asynchronous.
508     // See also: <https://bugs.webkit.org/show_bug.cgi?id=148256>.
509     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
510 }
511
512 JSValueRef EventSendingController::contextClick()
513 {
514     WKBundlePageRef page = InjectedBundle::singleton().page()->page();
515     WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
516     JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
517 #if ENABLE(CONTEXT_MENUS)
518     WKRetainPtr<WKArrayRef> menuEntries = adoptWK(WKBundlePageCopyContextMenuAtPointInWindow(page, m_position));
519     JSValueRef arrayResult = JSObjectMakeArray(context, 0, 0, 0);
520     if (!menuEntries)
521         return arrayResult;
522
523     JSObjectRef arrayObj = JSValueToObject(context, arrayResult, 0);
524     size_t entriesSize = WKArrayGetSize(menuEntries.get());
525     for (size_t i = 0; i < entriesSize; ++i) {
526         ASSERT(WKGetTypeID(WKArrayGetItemAtIndex(menuEntries.get(), i)) == WKContextMenuItemGetTypeID());
527
528         WKContextMenuItemRef item = static_cast<WKContextMenuItemRef>(WKArrayGetItemAtIndex(menuEntries.get(), i));
529         MenuItemPrivateData* privateData = new MenuItemPrivateData(page, item);
530         JSObjectSetPropertyAtIndex(context, arrayObj, i, JSObjectMake(context, getMenuItemClass(), privateData), 0);
531     }
532
533     return arrayResult;
534 #else
535     return JSValueMakeUndefined(context);
536 #endif
537 }
538
539 void EventSendingController::textZoomIn()
540 {
541     auto& injectedBundle = InjectedBundle::singleton();
542     // Ensure page zoom is reset.
543     WKBundlePageSetPageZoomFactor(injectedBundle.page()->page(), 1);
544
545     double zoomFactor = WKBundlePageGetTextZoomFactor(injectedBundle.page()->page());
546     WKBundlePageSetTextZoomFactor(injectedBundle.page()->page(), zoomFactor * ZoomMultiplierRatio);
547 }
548
549 void EventSendingController::textZoomOut()
550 {
551     auto& injectedBundle = InjectedBundle::singleton();
552     // Ensure page zoom is reset.
553     WKBundlePageSetPageZoomFactor(injectedBundle.page()->page(), 1);
554
555     double zoomFactor = WKBundlePageGetTextZoomFactor(injectedBundle.page()->page());
556     WKBundlePageSetTextZoomFactor(injectedBundle.page()->page(), zoomFactor / ZoomMultiplierRatio);
557 }
558
559 void EventSendingController::zoomPageIn()
560 {
561     auto& injectedBundle = InjectedBundle::singleton();
562     // Ensure text zoom is reset.
563     WKBundlePageSetTextZoomFactor(injectedBundle.page()->page(), 1);
564
565     double zoomFactor = WKBundlePageGetPageZoomFactor(injectedBundle.page()->page());
566     WKBundlePageSetPageZoomFactor(injectedBundle.page()->page(), zoomFactor * ZoomMultiplierRatio);
567 }
568
569 void EventSendingController::zoomPageOut()
570 {
571     auto& injectedBundle = InjectedBundle::singleton();
572     // Ensure text zoom is reset.
573     WKBundlePageSetTextZoomFactor(injectedBundle.page()->page(), 1);
574
575     double zoomFactor = WKBundlePageGetPageZoomFactor(injectedBundle.page()->page());
576     WKBundlePageSetPageZoomFactor(injectedBundle.page()->page(), zoomFactor / ZoomMultiplierRatio);
577 }
578
579 void EventSendingController::scalePageBy(double scale, double x, double y)
580 {
581     WKPoint origin = { x, y };
582     WKBundlePageSetScaleAtOrigin(InjectedBundle::singleton().page()->page(), scale, origin);
583 }
584
585 void EventSendingController::monitorWheelEvents()
586 {
587     WKBundlePageRef page = InjectedBundle::singleton().page()->page();
588     
589     WKBundlePageStartMonitoringScrollOperations(page);
590 }
591
592 struct ScrollCompletionCallbackData {
593     JSContextRef m_context;
594     JSObjectRef m_function;
595
596     ScrollCompletionCallbackData(JSContextRef context, JSObjectRef function)
597         : m_context(context), m_function(function)
598     {
599     }
600 };
601
602 static void executeCallback(void* context)
603 {
604     if (!context)
605         return;
606
607     std::unique_ptr<ScrollCompletionCallbackData> callBackData(reinterpret_cast<ScrollCompletionCallbackData*>(context));
608
609     JSObjectCallAsFunction(callBackData->m_context, callBackData->m_function, nullptr, 0, nullptr, nullptr);
610     JSValueUnprotect(callBackData->m_context, callBackData->m_function);
611 }
612
613 void EventSendingController::callAfterScrollingCompletes(JSValueRef functionCallback)
614 {
615     if (!functionCallback)
616         return;
617
618     WKBundlePageRef page = InjectedBundle::singleton().page()->page();
619     WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
620     JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
621     
622     JSObjectRef functionCallbackObject = JSValueToObject(context, functionCallback, nullptr);
623     if (!functionCallbackObject)
624         return;
625     
626     JSValueProtect(context, functionCallbackObject);
627
628     auto scrollCompletionCallbackData = std::make_unique<ScrollCompletionCallbackData>(context, functionCallbackObject);
629
630     WKBundlePageRegisterScrollOperationCompletionCallback(page, executeCallback, scrollCompletionCallbackData.release());
631 }
632
633 #if ENABLE(TOUCH_EVENTS)
634 void EventSendingController::addTouchPoint(int x, int y)
635 {
636     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
637     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
638
639     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
640     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("AddTouchPoint"));
641     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
642
643     WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
644     WKRetainPtr<WKUInt64Ref> xRef(AdoptWK, WKUInt64Create(x));
645     WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
646
647     WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
648     WKRetainPtr<WKUInt64Ref> yRef(AdoptWK, WKUInt64Create(y));
649     WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
650
651     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
652 }
653
654 void EventSendingController::updateTouchPoint(int index, int x, int y)
655 {
656     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
657     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
658
659     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
660     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("UpdateTouchPoint"));
661     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
662
663     WKRetainPtr<WKStringRef> indexKey(AdoptWK, WKStringCreateWithUTF8CString("Index"));
664     WKRetainPtr<WKUInt64Ref> indexRef(AdoptWK, WKUInt64Create(index));
665     WKDictionarySetItem(EventSenderMessageBody.get(), indexKey.get(), indexRef.get());
666
667     WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
668     WKRetainPtr<WKUInt64Ref> xRef(AdoptWK, WKUInt64Create(x));
669     WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
670
671     WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
672     WKRetainPtr<WKUInt64Ref> yRef(AdoptWK, WKUInt64Create(y));
673     WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
674
675     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
676 }
677
678 void EventSendingController::setTouchModifier(const JSStringRef &modifier, bool enable)
679 {
680     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
681     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
682
683     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
684     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("SetTouchModifier"));
685     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
686
687     WKEventModifiers mod = 0;
688     if (JSStringIsEqualToUTF8CString(modifier, "ctrl"))
689         mod = kWKEventModifiersControlKey;
690     if (JSStringIsEqualToUTF8CString(modifier, "shift"))
691         mod = kWKEventModifiersShiftKey;
692     if (JSStringIsEqualToUTF8CString(modifier, "alt"))
693         mod = kWKEventModifiersAltKey;
694     if (JSStringIsEqualToUTF8CString(modifier, "meta"))
695         mod = kWKEventModifiersMetaKey;
696
697     WKRetainPtr<WKStringRef> modifierKey(AdoptWK, WKStringCreateWithUTF8CString("Modifier"));
698     WKRetainPtr<WKUInt64Ref> modifierRef(AdoptWK, WKUInt64Create(mod));
699     WKDictionarySetItem(EventSenderMessageBody.get(), modifierKey.get(), modifierRef.get());
700
701     WKRetainPtr<WKStringRef> enableKey(AdoptWK, WKStringCreateWithUTF8CString("Enable"));
702     WKRetainPtr<WKUInt64Ref> enableRef(AdoptWK, WKUInt64Create(enable));
703     WKDictionarySetItem(EventSenderMessageBody.get(), enableKey.get(), enableRef.get());
704
705     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
706 }
707
708
709 void EventSendingController::setTouchPointRadius(int radiusX, int radiusY)
710 {
711     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
712     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
713
714     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
715     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("SetTouchPointRadius"));
716     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
717
718     WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("RadiusX"));
719     WKRetainPtr<WKUInt64Ref> xRef(AdoptWK, WKUInt64Create(radiusX));
720     WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
721
722     WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("RadiusY"));
723     WKRetainPtr<WKUInt64Ref> yRef(AdoptWK, WKUInt64Create(radiusY));
724     WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
725
726     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
727 }
728
729 void EventSendingController::touchStart()
730 {
731     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
732     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
733
734     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
735     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("TouchStart"));
736     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
737
738     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
739 }
740
741 void EventSendingController::touchMove()
742 {
743     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
744     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
745
746     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
747     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("TouchMove"));
748     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
749
750     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
751 }
752
753 void EventSendingController::touchEnd()
754 {
755     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
756     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
757
758     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
759     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("TouchEnd"));
760     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
761
762     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
763 }
764
765 void EventSendingController::touchCancel()
766 {
767     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
768     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
769
770     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
771     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("TouchCancel"));
772     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
773
774     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
775 }
776
777 void EventSendingController::clearTouchPoints()
778 {
779     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
780     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
781
782     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
783     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("ClearTouchPoints"));
784     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
785
786     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
787 }
788
789 void EventSendingController::releaseTouchPoint(int index)
790 {
791     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
792     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
793
794     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
795     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("ReleaseTouchPoint"));
796     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
797
798     WKRetainPtr<WKStringRef> indexKey(AdoptWK, WKStringCreateWithUTF8CString("Index"));
799     WKRetainPtr<WKUInt64Ref> indexRef(AdoptWK, WKUInt64Create(index));
800     WKDictionarySetItem(EventSenderMessageBody.get(), indexKey.get(), indexRef.get());
801
802     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
803 }
804
805 void EventSendingController::cancelTouchPoint(int index)
806 {
807     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
808     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
809
810     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
811     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("CancelTouchPoint"));
812     WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
813
814     WKRetainPtr<WKStringRef> indexKey(AdoptWK, WKStringCreateWithUTF8CString("Index"));
815     WKRetainPtr<WKUInt64Ref> indexRef(AdoptWK, WKUInt64Create(index));
816     WKDictionarySetItem(EventSenderMessageBody.get(), indexKey.get(), indexRef.get());
817
818     WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
819 }
820 #endif
821
822 // Object Creation
823
824 void EventSendingController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
825 {
826     setProperty(context, windowObject, "eventSender", this, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
827 }
828
829 } // namespace WTR