| 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 { |
| 47 | (WKBundlePageRef page, WKContextMenuItemRef item) : |
| 48 | m_page(page), |
| 49 | m_item(item) { } |
| 50 | WKBundlePageRef ; |
| 51 | WKRetainPtr<WKContextMenuItemRef> ; |
| 52 | }; |
| 53 | |
| 54 | #if ENABLE(CONTEXT_MENUS) |
| 55 | static JSValueRef (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 (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 [] = { |
| 70 | { "click" , menuItemClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, |
| 71 | { 0, 0, 0 } |
| 72 | }; |
| 73 | |
| 74 | static JSStaticValue [] = { |
| 75 | { "title" , getMenuItemTitleCallback, 0, kJSPropertyAttributeReadOnly }, |
| 76 | { 0, 0, 0, 0 } |
| 77 | }; |
| 78 | |
| 79 | static void (JSObjectRef object) |
| 80 | { |
| 81 | delete static_cast<MenuItemPrivateData*>(JSObjectGetPrivate(object)); |
| 82 | } |
| 83 | |
| 84 | static JSValueRef (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 () |
| 92 | { |
| 93 | static JSClassRef = 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 | 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 | |
| 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 | 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 | |
| 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> = 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 | 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) |
| 638 | void 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 | |
| 658 | void 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 | |
| 682 | void 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 | |
| 713 | void 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 | |
| 733 | void 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 | |
| 745 | void 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 | |
| 757 | void 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 | |
| 769 | void 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 | |
| 781 | void 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 | |
| 793 | void 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 | |
| 809 | void 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 | |
| 828 | void EventSendingController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception) |
| 829 | { |
| 830 | setProperty(context, windowObject, "eventSender" , this, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception); |
| 831 | } |
| 832 | |
| 833 | } // namespace WTR |
| 834 | |