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
42namespace WTR {
43
44static const float ZoomMultiplierRatio = 1.2f;
45
46struct 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)
55static 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
62static 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
69static JSStaticFunction staticMenuItemFunctions[] = {
70 { "click", menuItemClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
71 { 0, 0, 0 }
72};
73
74static JSStaticValue staticMenuItemValues[] = {
75 { "title", getMenuItemTitleCallback, 0, kJSPropertyAttributeReadOnly },
76 { 0, 0, 0, 0 }
77};
78
79static void staticMenuItemFinalize(JSObjectRef object)
80{
81 delete static_cast<MenuItemPrivateData*>(JSObjectGetPrivate(object));
82}
83
84static 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
91static 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
109static 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
131static unsigned arrayLength(JSContextRef context, JSObjectRef array)
132{
133 auto 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
140static 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 auto 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 auto string = adopt(JSValueToStringCopy(context, value, &exception));
162 if (exception)
163 continue;
164 modifiers |= parseModifier(string.get());
165 }
166 return modifiers;
167}
168
169Ref<EventSendingController> EventSendingController::create()
170{
171 return adoptRef(*new EventSendingController);
172}
173
174EventSendingController::EventSendingController()
175{
176}
177
178EventSendingController::~EventSendingController()
179{
180}
181
182JSClassRef EventSendingController::wrapperClass()
183{
184 return JSEventSendingController::eventSendingControllerClass();
185}
186
187enum MouseState {
188 MouseUp,
189 MouseDown
190};
191
192static 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
211void 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
225void 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
238void 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
260void 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
272void 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
284void 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
296void 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
308void 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
324void 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
340void 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
356static 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
378void 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
391void 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
399void 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
420static 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
439static 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
454void 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
486void 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
512JSValueRef 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
539void 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
549void 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
559void 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
569void 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
579void EventSendingController::scalePageBy(double scale, double x, double y)
580{
581 WKPoint origin = { x, y };
582 WKBundlePageSetScaleAtOrigin(InjectedBundle::singleton().page()->page(), scale, origin);
583}
584
585void EventSendingController::monitorWheelEvents()
586{
587 WKBundlePageRef page = InjectedBundle::singleton().page()->page();
588
589 WKBundlePageStartMonitoringScrollOperations(page);
590}
591
592struct 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
602static 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
613void 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 auto scrollCompletionCallbackDataPtr = scrollCompletionCallbackData.release();
630 bool callbackWillBeCalled = WKBundlePageRegisterScrollOperationCompletionCallback(page, executeCallback, scrollCompletionCallbackDataPtr);
631 if (!callbackWillBeCalled) {
632 // Reassign raw pointer to std::unique_ptr<> so it will not be leaked.
633 scrollCompletionCallbackData.reset(scrollCompletionCallbackDataPtr);
634 }
635}
636
637#if ENABLE(TOUCH_EVENTS)
638void EventSendingController::addTouchPoint(int x, int y)
639{
640 WKRetainPtr<WKStringRef> EventSenderMessageName = adoptWK(WKStringCreateWithUTF8CString("EventSender"));
641 WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody = adoptWK(WKMutableDictionaryCreate());
642
643 WKRetainPtr<WKStringRef> subMessageKey = adoptWK(WKStringCreateWithUTF8CString("SubMessage"));
644 WKRetainPtr<WKStringRef> subMessageName = adoptWK(WKStringCreateWithUTF8CString("AddTouchPoint"));
645 WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
646
647 WKRetainPtr<WKStringRef> xKey = adoptWK(WKStringCreateWithUTF8CString("X"));
648 WKRetainPtr<WKUInt64Ref> xRef = adoptWK(WKUInt64Create(x));
649 WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
650
651 WKRetainPtr<WKStringRef> yKey = adoptWK(WKStringCreateWithUTF8CString("Y"));
652 WKRetainPtr<WKUInt64Ref> yRef = adoptWK(WKUInt64Create(y));
653 WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
654
655 WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
656}
657
658void EventSendingController::updateTouchPoint(int index, int x, int y)
659{
660 WKRetainPtr<WKStringRef> EventSenderMessageName = adoptWK(WKStringCreateWithUTF8CString("EventSender"));
661 WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody = adoptWK(WKMutableDictionaryCreate());
662
663 WKRetainPtr<WKStringRef> subMessageKey = adoptWK(WKStringCreateWithUTF8CString("SubMessage"));
664 WKRetainPtr<WKStringRef> subMessageName = adoptWK(WKStringCreateWithUTF8CString("UpdateTouchPoint"));
665 WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
666
667 WKRetainPtr<WKStringRef> indexKey = adoptWK(WKStringCreateWithUTF8CString("Index"));
668 WKRetainPtr<WKUInt64Ref> indexRef = adoptWK(WKUInt64Create(index));
669 WKDictionarySetItem(EventSenderMessageBody.get(), indexKey.get(), indexRef.get());
670
671 WKRetainPtr<WKStringRef> xKey = adoptWK(WKStringCreateWithUTF8CString("X"));
672 WKRetainPtr<WKUInt64Ref> xRef = adoptWK(WKUInt64Create(x));
673 WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
674
675 WKRetainPtr<WKStringRef> yKey = adoptWK(WKStringCreateWithUTF8CString("Y"));
676 WKRetainPtr<WKUInt64Ref> yRef = adoptWK(WKUInt64Create(y));
677 WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
678
679 WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
680}
681
682void EventSendingController::setTouchModifier(const JSStringRef &modifier, bool enable)
683{
684 WKRetainPtr<WKStringRef> EventSenderMessageName = adoptWK(WKStringCreateWithUTF8CString("EventSender"));
685 WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody = adoptWK(WKMutableDictionaryCreate());
686
687 WKRetainPtr<WKStringRef> subMessageKey = adoptWK(WKStringCreateWithUTF8CString("SubMessage"));
688 WKRetainPtr<WKStringRef> subMessageName = adoptWK(WKStringCreateWithUTF8CString("SetTouchModifier"));
689 WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
690
691 WKEventModifiers mod = 0;
692 if (JSStringIsEqualToUTF8CString(modifier, "ctrl"))
693 mod = kWKEventModifiersControlKey;
694 if (JSStringIsEqualToUTF8CString(modifier, "shift"))
695 mod = kWKEventModifiersShiftKey;
696 if (JSStringIsEqualToUTF8CString(modifier, "alt"))
697 mod = kWKEventModifiersAltKey;
698 if (JSStringIsEqualToUTF8CString(modifier, "meta"))
699 mod = kWKEventModifiersMetaKey;
700
701 WKRetainPtr<WKStringRef> modifierKey = adoptWK(WKStringCreateWithUTF8CString("Modifier"));
702 WKRetainPtr<WKUInt64Ref> modifierRef = adoptWK(WKUInt64Create(mod));
703 WKDictionarySetItem(EventSenderMessageBody.get(), modifierKey.get(), modifierRef.get());
704
705 WKRetainPtr<WKStringRef> enableKey = adoptWK(WKStringCreateWithUTF8CString("Enable"));
706 WKRetainPtr<WKUInt64Ref> enableRef = adoptWK(WKUInt64Create(enable));
707 WKDictionarySetItem(EventSenderMessageBody.get(), enableKey.get(), enableRef.get());
708
709 WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
710}
711
712
713void EventSendingController::setTouchPointRadius(int radiusX, int radiusY)
714{
715 WKRetainPtr<WKStringRef> EventSenderMessageName = adoptWK(WKStringCreateWithUTF8CString("EventSender"));
716 WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody = adoptWK(WKMutableDictionaryCreate());
717
718 WKRetainPtr<WKStringRef> subMessageKey = adoptWK(WKStringCreateWithUTF8CString("SubMessage"));
719 WKRetainPtr<WKStringRef> subMessageName = adoptWK(WKStringCreateWithUTF8CString("SetTouchPointRadius"));
720 WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
721
722 WKRetainPtr<WKStringRef> xKey = adoptWK(WKStringCreateWithUTF8CString("RadiusX"));
723 WKRetainPtr<WKUInt64Ref> xRef = adoptWK(WKUInt64Create(radiusX));
724 WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
725
726 WKRetainPtr<WKStringRef> yKey = adoptWK(WKStringCreateWithUTF8CString("RadiusY"));
727 WKRetainPtr<WKUInt64Ref> yRef = adoptWK(WKUInt64Create(radiusY));
728 WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
729
730 WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
731}
732
733void EventSendingController::touchStart()
734{
735 WKRetainPtr<WKStringRef> EventSenderMessageName = adoptWK(WKStringCreateWithUTF8CString("EventSender"));
736 WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody = adoptWK(WKMutableDictionaryCreate());
737
738 WKRetainPtr<WKStringRef> subMessageKey = adoptWK(WKStringCreateWithUTF8CString("SubMessage"));
739 WKRetainPtr<WKStringRef> subMessageName = adoptWK(WKStringCreateWithUTF8CString("TouchStart"));
740 WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
741
742 WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
743}
744
745void EventSendingController::touchMove()
746{
747 WKRetainPtr<WKStringRef> EventSenderMessageName = adoptWK(WKStringCreateWithUTF8CString("EventSender"));
748 WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody = adoptWK(WKMutableDictionaryCreate());
749
750 WKRetainPtr<WKStringRef> subMessageKey = adoptWK(WKStringCreateWithUTF8CString("SubMessage"));
751 WKRetainPtr<WKStringRef> subMessageName = adoptWK(WKStringCreateWithUTF8CString("TouchMove"));
752 WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
753
754 WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
755}
756
757void EventSendingController::touchEnd()
758{
759 WKRetainPtr<WKStringRef> EventSenderMessageName = adoptWK(WKStringCreateWithUTF8CString("EventSender"));
760 WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody = adoptWK(WKMutableDictionaryCreate());
761
762 WKRetainPtr<WKStringRef> subMessageKey = adoptWK(WKStringCreateWithUTF8CString("SubMessage"));
763 WKRetainPtr<WKStringRef> subMessageName = adoptWK(WKStringCreateWithUTF8CString("TouchEnd"));
764 WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
765
766 WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
767}
768
769void EventSendingController::touchCancel()
770{
771 WKRetainPtr<WKStringRef> EventSenderMessageName = adoptWK(WKStringCreateWithUTF8CString("EventSender"));
772 WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody = adoptWK(WKMutableDictionaryCreate());
773
774 WKRetainPtr<WKStringRef> subMessageKey = adoptWK(WKStringCreateWithUTF8CString("SubMessage"));
775 WKRetainPtr<WKStringRef> subMessageName = adoptWK(WKStringCreateWithUTF8CString("TouchCancel"));
776 WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
777
778 WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
779}
780
781void EventSendingController::clearTouchPoints()
782{
783 WKRetainPtr<WKStringRef> EventSenderMessageName = adoptWK(WKStringCreateWithUTF8CString("EventSender"));
784 WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody = adoptWK(WKMutableDictionaryCreate());
785
786 WKRetainPtr<WKStringRef> subMessageKey = adoptWK(WKStringCreateWithUTF8CString("SubMessage"));
787 WKRetainPtr<WKStringRef> subMessageName = adoptWK(WKStringCreateWithUTF8CString("ClearTouchPoints"));
788 WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
789
790 WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
791}
792
793void EventSendingController::releaseTouchPoint(int index)
794{
795 WKRetainPtr<WKStringRef> EventSenderMessageName = adoptWK(WKStringCreateWithUTF8CString("EventSender"));
796 WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody = adoptWK(WKMutableDictionaryCreate());
797
798 WKRetainPtr<WKStringRef> subMessageKey = adoptWK(WKStringCreateWithUTF8CString("SubMessage"));
799 WKRetainPtr<WKStringRef> subMessageName = adoptWK(WKStringCreateWithUTF8CString("ReleaseTouchPoint"));
800 WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
801
802 WKRetainPtr<WKStringRef> indexKey = adoptWK(WKStringCreateWithUTF8CString("Index"));
803 WKRetainPtr<WKUInt64Ref> indexRef = adoptWK(WKUInt64Create(index));
804 WKDictionarySetItem(EventSenderMessageBody.get(), indexKey.get(), indexRef.get());
805
806 WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
807}
808
809void EventSendingController::cancelTouchPoint(int index)
810{
811 WKRetainPtr<WKStringRef> EventSenderMessageName = adoptWK(WKStringCreateWithUTF8CString("EventSender"));
812 WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody = adoptWK(WKMutableDictionaryCreate());
813
814 WKRetainPtr<WKStringRef> subMessageKey = adoptWK(WKStringCreateWithUTF8CString("SubMessage"));
815 WKRetainPtr<WKStringRef> subMessageName = adoptWK(WKStringCreateWithUTF8CString("CancelTouchPoint"));
816 WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
817
818 WKRetainPtr<WKStringRef> indexKey = adoptWK(WKStringCreateWithUTF8CString("Index"));
819 WKRetainPtr<WKUInt64Ref> indexRef = adoptWK(WKUInt64Create(index));
820 WKDictionarySetItem(EventSenderMessageBody.get(), indexKey.get(), indexRef.get());
821
822 WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
823}
824#endif
825
826// Object Creation
827
828void EventSendingController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
829{
830 setProperty(context, windowObject, "eventSender", this, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
831}
832
833} // namespace WTR
834