免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1545 | 回复: 0

Adding custom Javascript object to WebKIT [复制链接]

论坛徽章:
0
发表于 2011-12-20 09:48 |显示全部楼层

This post will show you how to add custom objects / functions which are implemented in C but used in a Javascript that's part of a HTML document that WebKIT renders. We will add a class "myclass" to the Javascript engine instance and it will have one static function named "mymethod()" that returns a single string.

First you need to install all the needed dependencies, assuming you are using Ubuntu or other Debian based system run the following command as root:

    * apt-get install libwebkit-1.0-2 libwebkit-dev

The following very simple HTML page will be used to test that the Javascript binding to the native C function works properly.

simple.html

<html>
<body>
<h1>String in html</h1>

<script type="text/javascript">
document.write("<h1>String from JS:");
document.write(myclass.mymethod());
document.write("</h1>");
</script>

</body>
</html>


C implementation of myclass.mymethod()

mymethod() will be implemented as a static function on the myclass object. The JavaScript framework used by WebKIT can be used with an API that's documented on Apple's pages. The important thing for this simple class is the JSClassDefinition and JSStaticFunction struct both have to be filled out with information about our class, including its static function(s) (mymethod), initialize/constructor callback, finalize/destructor callback and so on. To add the class to the Javascript engine we need something called the JSGlobalContextRef, how you get it depends on the flavor of WebKIT you are using. In this tutorial I will show how to do it with the GTK port of WebKIT. Connect a handler to the window-object-cleared signal which is sent when a new page is loaded (found this out after a lot of googling, reference). In the callback you connect you can call webkit_web_frame_get_global_context(), it will return the JSGlobalContextRef you need.

Enough talking, here is the actual source code for the example,


#include <gtk/gtk.h>
#include <webkit/webkit.h>
#include <JavaScriptCore/JavaScript.h>

static void myclass_init_cb(JSContextRef ctx, JSObjectRef object)
{
// ...
}

static void myclass_finalize_cb(JSObjectRef object)
{
// ...
}

static JSValueRef myclass_mymethod(JSContextRef context,
                       JSObjectRef function,
                       JSObjectRef thisObject,
                       size_t argumentCount,
                       const JSValueRef arguments[],
                       JSValueRef *exception)
{
JSStringRef string = JSStringCreateWithUTF8CString("mystring");
return JSValueMakeString(context, string);
}

static const JSStaticFunction class_staticfuncs[] =
{
{ "mymethod", myclass_mymethod, kJSPropertyAttributeReadOnly },
{ NULL, NULL, 0 }
};

static const JSClassDefinition class_def =
{
0,
kJSClassAttributeNone,
"myclass",
NULL,

NULL,
class_staticfuncs,

myclass_init_cb,
myclass_finalize_cb,

NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};

static void addJSClasses(JSGlobalContextRef context)
{
JSClassRef classDef = JSClassCreate(&class_def);
JSObjectRef classObj = JSObjectMake(context, classDef, context);
JSObjectRef globalObj = JSContextGetGlobalObject(context);
JSStringRef str = JSStringCreateWithUTF8CString("myclass");
JSObjectSetProperty(context, globalObj, str, classObj,
                   kJSPropertyAttributeNone, NULL);
}

static void window_object_cleared_cb(WebKitWebView  *web_view,
                                WebKitWebFrame *frame,
                                gpointer        context,
                                gpointer        arg3,
                                gpointer        user_data)

{
JSGlobalContextRef jsContext = webkit_web_frame_get_global_context(frame);
addJSClasses(jsContext);
}

static GtkWidget* main_window;
static WebKitWebView* web_view;

static void destroy_cb(GtkWidget* widget, gpointer data)
{
gtk_main_quit ();
}

static GtkWidget* create_browser()
{
GtkWidget* scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ());
gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (web_view));

g_signal_connect (G_OBJECT (web_view), "window-object-cleared", G_CALLBACK(window_object_cleared_cb), web_view);

return scrolled_window;
}

static GtkWidget* create_window()
{
GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW (window), 500, 500);
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy_cb), NULL);
return window;
}

int main (int argc, char* argv[])
{
gtk_init (&argc, &argv);
if (!g_thread_supported())
   g_thread_init (NULL);

GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), create_browser (), TRUE, TRUE, 0);

main_window = create_window();
gtk_container_add(GTK_CONTAINER (main_window), vbox);

gchar* uri = (gchar*) "file://simple.html";
webkit_web_view_open(web_view, uri);                      

gtk_widget_grab_focus (GTK_WIDGET (web_view));
gtk_widget_show_all (main_window);
gtk_main ();

return 0;
}

Compile & Test

Finally, to compile and test the example code run the following commands:

    * gcc test.c -o test `pkg-config --cflags --libs webkit-1.0`
    * ./test
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP