WebKit — qt javascript

來源:互聯網
上載者:User
 

在 QT 目錄中開啟下面的檔案:
/src/3rdparty/webkit/JavaScriptCore/bindings/runtime.cpp

有下面幾行:

view plaincopy to clipboardprint?

  1. #if PLATFORM(QT)   
  2.         case Instance::QtLanguage: {  
  3.             newInstance = Bindings::QtInstance::getQtInstance((QObject *)nativeInstance, rootObject);  
  4.             break;  
  5.         }  
  6. #endif  

#if PLATFORM(QT) case Instance::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

可以看到其中有這樣幾行:

view plaincopy to clipboardprint?
  1. static char code[] =  
  2.     "myInterface.foo();/n"  
  3.     "myInterface.testString = /"Hello/";/n"  
  4.     "str = myInterface.testString;/n"  
  5.     "myInterface.testInt = 10;/n"  
  6.     "i = myInterface.testInt;/n";  

static char code[] = "myInterface.foo();/n" "myInterface.testString = /"Hello/";/n" "str = myInterface.testString;/n" "myInterface.testInt = 10;/n" "i = myInterface.testInt;/n";

這就是說,testqtbindings.cpp 的內容可以對下面的 javascript 進行解析:

view plaincopy to clipboardprint?
  1. myInterface.foo();  
  2. myInterface.testString = "Hello";  
  3. var str = myInterface.testString;  
  4. myInterface.testInt = 10;  
  5. var i = myInterface.testInt;  

myInterface.foo();myInterface.testString = "Hello";var str = myInterface.testString;myInterface.testInt = 10;var i = myInterface.testInt;

我想定義自己的 javascript,比如在 myInterface 對象前面加上一個 CSDN 對象:

view plaincopy to clipboardprint?
  1. CSDN.myInterface.foo();  
  2. CSDN.myInterface.testString = "Hello";  
  3. var str = CSDN.myInterface.testString;  

CSDN.myInterface.foo();CSDN.myInterface.testString = "Hello";var str = CSDN.myInterface.testString;

這件事情本來很簡單,可是就象 CSDN.myInterface.foo() 這樣,串連 CSDN 和 myInterface 兩個對象的事情,在網上(中文和英文網站)找了半天沒找著,結果還是我自己想到的。

1. 在原來的檔案中再添加一個 MyCSDNObject 對象:

view plaincopy to clipboardprint?
  1. class MyCSDNObject : public QObject  
  2. {  
  3.     Q_OBJECT  
  4.     Q_PROPERTY(QString testString READ testString WRITE setTestString)  
  5.     Q_PROPERTY(int testInt READ testInt WRITE setTestInt)  
  6.  // 添加 QObject 成員作為 CSDN 對象的屬性,映射到 testMyInterface 函數上   
  7.  Q_PROPERTY(QObject* myInterface READ testMyInterface)  
  8.   
  9. public:  
  10.     MyCSDNObject() : QObject(0), integer(0), m_myObject(NULL){}  
  11.   
  12.     void setTestString(const QString &str) {  
  13.         qDebug() << "called setTestString" << str;  
  14.         string = str;  
  15.     }  
  16.     void setTestInt(int i) {  
  17.         qDebug() << "called setTestInt" << i;  
  18.         integer = i;  
  19.     }  
  20.     QString testString() const {  
  21.         qDebug() << "called testString" << string;  
  22.         return string;  
  23.     }  
  24.     int testInt() const {  
  25.         qDebug() << "called testInt" << integer;  
  26.         return integer;  
  27.     }  
  28.  // 在這裡返回一個 QObject 對象   
  29.  QObject *testMyInterface()  
  30.  {  
  31.   if (m_myObject == NULL)  
  32.    m_myObject = new MyObject();  
  33.   return m_myObject;  
  34.  }  
  35.     QString string;  
  36.     int integer;  
  37.  // 聲名一個 QObject 對象   
  38.  MyObject *m_myObject;  
  39.   
  40. public slots:  
  41.     void foo() { qDebug() << "foo invoked"; }  
  42. };  

class MyCSDNObject : public QObject{ Q_OBJECT Q_PROPERTY(QString testString READ testString WRITE setTestString) Q_PROPERTY(int testInt READ testInt WRITE setTestInt) // 添加 QObject 成員作為 CSDN 對象的屬性,映射到 testMyInterface 函數上 Q_PROPERTY(QObject* myInterface READ testMyInterface)public: MyCSDNObject() : QObject(0), integer(0), m_myObject(NULL){} void setTestString(const QString &str) { qDebug() << "called setTestString" << str; string = str; } void setTestInt(int i) { qDebug() << "called setTestInt" << i; integer = i; } QString testString() const { qDebug() << "called testString" << string; return string; } int testInt() const { qDebug() << "called testInt" << integer; return integer; } // 在這裡返回一個 QObject 對象 QObject *testMyInterface() { if (m_myObject == NULL) m_myObject = new MyObject(); return m_myObject; } QString string; int integer; // 聲名一個 QObject 對象 MyObject *m_myObject;public slots: void foo() { qDebug() << "foo invoked"; }};

這樣 MyCSDNObject 和 MyObject 這樣兩個對象就可以連起來了,成為 CSDN.testMyInterface

2. 修改一下建立的根對象的名字

view plaincopy to clipboardprint?

