webkit js Binding添加新DOM对象
一.基础知识
首先WebKit IDL并非完全遵循Web IDL,只是借鉴使用。WebKit官网提供了一份说明(WebKitIDL),比如Web IDL称"operation”(操作), 而WebKitIDL称为"method"(方法),具体详细定义请参见:http://trac.webkit.org/wiki/WebKitIDL。
二.内置对象实现
a.添加新代码(可以参考DOMWindow的Navigator实现)
OipfObjectFactory.h(代码已省略)
#ifndef OipfObjectFactory_h
#define OipfObjectFactory_h
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
class OipfObjectFactory : publicRefCounted<OipfObjectFactory> {
public:
static PassRefPtr<OipfObjectFactory>create(Frame* frame)
{
return adoptRef(new OipfObjectFactory(frame));
}
Frame*frame() const;
virtual~OipfObjectFactory();
boolisObjectSupported(const String& mimeType);
//supported objects
PassRefPtr<Element>createVideoBroadcastObject(ExceptionCode& ec);
PassRefPtr<Element> createVideoMpegObject(ExceptionCode& ec);
PassRefPtr<Element>createApplicationManagerObject(ExceptionCode& ec);
PassRefPtr<Element> createConfigurationObject(ExceptionCode&ec);
PassRefPtr<Element> createDownloadManagerObject(ExceptionCode&ec);
PassRefPtr<Element> createDrmAgentObject(ExceptionCode& ec);
PassRefPtr<Element>createParentalControlManagerObject(ExceptionCode& ec);
PassRefPtr<Element>createCapabilitiesObject(ExceptionCode& ec);
private:
OipfObjectFactory(Frame*);
Frame*m_frame;
};
} // namespace WebCore
#endif // OipfObjectFactory_h
OipfObjectFactory.cpp可以略过
主要是OipfObjectFactory.IDL:
[
] interface OipfObjectFactory {
booleanisObjectSupported(in DOMString mimeType);
[ReturnNewObject, RaisesException] Element createVideoBroadcastObject();
……
};
注意:
(1).以前可以定义在window或者其他模块里,现在此功能已经去除
(2).以前[ ]在interface或者属性或者函数后面写,现在写在前面,例如:
以前:Element [ReturnNewObject,RaisesException] createVideoBroadcastObject();
现在:[ReturnNewObject,RaisesException] Element createVideoBroadcastObject();
(3).以前[ ]里的关键词与现在也不同,具体详细请参照http://trac.webkit.org/wiki/WebKitIDL定义
b. 修改DOMWindow.h,添加如下代码:
class OipfObjectFactory;
……
public:
OipfObjectFactory *oipfObjectFactory ()const;
private:
mutableRefPtr< OipfObjectFactory > m_ oipfObjectFactory;
c. 修改DOMWindow.cpp,添加如下代码
OipfObjectFactory*DOMWindow:: OipfObjectFactory()const
{
if (!m_ oipfObjectFactory)
m_ oipfObjectFactory = OipfObjectFactory::create();
returnm_ oipfObjectFactory .get();
}
d. 修改DOMWindow.idl,添加如下一行 :
attribute OipfObjectFactory oipfObjectFactory;
e. 修改DerivedSources.make,参考Navigator.idl添加如下代码:
$(WebCore)/page/OipfObjectFactory.idl \
f.修改CMakeLists.txt,添加IDL和CPP文件路径。
到此,添加内置对象就完成了!!!
二.本地对象实现(网上一些资料实现非常复杂,实际新版本webkit实现早已经简化):
头文件和CPP文件同上,不会做任何改变。
主要是IDL文件:
a.当interface上的参数为Constructor,此定义可以实现一个构造器,只能调用属性,不能调用方法
头文件和CPP文件省略
DRMControlInformation.idl:
[
Constructor,
]interfaceDRMControlInformation {
[TreatReturnedNullStringAs=Undefined] attribute DOMStringdrmType;
[TreatReturnedNullStringAs=Undefined] attribute DOMStringdrmContentId;
[TreatReturnedNullStringAs=Undefined] attribute DOMStringdrmPrivateData;
};
注:这种实现方式只需要直接添加头文件和CPP文件和IDL路径到CMakeLists.txt即可,非常简单!!!
b.当interface上的参数为CustomConstructor,此定义可以实现一个构造器,只需要自定义一个JS绑定函数,就可以调用方法和属性
举其中一个Channel例子
头文件和CPP文件省略
Channel.idl:
[
CustomConstructor,
]interface Channel : Event {
const unsigned long TYPE_TV = 0;
const unsigned long TYPE_RADIO =1;
const unsigned long TYPE_OTHER = 2;
void initChannel (in DOMString typeArg,
in boolean canBubbleArg,
in boolean cancelableArg);
};
在标准定义中,这种实现需要定义绑定的cpp(如果命名为XXX,你需要写的绑定函数名就为JSXXXCustom.cpp,并放在webcore/binding/js目录下):
JSChannelCustom.cpp(自定义绑定文件,具体可参照webkit中一些绑定cpp文件):
#include "config.h"
#include"JSChannel.h"
#include "Channel.h"
#include <runtime/Error.h>
#include "Document.h"
using namespace JSC;
namespace WebCore {
EncodedJSValue JSC_HOST_CALLconstructJSChannel(ExecState* exec)
{
JSChannel* jsConstructor =jsCast<JSChannel*>(exec->callee());
RefPtr<Channel> channel;
if (!exec->argumentCount()) {
channel = Channel::create();
}
else {
String type =exec->argument(0).toWTFString(exec);
channel = Channel::create(type);
}
if (!channel.get())
return throwVMError(exec, createReferenceError(exec,"Cannot create the new instance of Channel!"));
returnJSValue::encode(CREATE_DOM_WRAPPER(jsConstructor->globalObject(), Channel,channel.get()));
}
} // namespace WebCore
最后将添加头文件和CPP文件和IDL还有自定义绑定的JSXXXCustom.CPP的路径到CMakeLists.txt中即可