WebKit 學習筆記(5) — qt javascript 擴充

來源:互聯網
上載者:User

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

有下面幾行:

#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

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

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 進行解析:

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

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

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

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

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

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. 修改一下建立的根對象的名字

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

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

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 根對象。

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 根對象

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.