在 QT 目录中打开下面的文件:
/src/3rdparty/webkit/JavaScriptCore/bindings/runtime.cpp
有下面几行:
- #ifPLATFORM(QT)
- caseInstance::QtLanguage:{
- newInstance=Bindings::QtInstance::getQtInstance((QObject*)nativeInstance,rootObject);
- break;
- }
- #endif
这就表明,可以用 QtLanguage 来编写自定义的 javascript 对象。这里也有几个别的 Language,也就是说可以用它们来编写扩展 javascript 对象,应该也能自定义自己的 Language。既然是用 qt 的 GUI,使用 QtLanguage 应该是最合适的。
先打开它的例子文件:
/src/3rdparty/webkit/JavaScriptCore/bindings/testqtbindings.cpp
可以看到其中有这样几行:
- staticcharcode[]=
- "myInterface.foo();/n"
- "myInterface.testString=/"Hello/";/n"
- "str=myInterface.testString;/n"
- "myInterface.testInt=10;/n"
- "i=myInterface.testInt;/n";
这就是说,testqtbindings.cpp 的内容可以对下面的 javascript 进行解析:
- myInterface.foo();
- myInterface.testString="Hello";
- varstr=myInterface.testString;
- myInterface.testInt=10;
- vari=myInterface.testInt;
我想定义自己的 javascript,比如在 myInterface 对象前面加上一个 CSDN 对象:
- CSDN.myInterface.foo();
- CSDN.myInterface.testString="Hello";
- varstr=CSDN.myInterface.testString;
这件事情本来很简单,可是就象 CSDN.myInterface.foo() 这样,连接 CSDN 和 myInterface 两个对象的事情,在网上(中文和英文网站)找了半天没找着,结果还是我自己想到的。
1. 在原来的文件中再添加一个 MyCSDNObject 对象:
- classMyCSDNObject:publicQObject
- {
- Q_OBJECT
- Q_PROPERTY(QStringtestStringREADtestStringWRITEsetTestString)
- Q_PROPERTY(inttestIntREADtestIntWRITEsetTestInt)
-
- Q_PROPERTY(QObject*myInterfaceREADtestMyInterface)
- public:
- MyCSDNObject():QObject(0),integer(0),m_myObject(NULL){}
- voidsetTestString(constQString&str){
- qDebug()<<"calledsetTestString"<<str;
- string=str;
- }
- voidsetTestInt(inti){
- qDebug()<<"calledsetTestInt"<<i;
- integer=i;
- }
- QStringtestString()const{
- qDebug()<<"calledtestString"<<string;
- returnstring;
- }
- inttestInt()const{
- qDebug()<<"calledtestInt"<<integer;
- returninteger;
- }
-
- QObject*testMyInterface()
- {
- if(m_myObject==NULL)
- m_myObject=newMyObject();
- returnm_myObject;
- }
- QStringstring;
- intinteger;
-
- MyObject*m_myObject;
- publicslots:
- voidfoo(){qDebug()<<"fooinvoked";}
- };
这样 MyCSDNObject 和 MyObject 这样两个对象就可以连起来了,成为 CSDN.testMyInterface
2. 修改一下创建的根对象的名字
- global->put(exec,Identifier("CSDN"),Instance::createRuntimeObject(Instance::QtLanguage,(void*)myObject));
这样就可以了。这是个测试程序,需要把这些测试代码添加到 WebKit 浏览器中。打开文件:
./src/3rdparty/webkit/WebKit/qt/Api/qwebframe.h
把刚才的 MyObject 类和 MyCSDNObject 类在其中声名一下,然后添加CSDN 根对象作为QWebFrame 类的私有成员,如下所示:
- classMyObject:publicQObject
- {
- Q_OBJECT
-
- };
- classMyCSDNObject:publicQObject
- {
- Q_OBJECT
-
- };
- classQWEBKIT_EXPORTQWebFrame:publicQObject
- {
- Q_OBJECT
- Q_PROPERTY(qrealtextSizeMultiplierREADtextSizeMultiplierWRITEsetTextSizeMultiplier)
- Q_PROPERTY(QStringtitleREADtitle)
- Q_PROPERTY(QUrlurlREADurlWRITEsetUrl)
- Q_PROPERTY(QIconiconREADicon)
- Q_PROPERTY(QSizecontentsSizeREADcontentsSize)
- private:
- QWebFrame(QWebPage*parent,QWebFrameData*frameData);
- QWebFrame(QWebFrame*parent,QWebFrameData*frameData);
- ~QWebFrame();
-
- MyCSDNObject*m_csdn;
- public:
-
- };
打开 qwebframe.cpp 文件,在 QWebFrame 的构造函数中创建 CSDN 根对象。
- QWebFrame::QWebFrame(QWebPage*parent,QWebFrameData*frameData)
- :QObject(parent)
- ,d(newQWebFramePrivate)
- {
- d->page=parent;
- d->init(this,parent->d->page,frameData);
-
- {
- KJS::Bindings::RootObject*root=d->frame->bindingRootObject();
- KJS::ExecState*exec=root->interpreter()->globalExec();
- KJS::JSObject*global=root->interpreter()->globalObject();
- m_csdn=newMyCSDNObject();
- global->put(exec,KJS::Identifier("CSDN"),KJS::Bindings::Instance::createRuntimeObject(KJS::Bindings::Instance::QtLanguage,(void*)m_csdn,root));
- }
- if(!frameData->url.isEmpty()){
- ResourceRequestrequest(frameData->url,frameData->referrer);
- d->frame->loader()->load(request,frameData->name);
- }
- }
在 QWebFrame 的析构函数中删除 CSDN 根对象
- QWebFrame::~QWebFrame()
- {
- if(d->frame&&d->frame->loader()&&d->frame->loader()->client())
- static_cast(d->frame->loader()->client())->m_webFrame=0;
- if(m_csdn)
- {
- deletem_csdn;
- m_csdn=NULL;
- }
- deleted;
- }
再手工编写一个 HTML 测试页 csdn1.htm,内容如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title> New Document </title> <script language="JavaScript"> <!-- function test() { CSDN.myInterface.foo(); CSDN.myInterface.testString = "Hello QtWebKit JavaScript"; var str = CSDN.myInterface.testString; document.getElementById("txtMessage").innerHTML = str; } //--> </script> </head> <body> <p><a href="javascript:test();">test qt-webkit javascript</a></p> <p id="txtMessage"></p> </body> </html> |
编译并运行WebKit 浏览器,让它打开刚才的测试页 csdn1.htm,点击上面的 test qt-webkit javascript 链接,可以得到下面的效果:
上面的 Hello QtWebKit JavaScript 就是 javascript 设置的 CSDN.myInterface.testString内容。
在 QT 目录中打开下面的文件:
/src/3rdparty/webkit/JavaScriptCore/bindings/runtime.cpp
有下面几行:
- #ifPLATFORM(QT)
- caseInstance::QtLanguage:{
- newInstance=Bindings::QtInstance::getQtInstance((QObject*)nativeInstance,rootObject);
- break;
- }
- #endif
这就表明,可以用 QtLanguage 来编写自定义的 javascript 对象。这里也有几个别的 Language,也就是说可以用它们来编写扩展 javascript 对象,应该也能自定义自己的 Language。既然是用 qt 的 GUI,使用 QtLanguage 应该是最合适的。
先打开它的例子文件:
/src/3rdparty/webkit/JavaScriptCore/bindings/testqtbindings.cpp
可以看到其中有这样几行:
- staticcharcode[]=
- "myInterface.foo();/n"
- "myInterface.testString=/"Hello/";/n"
- "str=myInterface.testString;/n"
- "myInterface.testInt=10;/n"
- "i=myInterface.testInt;/n";
这就是说,testqtbindings.cpp 的内容可以对下面的 javascript 进行解析:
- myInterface.foo();
- myInterface.testString="Hello";
- varstr=myInterface.testString;
- myInterface.testInt=10;
- vari=myInterface.testInt;
我想定义自己的 javascript,比如在 myInterface 对象前面加上一个 CSDN 对象:
- CSDN.myInterface.foo();
- CSDN.myInterface.testString="Hello";
- varstr=CSDN.myInterface.testString;
这件事情本来很简单,可是就象 CSDN.myInterface.foo() 这样,连接 CSDN 和 myInterface 两个对象的事情,在网上(中文和英文网站)找了半天没找着,结果还是我自己想到的。
1. 在原来的文件中再添加一个 MyCSDNObject 对象:
- classMyCSDNObject:publicQObject
- {
- Q_OBJECT
- Q_PROPERTY(QStringtestStringREADtestStringWRITEsetTestString)
- Q_PROPERTY(inttestIntREADtestIntWRITEsetTestInt)
-
- Q_PROPERTY(QObject*myInterfaceREADtestMyInterface)
- public:
- MyCSDNObject():QObject(0),integer(0),m_myObject(NULL){}
- voidsetTestString(constQString&str){
- qDebug()<<"calledsetTestString"<<str;
- string=str;
- }
- voidsetTestInt(inti){
- qDebug()<<"calledsetTestInt"<<i;
- integer=i;
- }
- QStringtestString()const{
- qDebug()<<"calledtestString"<<string;
- returnstring;
- }
- inttestInt()const{
- qDebug()<<"calledtestInt"<<integer;
- returninteger;
- }
-
- QObject*testMyInterface()
- {
- if(m_myObject==NULL)
- m_myObject=newMyObject();
- returnm_myObject;
- }
- QStringstring;
- intinteger;
-
- MyObject*m_myObject;
- publicslots:
- voidfoo(){qDebug()<<"fooinvoked";}
- };
这样 MyCSDNObject 和 MyObject 这样两个对象就可以连起来了,成为 CSDN.testMyInterface
2. 修改一下创建的根对象的名字
- global->put(exec,Identifier("CSDN"),Instance::createRuntimeObject(Instance::QtLanguage,(void*)myObject));
这样就可以了。这是个测试程序,需要把这些测试代码添加到 WebKit 浏览器中。打开文件:
./src/3rdparty/webkit/WebKit/qt/Api/qwebframe.h
把刚才的 MyObject 类和 MyCSDNObject 类在其中声名一下,然后添加CSDN 根对象作为QWebFrame 类的私有成员,如下所示:
- classMyObject:publicQObject
- {
- Q_OBJECT
-
- };
- classMyCSDNObject:publicQObject
- {
- Q_OBJECT
-
- };
- classQWEBKIT_EXPORTQWebFrame:publicQObject
- {
- Q_OBJECT
- Q_PROPERTY(qrealtextSizeMultiplierREADtextSizeMultiplierWRITEsetTextSizeMultiplier)
- Q_PROPERTY(QStringtitleREADtitle)
- Q_PROPERTY(QUrlurlREADurlWRITEsetUrl)
- Q_PROPERTY(QIconiconREADicon)
- Q_PROPERTY(QSizecontentsSizeREADcontentsSize)
- private:
- QWebFrame(QWebPage*parent,QWebFrameData*frameData);
- QWebFrame(QWebFrame*parent,QWebFrameData*frameData);
- ~QWebFrame();
-
- MyCSDNObject*m_csdn;
- public:
-
- };
打开 qwebframe.cpp 文件,在 QWebFrame 的构造函数中创建 CSDN 根对象。
- QWebFrame::QWebFrame(QWebPage*parent,QWebFrameData*frameData)
- :QObject(parent)
- ,d(newQWebFramePrivate)
- {
- d->page=parent;
- d->init(this,parent->d->page,frameData);
-
- {
- KJS::Bindings::RootObject*root=d->frame->bindingRootObject();
- KJS::ExecState*exec=root->interpreter()->globalExec();
- KJS::JSObject*global=root->interpreter()->globalObject();
- m_csdn=newMyCSDNObject();
- global->put(exec,KJS::Identifier("CSDN"),KJS::Bindings::Instance::createRuntimeObject(KJS::Bindings::Instance::QtLanguage,(void*)m_csdn,root));
- }
- if(!frameData->url.isEmpty()){
- ResourceRequestrequest(frameData->url,frameData->referrer);
- d->frame->loader()->load(request,frameData->name);
- }
- }
在 QWebFrame 的析构函数中删除 CSDN 根对象
- QWebFrame::~QWebFrame()
- {
- if(d->frame&&d->frame->loader()&&d->frame->loader()->client())
- static_cast(d->frame->loader()->client())->m_webFrame=0;
- if(m_csdn)
- {
- deletem_csdn;
- m_csdn=NULL;
- }
- deleted;
- }
再手工编写一个 HTML 测试页 csdn1.htm,内容如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title> New Document </title> <script language="JavaScript"> <!-- function test() { CSDN.myInterface.foo(); CSDN.myInterface.testString = "Hello QtWebKit JavaScript"; var str = CSDN.myInterface.testString; document.getElementById("txtMessage").innerHTML = str; } //--> </script> </head> <body> <p><a href="javascript:test();">test qt-webkit javascript</a></p> <p id="txtMessage"></p> </body> </html> |
编译并运行WebKit 浏览器,让它打开刚才的测试页 csdn1.htm,点击上面的 test qt-webkit javascript 链接,可以得到下面的效果:
上面的 Hello QtWebKit JavaScript 就是 javascript 设置的 CSDN.myInterface.testString内容。