12fc2651226baac27029e38c9d6ef883fa32084dbSteve Block/* 22fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * Copyright (C) 2011 Igalia S.L. 32fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * 42fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * Redistribution and use in source and binary forms, with or without 52fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * modification, are permitted provided that the following conditions 62fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * are met: 72fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * 82fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * 1. Redistributions of source code must retain the above copyright 92fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * notice, this list of conditions and the following disclaimer. 102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * 2. Redistributions in binary form must reproduce the above copyright 112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * notice, this list of conditions and the following disclaimer in the 122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * documentation and/or other materials provided with the distribution. 132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * its contributors may be used to endorse or promote products derived 152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * from this software without specific prior written permission. 162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * 172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block */ 282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "config.h" 302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "TextInputController.h" 312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "DumpRenderTree.h" 332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "WebCoreSupport/DumpRenderTreeSupportGtk.h" 342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <GOwnPtrGtk.h> 352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <JavaScriptCore/JSObjectRef.h> 362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <JavaScriptCore/JSRetainPtr.h> 372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <JavaScriptCore/JSStringRef.h> 382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <cstring> 392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <webkit/webkit.h> 402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 412fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic JSValueRef setMarkedTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) 422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!view) 452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSValueMakeUndefined(context); 462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (argumentCount < 3) 482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSValueMakeUndefined(context); 492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSStringRef string = JSValueToStringCopy(context, arguments[0], exception); 512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); 522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block size_t bufferSize = JSStringGetMaximumUTF8CStringSize(string); 542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block GOwnPtr<gchar> stringBuffer(static_cast<gchar*>(g_malloc(bufferSize))); 552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSStringGetUTF8CString(string, stringBuffer.get(), bufferSize); 562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSStringRelease(string); 572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int start = static_cast<int>(JSValueToNumber(context, arguments[1], exception)); 592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); 602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int end = static_cast<int>(JSValueToNumber(context, arguments[2], exception)); 622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); 632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block DumpRenderTreeSupportGtk::setComposition(view, stringBuffer.get(), start, end); 652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSValueMakeUndefined(context); 672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 692fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic JSValueRef insertTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) 702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!view) 732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSValueMakeUndefined(context); 742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (argumentCount < 1) 762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSValueMakeUndefined(context); 772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSStringRef string = JSValueToStringCopy(context, arguments[0], exception); 792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); 802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block size_t bufferSize = JSStringGetMaximumUTF8CStringSize(string); 822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block GOwnPtr<gchar> stringBuffer(static_cast<gchar*>(g_malloc(bufferSize))); 832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSStringGetUTF8CString(string, stringBuffer.get(), bufferSize); 842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSStringRelease(string); 852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block DumpRenderTreeSupportGtk::confirmComposition(view, stringBuffer.get()); 872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSValueMakeUndefined(context); 892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 912fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic JSValueRef unmarkTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) 922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!view) 952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSValueMakeUndefined(context); 962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block DumpRenderTreeSupportGtk::confirmComposition(view, 0); 982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSValueMakeUndefined(context); 992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1012fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic JSValueRef firstRectForCharacterRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) 1022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 1042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!view) 1052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSValueMakeUndefined(context); 1062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (argumentCount < 2) 1082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSValueMakeUndefined(context); 1092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int location = static_cast<int>(JSValueToNumber(context, arguments[0], exception)); 1112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); 1122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int length = static_cast<int>(JSValueToNumber(context, arguments[1], exception)); 1142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); 1152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block GdkRectangle rect; 1172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!DumpRenderTreeSupportGtk::firstRectForCharacterRange(view, location, length, &rect)) 1182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSValueMakeUndefined(context); 1192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSValueRef arrayValues[4]; 1212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block arrayValues[0] = JSValueMakeNumber(context, rect.x); 1222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block arrayValues[1] = JSValueMakeNumber(context, rect.y); 1232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block arrayValues[2] = JSValueMakeNumber(context, rect.width); 1242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block arrayValues[3] = JSValueMakeNumber(context, rect.height); 1252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSObjectRef arrayObject = JSObjectMakeArray(context, 4, arrayValues, exception); 1262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); 1272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return arrayObject; 1292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1312fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic JSValueRef selectedRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) 1322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); 1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!view) 1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSValueMakeUndefined(context); 1362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int start, end; 1382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!DumpRenderTreeSupportGtk::selectedRange(view, &start, &end)) 1392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSValueMakeUndefined(context); 1402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSValueRef arrayValues[2]; 1422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block arrayValues[0] = JSValueMakeNumber(context, start); 1432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block arrayValues[1] = JSValueMakeNumber(context, end); 1442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSObjectRef arrayObject = JSObjectMakeArray(context, 2, arrayValues, exception); 1452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); 1462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return arrayObject; 1482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1502fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic JSStaticFunction staticFunctions[] = { 1512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block { "setMarkedText", setMarkedTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 1522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block { "insertText", insertTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 1532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block { "unmarkText", unmarkTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 1542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block { "firstRectForCharacterRange", firstRectForCharacterRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 1552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block { "selectedRange", selectedRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 1562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block { 0, 0, 0 } 1572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}; 1582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1592fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic JSClassRef getClass(JSContextRef context) 1602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static JSClassRef textInputControllerClass = 0; 1622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!textInputControllerClass) { 1642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSClassDefinition classDefinition = { 1652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 0, 0, 0, 0, 0, 0, 1662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 1672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block classDefinition.staticFunctions = staticFunctions; 1682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block textInputControllerClass = JSClassCreate(&classDefinition); 1702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return textInputControllerClass; 1732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1752fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockJSObjectRef makeTextInputController(JSContextRef context) 1762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return JSObjectMake(context, getClass(context), 0); 1782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 179