尽管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>