Replace use of OwnArrayPtr<Foo> with std::unique_ptr<Foo[]> in Tools
[WebKit-https.git] / Tools / WebKitTestRunner / InjectedBundle / EventSendingController.cpp
1 /*
2  * Copyright (C) 2010, 2011 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 <WebKit2/WKBundle.h>
34 #include <WebKit2/WKBundleFrame.h>
35 #include <WebKit2/WKBundlePagePrivate.h>
36 #include <WebKit2/WKBundlePrivate.h>
37 #include <WebKit2/WKContextMenuItem.h>
38 #include <WebKit2/WKMutableDictionary.h>
39 #include <WebKit2/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
55 static JSValueRef menuItemClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
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* exception)
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
108 static WKEventModifiers parseModifier(JSStringRef modifier)
109 {
110     if (JSStringIsEqualToUTF8CString(modifier, "ctrlKey"))
111         return kWKEventModifiersControlKey;
112     if (JSStringIsEqualToUTF8CString(modifier, "shiftKey") || JSStringIsEqualToUTF8CString(modifier, "rangeSelectionKey"))
113         return kWKEventModifiersShiftKey;
114     if (JSStringIsEqualToUTF8CString(modifier, "altKey"))
115         return kWKEventModifiersAltKey;
116     if (JSStringIsEqualToUTF8CString(modifier, "metaKey"))
117         return kWKEventModifiersMetaKey;
118     if (JSStringIsEqualToUTF8CString(modifier, "addSelectionKey")) {
119 #if OS(MAC_OS_X)
120         return kWKEventModifiersMetaKey;
121 #else
122         return kWKEventModifiersControlKey;
123 #endif
124     }
125     return 0;
126 }
127
128 static unsigned arrayLength(JSContextRef context, JSObjectRef array)
129 {
130     JSRetainPtr<JSStringRef> lengthString(Adopt, JSStringCreateWithUTF8CString("length"));
131     JSValueRef lengthValue = JSObjectGetProperty(context, array, lengthString.get(), 0);
132     if (!lengthValue)
133         return 0;
134     return static_cast<unsigned>(JSValueToNumber(context, lengthValue, 0));
135 }
136
137 static WKEventModifiers parseModifierArray(JSContextRef context, JSValueRef arrayValue)
138 {
139     if (!arrayValue)
140         return 0;
141
142     // The value may either be a string with a single modifier or an array of modifiers.
143     if (JSValueIsString(context, arrayValue)) {
144         JSRetainPtr<JSStringRef> string(Adopt, JSValueToStringCopy(context, arrayValue, 0));
145         return parseModifier(string.get());
146     }
147
148     if (!JSValueIsObject(context, arrayValue))
149         return 0;
150     JSObjectRef array = const_cast<JSObjectRef>(arrayValue);
151     unsigned length = arrayLength(context, array);
152     WKEventModifiers modifiers = 0;
153     for (unsigned i = 0; i < length; i++) {
154         JSValueRef exception = 0;
155         JSValueRef value = JSObjectGetPropertyAtIndex(context, array, i, &exception);
156         if (exception)
157             continue;
158         JSRetainPtr<JSStringRef> string(Adopt, JSValueToStringCopy(context, value, &exception));
159         if (exception)
160             continue;
161         modifiers |= parseModifier(string.get());
162     }
163     return modifiers;
164 }
165
166 PassRefPtr<EventSendingController> EventSendingController::create()
167 {
168     return adoptRef(new EventSendingController);
169 }
170
171 EventSendingController::EventSendingController()
172 {
173 }
174
175 EventSendingController::~EventSendingController()
176 {
177 }
178
179 JSClassRef EventSendingController::wrapperClass()
180 {
181     return JSEventSendingController::eventSendingControllerClass();
182 }
183
184 enum MouseState {
185     MouseUp,
186     MouseDown
187 };
188
189 static WKMutableDictionaryRef createMouseMessageBody(MouseState state, int button, WKEventModifiers modifiers)
190 {
191     WKMutableDictionaryRef EventSenderMessageBody = WKMutableDictionaryCreate();
192
193     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
194     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString(state == MouseUp ? "MouseUp" : "MouseDown"));
195     WKDictionaryAddItem(EventSenderMessageBody, subMessageKey.get(), subMessageName.get());
196
197     WKRetainPtr<WKStringRef> buttonKey = adoptWK(WKStringCreateWithUTF8CString("Button"));
198     WKRetainPtr<WKUInt64Ref> buttonRef = adoptWK(WKUInt64Create(button));
199     WKDictionaryAddItem(EventSenderMessageBody, buttonKey.get(), buttonRef.get());
200
201     WKRetainPtr<WKStringRef> modifiersKey = adoptWK(WKStringCreateWithUTF8CString("Modifiers"));
202     WKRetainPtr<WKUInt64Ref> modifiersRef = adoptWK(WKUInt64Create(modifiers));
203     WKDictionaryAddItem(EventSenderMessageBody, modifiersKey.get(), modifiersRef.get());
204
205     return EventSenderMessageBody;
206 }
207
208 void EventSendingController::mouseDown(int button, JSValueRef modifierArray) 
209 {
210     WKBundlePageRef page = InjectedBundle::shared().page()->page();
211     WKBundleFrameRef frame = WKBundlePageGetMainFrame(page);
212     JSContextRef context = WKBundleFrameGetJavaScriptContext(frame);
213     WKEventModifiers modifiers = parseModifierArray(context, modifierArray);
214
215     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
216     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, createMouseMessageBody(MouseDown, button, modifiers));
217
218     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
219 }
220
221 void EventSendingController::mouseUp(int button, JSValueRef modifierArray)
222 {
223     WKBundlePageRef page = InjectedBundle::shared().page()->page();
224     WKBundleFrameRef frame = WKBundlePageGetMainFrame(page);
225     JSContextRef context = WKBundleFrameGetJavaScriptContext(frame);
226     WKEventModifiers modifiers = parseModifierArray(context, modifierArray);
227
228     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
229     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, createMouseMessageBody(MouseUp, button, modifiers));
230
231     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
232 }
233
234 void EventSendingController::mouseMoveTo(int x, int y)
235 {
236     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
237     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
238
239     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
240     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseMoveTo"));
241     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
242
243     WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
244     WKRetainPtr<WKDoubleRef> xRef(AdoptWK, WKDoubleCreate(x));
245     WKDictionaryAddItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
246
247     WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
248     WKRetainPtr<WKDoubleRef> yRef(AdoptWK, WKDoubleCreate(y));
249     WKDictionaryAddItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
250
251     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
252 }
253
254 void EventSendingController::leapForward(int milliseconds)
255 {
256     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
257     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
258
259     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
260     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("LeapForward"));
261     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
262
263     WKRetainPtr<WKStringRef> timeKey(AdoptWK, WKStringCreateWithUTF8CString("TimeInMilliseconds"));
264     WKRetainPtr<WKUInt64Ref> timeRef(AdoptWK, WKUInt64Create(milliseconds));
265     WKDictionaryAddItem(EventSenderMessageBody.get(), timeKey.get(), timeRef.get());
266
267     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
268 }
269
270 void EventSendingController::scheduleAsynchronousClick()
271 {
272     WKEventModifiers modifiers = 0;
273     int button = 0;
274
275     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
276
277     // Asynchronous mouse down.
278     WKRetainPtr<WKMutableDictionaryRef> mouseDownMessageBody(AdoptWK, createMouseMessageBody(MouseDown, button, modifiers));
279     WKBundlePostMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), mouseDownMessageBody.get());
280
281     // Asynchronous mouse up.
282     WKRetainPtr<WKMutableDictionaryRef> mouseUpMessageBody(AdoptWK, createMouseMessageBody(MouseUp, button, modifiers));
283     WKBundlePostMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), mouseUpMessageBody.get());
284 }
285
286 static WKRetainPtr<WKMutableDictionaryRef> createKeyDownMessageBody(JSStringRef key, WKEventModifiers modifiers, int location)
287 {
288     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
289
290     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
291     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("KeyDown"));
292     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
293
294     WKRetainPtr<WKStringRef> keyKey(AdoptWK, WKStringCreateWithUTF8CString("Key"));
295     WKDictionaryAddItem(EventSenderMessageBody.get(), keyKey.get(), toWK(key).get());
296
297     WKRetainPtr<WKStringRef> modifiersKey(AdoptWK, WKStringCreateWithUTF8CString("Modifiers"));
298     WKRetainPtr<WKUInt64Ref> modifiersRef(AdoptWK, WKUInt64Create(modifiers));
299     WKDictionaryAddItem(EventSenderMessageBody.get(), modifiersKey.get(), modifiersRef.get());
300
301     WKRetainPtr<WKStringRef> locationKey(AdoptWK, WKStringCreateWithUTF8CString("Location"));
302     WKRetainPtr<WKUInt64Ref> locationRef(AdoptWK, WKUInt64Create(location));
303     WKDictionaryAddItem(EventSenderMessageBody.get(), locationKey.get(), locationRef.get());
304
305     return EventSenderMessageBody;
306 }
307
308 void EventSendingController::keyDown(JSStringRef key, JSValueRef modifierArray, int location)
309 {
310     WKBundlePageRef page = InjectedBundle::shared().page()->page();
311     WKBundleFrameRef frame = WKBundlePageGetMainFrame(page);
312     JSContextRef context = WKBundleFrameGetJavaScriptContext(frame);
313     WKEventModifiers modifiers = parseModifierArray(context, modifierArray);
314
315     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
316     WKRetainPtr<WKMutableDictionaryRef> keyDownMessageBody = createKeyDownMessageBody(key, modifiers, location);
317
318     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), keyDownMessageBody.get(), 0);
319 }
320
321 void EventSendingController::scheduleAsynchronousKeyDown(JSStringRef key)
322 {
323     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
324     WKRetainPtr<WKMutableDictionaryRef> keyDownMessageBody = createKeyDownMessageBody(key, 0 /* modifiers */, 0 /* location */);
325
326     WKBundlePostMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), keyDownMessageBody.get());
327 }
328
329 void EventSendingController::mouseScrollBy(int x, int y)
330 {
331     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
332     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
333
334     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
335     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseScrollBy"));
336     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
337
338     WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
339     WKRetainPtr<WKDoubleRef> xRef(AdoptWK, WKDoubleCreate(x));
340     WKDictionaryAddItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
341
342     WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
343     WKRetainPtr<WKDoubleRef> yRef(AdoptWK, WKDoubleCreate(y));
344     WKDictionaryAddItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
345
346     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
347 }
348
349 void EventSendingController::continuousMouseScrollBy(int x, int y, bool paged)
350 {
351     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
352     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
353
354     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
355     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("ContinuousMouseScrollBy"));
356     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
357
358     WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
359     WKRetainPtr<WKDoubleRef> xRef(AdoptWK, WKDoubleCreate(x));
360     WKDictionaryAddItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
361
362     WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
363     WKRetainPtr<WKDoubleRef> yRef(AdoptWK, WKDoubleCreate(y));
364     WKDictionaryAddItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
365
366     WKRetainPtr<WKStringRef> pagedKey(AdoptWK, WKStringCreateWithUTF8CString("Paged"));
367     WKRetainPtr<WKUInt64Ref> pagedRef(AdoptWK, WKUInt64Create(paged));
368     WKDictionaryAddItem(EventSenderMessageBody.get(), pagedKey.get(), pagedRef.get());
369
370     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
371 }
372
373 JSValueRef EventSendingController::contextClick()
374 {
375     WKBundlePageRef page = InjectedBundle::shared().page()->page();
376     WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
377     JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
378 #if ENABLE(CONTEXT_MENUS)
379     // Do mouse context click.
380     mouseDown(2, 0);
381     mouseUp(2, 0);
382
383     WKRetainPtr<WKArrayRef> menuEntries = adoptWK(WKBundlePageCopyContextMenuItems(page));
384     size_t entriesSize = WKArrayGetSize(menuEntries.get());
385     auto jsValuesArray = std::make_unique<JSValueRef[]>(entriesSize);
386     for (size_t i = 0; i < entriesSize; ++i) {
387         ASSERT(WKGetTypeID(WKArrayGetItemAtIndex(menuEntries.get(), i)) == WKContextMenuItemGetTypeID());
388
389         WKContextMenuItemRef item = static_cast<WKContextMenuItemRef>(WKArrayGetItemAtIndex(menuEntries.get(), i));
390         MenuItemPrivateData* privateData = new MenuItemPrivateData(page, item);
391         jsValuesArray[i] = JSObjectMake(context, getMenuItemClass(), privateData);
392     }
393
394     return JSObjectMakeArray(context, entriesSize, jsValuesArray.get(), 0);
395 #else
396     return JSValueMakeUndefined(context);
397 #endif
398 }
399
400 void EventSendingController::textZoomIn()
401 {
402     // Ensure page zoom is reset.
403     WKBundlePageSetPageZoomFactor(InjectedBundle::shared().page()->page(), 1);
404
405     double zoomFactor = WKBundlePageGetTextZoomFactor(InjectedBundle::shared().page()->page());
406     WKBundlePageSetTextZoomFactor(InjectedBundle::shared().page()->page(), zoomFactor * ZoomMultiplierRatio);
407 }
408
409 void EventSendingController::textZoomOut()
410 {
411     // Ensure page zoom is reset.
412     WKBundlePageSetPageZoomFactor(InjectedBundle::shared().page()->page(), 1);
413
414     double zoomFactor = WKBundlePageGetTextZoomFactor(InjectedBundle::shared().page()->page());
415     WKBundlePageSetTextZoomFactor(InjectedBundle::shared().page()->page(), zoomFactor / ZoomMultiplierRatio);
416 }
417
418 void EventSendingController::zoomPageIn()
419 {
420     // Ensure text zoom is reset.
421     WKBundlePageSetTextZoomFactor(InjectedBundle::shared().page()->page(), 1);
422
423     double zoomFactor = WKBundlePageGetPageZoomFactor(InjectedBundle::shared().page()->page());
424     WKBundlePageSetPageZoomFactor(InjectedBundle::shared().page()->page(), zoomFactor * ZoomMultiplierRatio);
425 }
426
427 void EventSendingController::zoomPageOut()
428 {
429     // Ensure text zoom is reset.
430     WKBundlePageSetTextZoomFactor(InjectedBundle::shared().page()->page(), 1);
431
432     double zoomFactor = WKBundlePageGetPageZoomFactor(InjectedBundle::shared().page()->page());
433     WKBundlePageSetPageZoomFactor(InjectedBundle::shared().page()->page(), zoomFactor / ZoomMultiplierRatio);
434 }
435
436 void EventSendingController::scalePageBy(double scale, double x, double y)
437 {
438     WKPoint origin = { x, y };
439     WKBundlePageSetScaleAtOrigin(InjectedBundle::shared().page()->page(), scale, origin);
440 }
441
442 #if ENABLE(TOUCH_EVENTS)
443 void EventSendingController::addTouchPoint(int x, int y)
444 {
445     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
446     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
447
448     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
449     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("AddTouchPoint"));
450     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
451
452     WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
453     WKRetainPtr<WKUInt64Ref> xRef(AdoptWK, WKUInt64Create(x));
454     WKDictionaryAddItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
455
456     WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
457     WKRetainPtr<WKUInt64Ref> yRef(AdoptWK, WKUInt64Create(y));
458     WKDictionaryAddItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
459
460     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
461 }
462
463 void EventSendingController::updateTouchPoint(int index, int x, int y)
464 {
465     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
466     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
467
468     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
469     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("UpdateTouchPoint"));
470     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
471
472     WKRetainPtr<WKStringRef> indexKey(AdoptWK, WKStringCreateWithUTF8CString("Index"));
473     WKRetainPtr<WKUInt64Ref> indexRef(AdoptWK, WKUInt64Create(index));
474     WKDictionaryAddItem(EventSenderMessageBody.get(), indexKey.get(), indexRef.get());
475
476     WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
477     WKRetainPtr<WKUInt64Ref> xRef(AdoptWK, WKUInt64Create(x));
478     WKDictionaryAddItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
479
480     WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
481     WKRetainPtr<WKUInt64Ref> yRef(AdoptWK, WKUInt64Create(y));
482     WKDictionaryAddItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
483
484     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
485 }
486
487 void EventSendingController::setTouchModifier(const JSStringRef &modifier, bool enable)
488 {
489     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
490     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
491
492     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
493     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("SetTouchModifier"));
494     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
495
496     WKEventModifiers mod = 0;
497     if (JSStringIsEqualToUTF8CString(modifier, "ctrl"))
498         mod = kWKEventModifiersControlKey;
499     if (JSStringIsEqualToUTF8CString(modifier, "shift"))
500         mod = kWKEventModifiersShiftKey;
501     if (JSStringIsEqualToUTF8CString(modifier, "alt"))
502         mod = kWKEventModifiersAltKey;
503     if (JSStringIsEqualToUTF8CString(modifier, "meta"))
504         mod = kWKEventModifiersMetaKey;
505
506     WKRetainPtr<WKStringRef> modifierKey(AdoptWK, WKStringCreateWithUTF8CString("Modifier"));
507     WKRetainPtr<WKUInt64Ref> modifierRef(AdoptWK, WKUInt64Create(mod));
508     WKDictionaryAddItem(EventSenderMessageBody.get(), modifierKey.get(), modifierRef.get());
509
510     WKRetainPtr<WKStringRef> enableKey(AdoptWK, WKStringCreateWithUTF8CString("Enable"));
511     WKRetainPtr<WKUInt64Ref> enableRef(AdoptWK, WKUInt64Create(enable));
512     WKDictionaryAddItem(EventSenderMessageBody.get(), enableKey.get(), enableRef.get());
513
514     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
515 }
516
517
518 void EventSendingController::setTouchPointRadius(int radiusX, int radiusY)
519 {
520     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
521     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
522
523     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
524     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("SetTouchPointRadius"));
525     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
526
527     WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("RadiusX"));
528     WKRetainPtr<WKUInt64Ref> xRef(AdoptWK, WKUInt64Create(radiusX));
529     WKDictionaryAddItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
530
531     WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("RadiusY"));
532     WKRetainPtr<WKUInt64Ref> yRef(AdoptWK, WKUInt64Create(radiusY));
533     WKDictionaryAddItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
534
535     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
536 }
537
538 void EventSendingController::touchStart()
539 {
540     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
541     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
542
543     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
544     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("TouchStart"));
545     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
546
547     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
548 }
549
550 void EventSendingController::touchMove()
551 {
552     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
553     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
554
555     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
556     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("TouchMove"));
557     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
558
559     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
560 }
561
562 void EventSendingController::touchEnd()
563 {
564     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
565     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
566
567     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
568     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("TouchEnd"));
569     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
570
571     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
572 }
573
574 void EventSendingController::touchCancel()
575 {
576     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
577     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
578
579     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
580     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("TouchCancel"));
581     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
582
583     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
584 }
585
586 void EventSendingController::clearTouchPoints()
587 {
588     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
589     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
590
591     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
592     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("ClearTouchPoints"));
593     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
594
595     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
596 }
597
598 void EventSendingController::releaseTouchPoint(int index)
599 {
600     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
601     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
602
603     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
604     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("ReleaseTouchPoint"));
605     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
606
607     WKRetainPtr<WKStringRef> indexKey(AdoptWK, WKStringCreateWithUTF8CString("Index"));
608     WKRetainPtr<WKUInt64Ref> indexRef(AdoptWK, WKUInt64Create(index));
609     WKDictionaryAddItem(EventSenderMessageBody.get(), indexKey.get(), indexRef.get());
610
611     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
612 }
613
614 void EventSendingController::cancelTouchPoint(int index)
615 {
616     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
617     WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
618
619     WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
620     WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("CancelTouchPoint"));
621     WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
622
623     WKRetainPtr<WKStringRef> indexKey(AdoptWK, WKStringCreateWithUTF8CString("Index"));
624     WKRetainPtr<WKUInt64Ref> indexRef(AdoptWK, WKUInt64Create(index));
625     WKDictionaryAddItem(EventSenderMessageBody.get(), indexKey.get(), indexRef.get());
626
627     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
628 }
629 #endif
630
631 // Object Creation
632
633 void EventSendingController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
634 {
635     setProperty(context, windowObject, "eventSender", this, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
636 }
637
638 } // namespace WTR