webkit js扩展方式之Binding添加新DOM对象

来源:互联网 发布:简明python教程 chm 编辑:程序博客网 时间:2024/05/20 18:44

webkit js Binding添加新DOM对象

一.基础知识

首先WebKit IDL并非完全遵循Web IDL,只是借鉴使用。WebKit官网提供了一份说明(WebKitIDL),比如Web IDL称"operation”(操作), 而WebKitIDL称为"method"(方法),具体详细定义请参见:http://trac.webkit.org/wiki/WebKitIDL

 

二.内置对象实现

a.添加新代码(可以参考DOMWindowNavigator实现)

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,添加IDLCPP文件路径。

  

到此,添加内置对象就完成了!!!

 

 

二.本地对象实现(网上一些资料实现非常复杂,实际新版本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中即可

0 0
原创粉丝点击