GTK Webkit 添加JS对象

来源:互联网 发布:知乎.基金公司面试 编辑:程序博客网 时间:2024/05/09 20:51
 

尽管GTK Webkit没有类似于QT Webkit 的 addToJavaScriptWindowObject()接口,
但我们还是可以利用JavascriptCore的接口函数来实现对Javascript扩展对象的
添加, 只不过过程会稍微复杂一点。

首先要定义一个JSClassRef结构, 该结构用来指定类的成员函数,属性等信息,
然后调用JSClassCreate()接口来创建这个类, 创建成功后, 调用JSObjectMake()接口
把该类结构转换为一个Javascript对象, 最后把该对象设置到Javascript的上下文环境即可。
说起来啰嗦, 实现起来也是比较容易,具体可以参考示例代码。

同样要注意在跨页面的时候,该对象会被清除,所以要重新加回来,方法很简单,
只要捕获window-object-cleared信号即可,在该信号处理函数里面执行增加对象
的操作即可。

参考示例代码如下:

// 类创建函数:
JSClassRef Foo_ClassCreate(JSContextRef ctx)
{
    static JSClassRef fooClass = NULL;
    if (fooClass) {
        // already created, just return
        return fooClass;
    }
 
   
    JSStaticFunction fooStaticFunctions[] = {
        { "print",           foo_Print,           kJSPropertyAttributeNone },
        { NULL, 0, 0 },
    };
   
   
    JSStaticFunction fooStaticValues[] = {
        { "Verbose",   foo_GetVerbose,  NULL,  kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
        { NULL, 0, 0, 0},
    };
   
   
    JSClassDefinition classdef = kJSClassDefinitionEmpty;
    classdef.className         = "Foo";
    classdef.initialize        = foo_Initialize;
    classdef.finalize          = foo_Finalize;
    classdef.staticValues      = fooStaticValues;
    classdef.staticFunctions   = fooStaticFunctions;

    return fooClass = JSClassCreate(&classdef);
}

void foo_Initialize(JSContextRef ctx, JSObjectRef object)
{
}

void foo_Finalize(JSObjectRef object)
{
}

JSValueRef foo_GetVerbose(
           JSContextRef ctx,
           JSObjectRef  object,
           JSStringRef  propertyName,
           JSValueRef  *exception)
{
    // verbose is false
    return JSValueMakeBoolean(ctx, false);
}

JSValueRef foo_Print(JSContextRef ctx,
                       JSObjectRef function,
                       JSObjectRef thisObject,
                       size_t argumentCount,
                       const JSValueRef arguments[],
                       JSValueRef *exception)
{
 JSStringRef str = JSValueToStringCopy(ctx, arguments[0], exception);
 size_t size = JSStringGetMaximumUTF8CStringSize(str);
 char* utf8 = new char [size];
 
 JSStringGetUTF8CString(str, utf8, size);
 
 fprintf(stderr, "utf8 = %s(%u)\n", utf8, size);

 return JSValueMakeNull(ctx);
}

// window-object-cleared信号处理函数
JSStringRef className = JSStringCreateWithUTF8CString("MediaPlayer");
 assert(className != NULL);
 JSObjectRef classObj = JSObjectMake(ctx, JSMP_ConstructorClassCreate(ctx), ctx);
 
 JSObjectSetProperty(ctx, JSContextGetGlobalObject(ctx), className, classObj,
                   kJSPropertyAttributeNone, NULL);

 if (className != NULL) JSStringRelease(className);
 
void foo_WindowObjectClearedCB(
            WebKitWebView  *wv,
            WebKitWebFrame *wf,
            gpointer        ctx,
            gpointer        arg3,
            gpointer        user_data)
{
    JSStringRef name = JSStringCreateWithUTF8CString("Foo");
    // Make the javascript object
    JSObjectRef obj = JSObjectMake(ctx, Foo_ClassCreate(ctx), NULL);
    // Set the property
    JSObjectSetProperty(ctx, JSContextGetGlobalObject(ctx), name, obj,kJSPropertyAttributeNone, NULL);
}

// 安装信号
在GTK应用中创建浏览器的时候,用以下代码来安装window-object-cleared信号即可。
WebKitWebView *view = WEBKIT_WEB_VIEW (webkit_web_view_new ());
g_signal_connect(G_OBJECT (view), "window-object-cleared", G_CALLBACK(foo_WindowObjectClearedCB), view);


//HTML测试代码:

<script>
Foo.print("Hello world!");
</script>

原创粉丝点击