[EFL] [DRT] Implement scheduleAsynchronousKeyDown.
[WebKit-https.git] / Tools / DumpRenderTree / efl / EventSender.cpp
index 7a4ca30..5934d4c 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2009 Holger Hans Peter Freyther
  * Copyright (C) 2010 Igalia S.L.
  * Copyright (C) 2011 ProFUSION Embedded Systems
- * Copyright (C) 2011 Samsung Electronics
+ * Copyright (C) 2011, 2012 Samsung Electronics
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -103,6 +103,17 @@ enum ZoomEvent {
     ZoomOut
 };
 
+struct KeyEventInfo {
+    KeyEventInfo(const char* keyName, EvasKeyModifier modifiers)
+        : keyName(keyName)
+        , modifiers(modifiers)
+    {
+    }
+
+    const char* keyName;
+    EvasKeyModifier modifiers;
+};
+
 static void setEvasModifiers(Evas* evas, EvasKeyModifier modifiers)
 {
     static const char* modifierNames[] = { "Control", "Shift", "Alt", "Super" };
@@ -399,14 +410,13 @@ static const char* keyNameFromJSValue(JSStringRef character)
     return 0;
 }
 
-static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+static KeyEventInfo* createKeyEventInfo(JSContextRef context, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
-    Evas_Object* view = ewk_frame_view_get(browser->mainFrame());
-    if (!view)
-        return JSValueMakeUndefined(context);
+    if (!ewk_frame_view_get(browser->mainFrame()))
+        return 0;
 
     if (argumentCount < 1)
-        return JSValueMakeUndefined(context);
+        return 0;
 
     // handle location argument.
     int location = DomKeyLocationStandard;
@@ -415,25 +425,44 @@ static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JS
 
     JSRetainPtr<JSStringRef> character(Adopt, JSValueToStringCopy(context, arguments[0], exception));
     if (exception && *exception)
-        return JSValueMakeUndefined(context);
+        return 0;
 
-    // send the event
-    Evas* evas = evas_object_evas_get(view);
+    EvasKeyModifier modifiers = EvasKeyModifierNone;
     if (argumentCount >= 2)
-        setEvasModifiers(evas, modifiersFromJSValue(context, arguments[1]));
+        modifiers = modifiersFromJSValue(context, arguments[1]);
 
     const CString cCharacter = character.get()->ustring().utf8();
     const char* keyName = (location == DomKeyLocationNumpad) ? keyPadNameFromJSValue(character.get()) : keyNameFromJSValue(character.get());
-
     if (!keyName)
         keyName = cCharacter.data();
 
+    return new KeyEventInfo(keyName, modifiers);
+}
+
+static void sendKeyDown(Evas* evas, KeyEventInfo* keyEventInfo)
+{
+    if (!keyEventInfo)
+        return;
+
+    const char* keyName = keyEventInfo->keyName;
+    EvasKeyModifier modifiers = keyEventInfo->modifiers;
+
     DumpRenderTreeSupportEfl::layoutFrame(browser->mainFrame());
+
+    ASSERT(evas);
+    setEvasModifiers(evas, modifiers);
     evas_event_feed_key_down(evas, keyName, keyName, keyName, 0, 0, 0);
     evas_event_feed_key_up(evas, keyName, keyName, keyName, 0, 1, 0);
-
     setEvasModifiers(evas, EvasKeyModifierNone);
 
+    DumpRenderTreeSupportEfl::deliverAllMutationsIfNecessary();
+}
+
+static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    OwnPtr<KeyEventInfo> keyEventInfo = adoptPtr(createKeyEventInfo(context, argumentCount, arguments, exception));
+    sendKeyDown(evas_object_evas_get(browser->mainFrame()), keyEventInfo.get());
+
     return JSValueMakeUndefined(context);
 }
 
@@ -508,6 +537,20 @@ static JSValueRef zoomPageOutCallback(JSContextRef context, JSObjectRef function
     return JSValueMakeUndefined(context);
 }
 
+static Eina_Bool sendAsynchronousKeyDown(void* userData)
+{
+    OwnPtr<KeyEventInfo> keyEventInfo = adoptPtr(static_cast<KeyEventInfo*>(userData));
+    sendKeyDown(evas_object_evas_get(browser->mainFrame()), keyEventInfo.get());
+    return ECORE_CALLBACK_CANCEL;
+}
+
+static JSValueRef scheduleAsynchronousKeyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    KeyEventInfo* keyEventInfo = createKeyEventInfo(context, argumentCount, arguments, exception);
+    ecore_idler_add(sendAsynchronousKeyDown, static_cast<void*>(keyEventInfo));
+    return JSValueMakeUndefined(context);
+}
+
 static JSStaticFunction staticFunctions[] = {
     { "mouseScrollBy", mouseScrollByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
     { "continuousMouseScrollBy", continuousMouseScrollByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
@@ -516,6 +559,7 @@ static JSStaticFunction staticFunctions[] = {
     { "mouseMoveTo", mouseMoveToCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
     { "keyDown", keyDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
     { "scheduleAsynchronousClick", scheduleAsynchronousClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+    { "scheduleAsynchronousKeyDown", scheduleAsynchronousKeyDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
     { "scalePageBy", scalePageByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
     { "textZoomIn", textZoomInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
     { "textZoomOut", textZoomOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },