BlackLead

jQueryでタブブラウザ的な何かを作ってみましたが残念ながらChromelessではありません.QtWebKitのWebKit Bridge,つまりC++で書かれたQObjectをWebKitのJavaScriptから叩くことができる機能を使ったものです.タブ部分はdynatreeをそのまま使って,CSSをゴニョゴニョしてそれっぽく見せています.dynatreeだとitemの中にHTMLを自由に仕込むことができるので,僕の用途にもっとも近い.自力でGUI部品作るのってとても精神を害するので本当に良かった.

命名は鉛筆からの連想で,ちょっとしたメモを取りやすいものにしたいから.

ま,どこまでちゃんとやるか分からんけどねー.いままでもそうだったし,これからもきっとそうだ.

Qt 4.7 TPでQWebViewのDOM操作を追試してみた

2chで http://d.tnose.net/?p=1666 が晒されたようなので,せっかくですしQt 4.7 TP で追試してみました.

結論から言うと,C++の場合のみ400ms->330msとパフォーマンスが改善しているみたいです.JavaScriptはかえって悪くなっているような.

Qt 4.6 TP1 をビルドしてみた

Qt 4.6 の Technology Preview 1が出たので、ビルドしてみました。もちろん目当てはDOM APIが整備されたQtWebKitです。以前はevaluateJavaScriptというメソッドを経由してDOMをいじらないといけなかったので、速度・使い勝手的に厳しいものがありましたが、今回ははたしてどうでしょう?コードはこんな感じ:

void MainWindow::on_actionDOM_API_triggered()
{
    //DOM API版
    int i;
    QTime t;
    t.start();
    //本当は比較のためdocument.createElementと同等なAPIを使うべきだが見つからないので仕方なく断片の文字列を読み込ませている
    for(i=0;i<10000;i++)
         ui->webView->page()->mainFrame()->findFirstElement("body").appendInside("<p>aaa</p>");
    QMessageBox::information(NULL, "QWebElement::appendInside", QString("%1ms").arg(t.elapsed()));
}

void MainWindow::on_actionJavaScript_triggered()
{
    //JavaScript版
    QTime t;
    t.start();
    //断片をパースして追加するという意味ではdocumentFragmentを使って比較すべきかもしれない…。
    ui->webView->page()->mainFrame()->evaluateJavaScript("var i;for(i=0;i<10000;i++){"
                                                         "var elm = document.createElement('p');"
                                                         "elm.appendChild(document.createTextNode('aaa'));"
                                                         "document.body.appendChild(elm);}");
    QMessageBox::information(NULL, "QWebFrame::evaluateJavaScript", QString("%1ms").arg(t.elapsed()));
}

void MainWindow::on_actionTextBrowser_triggered()
{
    //QTextBrowserとも比較してみる
    int i;
    QTime t;
    t.start();
    for(i=0;i<10000;i++){
        ui->textBrowser->textCursor().movePosition(QTextCursor::End);
        ui->textBrowser->insertHtml("<p>aaa</p><br>"); //brを入れないと処理がなぜか戻ってこない
    }
    QMessageBox::information(NULL, "QTextBrowser::insertHtml", QString("%1ms").arg(t.elapsed()));
}

結果は、C++でDOMをいじった場合400ms台、JavaScriptだと1500ms台、QTextBrowserは4000ms台でした(OS: Xubuntu 9.04 on VirtualBox, CPU: Core2Duo 1.6GHz)。QWebViewのC++とJSに関しては等価なコードではないので正確な比較ではありませんが… これなら2chブラウザをQtWebKitベースで作ってもあまり問題はなさそう(4.5のQWebViewはあからさまに遅かったのでQTextBrowserを使いました)。ただし、Qt 4.6ではイベント関連のAPIの整備が延期されているようなのが残念。QWebFrame::addToJavaScriptWindowObjectを駆使するしかないんかな?

なお、JavaScript版のコードを動かした後、ui->webView->page()->mainFrame()->findFirstElement("body").removeChildren();とすると、なぜか一部の要素が残るという謎の結果が生じました。C++版だと起きず、完全にクリアされます。バグ?

Qt 4.6には、他にもJavaScriptCoreをバックエンドに選べるようになったQtScriptやQStateMachineなどおもしろげなものが転がってますので、一度さらっと眺めてみるといいかもしれません。

先日のJavaOneでのJWebPaneに関するスライド

PDF注意。

ダウンロードサイズが2MBってのは、描画機能がJava2Dに頼っていたり、FirefoxやSafariがガワも搭載していることを考えるとあまりフェアな比較ではないように思うが…

あと、FlashのサポートのためにNPAPIでなくActiveXを使うつもりらしいのが意外。

Qt4.6から加わるQtWebKitのDOM API

Qt4.5で見合わされたDOM APIが、ついにQt4.6で使えるようになります。

現在、QWebFrameを覗いてみると、こんな感じになっています。

QWebElement documentElement() const;
QList findAllElements(const QString &selectorQuery) const;
QWebElement findFirstElement(const QString &selectorQuery) const;

QWebElementを見ると、appendInsideなどの見慣れないメソッドが見えます。

WebKitのOgg Vorbis/Theora対応はどうなるか

WebKitのBugzillaにBug 22548: HTML5: Native codec support for <audio> and <video>なるBugが立っている。通常のWindows版WebKitはQuickTime(QtWebKitのWindows版だとDirectShowだったかな)を用いてvideoやaudioに対応しているのだが、Firefox・Operaと同様に本体でOgg Vorbis/Theoraに対応してくれるとなかなかうれしい話になる。ただ、Appleの意向がどうなるか…

再配布可能なWebKitがついに実現

Brent Fulgham氏による成果がついに出ました。Appleのプロプライエタリなライブラリに依存しない、cairo版のWebKitがビルドできたとのこと。Release版とDebug版の両方を氏のBlogから入手することができます。

Safariに搭載されているものとは以下が違います。

  • QuickTimeムービーのサポートはない
  • CFNetworkはcURLに、CoreGraphicsはcairo、CoreFoundationはCFLiteにそれぞれ置き換えられているので、機能的に退行しているところが多々ある