  1. global->put(exec, Identifier("CSDN"), Instance::createRuntimeObject(Instance::QtLanguage, (void*)myObject));  

global->put(exec, Identifier("CSDN"), Instance::createRuntimeObject(Instance::QtLanguage, (void*)myObject));

 
這樣就可以了。這是個測試程式,需要把這些測試代碼添加到 WebKit 瀏覽器中。開啟檔案:
./src/3rdparty/webkit/WebKit/qt/Api/qwebframe.h
把剛才的 MyObject 類和 MyCSDNObject 類在其中聲名一下,然後添加 CSDN 根對象作為 QWebFrame 類的私人成員,如下所示:

view plaincopy to clipboardprint?
  1. class MyObject : public QObject  
  2. {  
  3.     Q_OBJECT  
  4.    // 省略 ...   
  5. };  
  6.   
  7. class MyCSDNObject : public QObject  
  8. {  
  9.     Q_OBJECT     
  10.     // 省略 ...   
  11. };  
  12.   
  13. class QWEBKIT_EXPORT QWebFrame : public QObject  
  14. {  
  15.     Q_OBJECT  
  16.     Q_PROPERTY(qreal textSizeMultiplier READ textSizeMultiplier WRITE setTextSizeMultiplier)  
  17.     Q_PROPERTY(QString title READ title)  
  18.     Q_PROPERTY(QUrl url READ url WRITE setUrl)  
  19.     Q_PROPERTY(QIcon icon READ icon)  
  20.     Q_PROPERTY(QSize contentsSize READ contentsSize)  
  21. private:  
  22.     QWebFrame(QWebPage *parent, QWebFrameData *frameData);  
  23.     QWebFrame(QWebFrame *parent, QWebFrameData *frameData);  
  24.     ~QWebFrame();  
  25.   
  26.     // 聲名 CSDN 根對象   
  27.     MyCSDNObject *m_csdn;  
  28.   
  29.     public:  
  30.   // 以下省略 ...   
  31. };  

class MyObject : public QObject{ Q_OBJECT // 省略 ...};class MyCSDNObject : public QObject{ Q_OBJECT // 省略 ...};class QWEBKIT_EXPORT QWebFrame : public QObject{ Q_OBJECT Q_PROPERTY(qreal textSizeMultiplier READ textSizeMultiplier WRITE setTextSizeMultiplier) Q_PROPERTY(QString title READ title) Q_PROPERTY(QUrl url READ url WRITE setUrl) Q_PROPERTY(QIcon icon READ icon) Q_PROPERTY(QSize contentsSize READ contentsSize)private: QWebFrame(QWebPage *parent, QWebFrameData *frameData); QWebFrame(QWebFrame *parent, QWebFrameData *frameData); ~QWebFrame(); // 聲名 CSDN 根對象 MyCSDNObject *m_csdn; public: // 以下省略 ...};

開啟 qwebframe.cpp 檔案,在 QWebFrame 的建構函式中建立 CSDN 根對象。

view plaincopy to clipboardprint?
  1. QWebFrame::QWebFrame(QWebPage *parent, QWebFrameData *frameData)  
  2.     : QObject(parent)  
  3.     , d(new QWebFramePrivate)  
  4. {  
  5.     d->page = parent;  
  6.     d->init(this, parent->d->page, frameData);  
  7.   
  8.     // 在這裡建立 CSDN 根對象   
  9.     {  
  10.     KJS::Bindings::RootObject *root = d->frame->bindingRootObject();  
  11.     KJS::ExecState *exec = root->interpreter()->globalExec();  
  12.     KJS::JSObject *global = root->interpreter()->globalObject();  
  13.   
  14.     m_csdn = new MyCSDNObject();  
  15.     global->put(exec, KJS::Identifier("CSDN"), KJS::Bindings::Instance::createRuntimeObject(KJS::Bindings::Instance::QtLanguage, (void *)m_csdn, root));  
  16.     }  
  17.   
  18.     if (!frameData->url.isEmpty()) {  
  19.         ResourceRequest request(frameData->url, frameData->referrer);  
  20.         d->frame->loader()->load(request, frameData->name);  
  21.     }  
  22. }  

QWebFrame::QWebFrame(QWebPage *parent, QWebFrameData *frameData) : QObject(parent) , d(new QWebFramePrivate){ d->page = parent; d->init(this, parent->d->page, frameData); // 在這裡建立 CSDN 根對象 { KJS::Bindings::RootObject *root = d->frame->bindingRootObject(); KJS::ExecState *exec = root->interpreter()->globalExec(); KJS::JSObject *global = root->interpreter()->globalObject(); m_csdn = new MyCSDNObject(); global->put(exec, KJS::Identifier("CSDN"), KJS::Bindings::Instance::createRuntimeObject(KJS::Bindings::Instance::QtLanguage, (void *)m_csdn, root)); } if (!frameData->url.isEmpty()) { ResourceRequest request(frameData->url, frameData->referrer); d->frame->loader()->load(request, frameData->name); }}

 在 QWebFrame 的解構函式中刪除 CSDN 根對象

view plaincopy to clipboardprint?
  1. QWebFrame::~QWebFrame()  
  2. {  
  3.     if (d->frame && d->frame->loader() && d->frame->loader()->client())  
  4.         static_cast(d->frame->loader()->client())->m_webFrame = 0;  
  5.   
  6.     if (m_csdn)  
  7.     {  
  8.         delete m_csdn;  
  9.         m_csdn = NULL;  
  10.     }  
  11.     delete d;  
  12. }  

QWebFrame::~QWebFrame(){ if (d->frame && d->frame->loader() && d->frame->loader()->client()) static_cast(d->frame->loader()->client())->m_webFrame = 0;if (m_csdn){delete m_csdn;m_csdn = NULL;} delete d;}

再手工編寫一個 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 內容。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.