新しいタブを開くときに前のタブの設定を継承する…

nomina.browser 0.0.038 alpha4 (シンプル版)
nomina.browser 0.0.039 alpha1 (ちょっとごーじゃすばーじょん)
一応、実装しました。
なれてきたこともあって、これ自体はけっこう簡単だったかも。

新しいタブを開く

要点は、こんな感じ。

  • nsIWindowCreatorを継承したclassを実装し、nsIWindowWatcher::SetWindowCreatorで登録。
    • 要するに、親のWebBrowserChrome(タブみたいなもん)をもらい、新しく作って返すのです。
    • このときに、NS_ADDREF(*_retval)を忘れない。これを忘れると、ガーベジコレクタが拗ねる。
    • Geckoは還ってきたChromeに対していろいろするみたい。
    • だから、これはGeckoURIをLoadする前の処理ということになる。

そして、実装はこんな感じ。

nmnWindowCreator::nmnWindowCreator() { return; }
nmnWindowCreator::~nmnWindowCreator() { return; }

//*****************************************************
// nsISupportsの中の人
//*****************************************************
// * 呪文。
//
NS_IMPL_ISUPPORTS1(nmnWindowCreator, nsIWindowCreator)

//*****************************************************
// nsIWindowCreatorの中の人
//*****************************************************
//
// CreateChromeWindow
//  *Geckoから呼ばれる(新規タブ・javascriptのpopup()など)
//  *Geckoは(*_retval)->GetWebBrowser(webBrowser)に対していろいろするみたい
//  *だから、ここでやる処理は、新しいウインドウにURIがロードされる前の処理
NS_IMETHODIMP nmnWindowCreator::CreateChromeWindow(nsIWebBrowserChrome *parent,
                                                   PRUint32 chromeFlags,
                                                   nsIWebBrowserChrome **_retval)
{
    if (_retval) {
        // nmnWebBrowserChromeを新しく作る
        nmnWebBrowserChrome* newChrome = nmnWebBrowserChrome();
        if (newChrome) {
            // 創れたら、*_retval(返り値)に設定して、忘れずにNS_ADDREFする
            *_retval = chrome;
            NS_ADDREF(*_retval);

            // ChromeFlags(メニューバーをつけるかどうかとか)を設定
            chrome->SetChromeFlags(chromeFlags);

            // あとは、このへんで、設定の継承をやります。
            // それは、次で。
        }
    }
    return NS_OK;
}

で、これをこうやって登録するのです。

int RegisterWindowCreator()
{
    // 自分が実装したWindowCreatorのinstanceを作成する
    nsCOMPtr<nsIWindowCreator> windowCreator(new nmnWindowCreator());
    if (!windowCreator) return -1;

    // XPCOMGlueを経由して、GREのWindowWatcherというserviceへのinterfaceを作成する
    nsCOMPtr<nsIWindowWatcher> windowWatcher (do_GetService(NS_WINDOWWATCHER_CONTRACTID));
    if (!windowWatcher) return -1;

    // WindowWatherに、自分の実装したWindowCreatorを登録する
    nsresult rv = windowWatcher->SetWindowCreator(windowCreator);
    if (NS_FAILED(rv)) return -1;

    return 0;
}

JavascriptのON/OFFなどの設定

要点は、こんな感じ。

  • WebBrowserに対する処理。よって、Chromeから取り出す必要がある。
  • WebBrowserが実装しているnsIWebBrowserSetupというinterfaceを使う。
  • できることは、以下の5つ
    • JavascriptのON/OFF
    • 画像のON/OFF
    • ActiveX(Pluginと呼んでる)のON/OFF
    • リダイレクト(MetaRedirectと呼んでる)のON/OFF
    • フレーム(SubFrameと呼んでる)のON/OFF
  • Getはこれではできないっぽい

必要ないかもしれないけど、例は、こんな感じ。

int SetAllowJavaScript(nsIWebBrowserChrome* aChrome, bool aValue)
{
    nsIWebBrowser* webBrowser;
    aChrome->GetWebBrowser(getter_AddRefs(webBrowser)); //ガーベジコレクタをだますの
    if (webBrowser) {
        // nsIWebBrowserSetup* webBrowserSetup = 
        //     reinterpret_cast<nsIWebBrowserSetup*>(webBrowser);
        // みたいなもん…かな?
        nsCOMPtr<nsIWebBrowserSetup> webBrowserSetup = do_QueryInterface(webBrowser);

        if (webBrowserSetup) {
            webBrowserSetup->SetProperty(nsIWebBrowserSetup::SETUP_ALLOW_JAVASCRIPT,
                                         aValue ? PR_TRUE : PR_FALSE);
        }
    }
    return 0;
}

文字サイズの設定

もう疲れてきましたね。

  • nsIDOMWindow::SetTextZoom(float)とGetTextZoom(float)を使う
  • nsIDOMWindowはnsIWebBrowser::GetContentDOMWindowでもらってくる

疲れてきたので関数にはしません。

nsCOMPtr<nsIDOMWindow> domWindow;
webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
if (domWindow) domWindow->SetTextZoom(0.75);

で、

これをいっしょくたにすれば完成。
どう?タブブラウザを造るって簡単なことでしょ?