mazilla mozilla
はじめに
モジラとは
当ページの主旨
モジラの特徴
モジラ概観
モジュール
Webツール
モジラの技術
その他のリソース
モジラのビルド
ビルド環境の構築
ソースのチェックアウト
ビルド手順
ビルド後のイメージ
モジラを実行
エンベッディング
エンベッディングとは
エンベッディングの概念
PPBrowserの構造
PPBrowserの解析
エンベッディングの構造
marbrowの構造
marbrowの解析
フィジラ
フィジラとは
フィジラのビルド
フィジラのエンベッディング
FAQ
やつぎ氏との会話

PPBrowserの解析

PPBrowserを解析!


ここでは、PPBrowserのコードを実際に解析していきます。


◆ CBrowserAppクラス ◆

■ main() - メイン関数

ツールボックス関連の初期化後、CBrowserAppクラスを生成し、イベントループに入ります。

int main()
{
                                
    SetDebugThrow_(PP_PowerPlant::debugAction_Alert);   // Set Debugging options
    SetDebugSignal_(PP_PowerPlant::debugAction_Alert);

    PP_PowerPlant::InitializeHeap(3);       // Initialize Memory Manager
                                            // Parameter is number of Master Pointer
                                            // blocks to allocate
    
    
    PP_PowerPlant::UQDGlobals::InitializeToolbox(&qd);  // Initialize standard Toolbox managers

#if DEBUG
    ::InitializeSIOUX(false);
#endif
    
    ::InitTSMAwareApplication();
    
    new PP_PowerPlant::LGrowZone(20000);    // Install a GrowZone function to catch low memory situations.

    {
        CBrowserApp theApp;         // create instance of your application
    
        theApp.Run();
    }

    ::CloseTSMAwareApplication();
    
    return 0;
}

mozilla/lib/ には、Macintoshのツールボックス関連の初期化をするInitializeMacToolbox()関数がありますが、PPBRowserでは、PowerPlantおよび素のMacintosh関数を使って、ツールボックス関連の初期化をしています。

■ CBrowserApp::CBrowserApp() - コンストラクタ

ここでの最も重要な処理は、エンベッディングAPIの初期化です。アプリケーションの存在するディレクトリを所得し、これをNS_InitEmbedding() に渡して初期化します。

CBrowserApp::CBrowserApp()
{
    .
    .

   nsresult        rv;
   ProcessSerialNumber psn;
   ProcessInfoRec  processInfo;
   FSSpec          appSpec;
   nsCOMPtr<nsILocalFileMac> macDir;
   nsCOMPtr<nsILocalFile>    appDir; // If this ends up being NULL, default is used

   if (!::GetCurrentProcess(&psn)) {
      processInfo.processInfoLength = sizeof(processInfo);
      processInfo.processName = NULL;
      processInfo.processAppSpec = &appSpec;    
      if (!::GetProcessInformation(&psn, &processInfo)) {
         // Turn the FSSpec of the app into an FSSpec of the app's directory
         ::FSMakeFSSpec(appSpec.vRefNum, appSpec.parID, "\p", &appSpec);
         // Make an nsILocalFile out of it
         rv = NS_NewLocalFileWithFSSpec(&appSpec, PR_TRUE, getter_AddRefs(macDir));
         if (NS_SUCCEEDED(rv))
             appDir = do_QueryInterface(macDir);
      }
   }

   rv = NS_InitEmbedding(appDir, nsnull);

また初期設定フォルダの"PP Browser"というプレファレンスを初期化し、英語のフォントサイズを12に固定しています。

nsMPFileLocProvider *locationProvider = new nsMPFileLocProvider;
   ThrowIfNil_(locationProvider);
   nsCOMPtr<nsIFile> rootDir;
   rv = NS_GetSpecialDirectory(NS_MAC_PREFS_DIR, getter_AddRefs(rootDir));
   ThrowIfError_(rv);
   rv = locationProvider->Initialize(rootDir, "PP Browser");   
   ThrowIfError_(rv);
   
   NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
   if (NS_SUCCEEDED(rv)) {

        prefs->ResetPrefs(;) // Needed because things read default prefs during startup
        prefs->ReadUserPrefs();
        
        // HACK ALERT: Since we don't have prefs UI, reduce the font size here by hand
        prefs->SetIntPref("font.size.variable.x-western", 12);
        prefs->SetIntPref("font.size.fixed.x-western", 12);
    }
    else
        NS_ASSERTION(PR_FALSE, "Could not get preferences service");
}

■ CBrowserApp::~CBrowserApp() - デストラクタ

ここでの最も重要な処理は、エンベッディングAPIの終了処理です。他に、プレファレンスのセーブ、UMacUnicodeのクリーンアップも行っています。

CBrowserApp::~CBrowserApp()
{
   nsresult rv;
   NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
   if (NS_SUCCEEDED(rv))
      prefs->SavePrefFile();

   UMacUnicode::ReleaseUnit();

   NS_TermEmbedding();
}

■ CBrowserApp::StartUp() - スタートアップ

PowerPlant固有の方法により、初期のメインウインドウを表示します。

void
CBrowserApp::StartUp()
{
    ObeyCommand(PP_PowerPlant::cmd_New, nil);   // EXAMPLE, create a new window
}

■ CBrowserApp::ProcessNextEvent() - イベント処理

モジラに必要なイベント処理を行う為に、ProcessNextEvent() をオーバーライドします。

void
CBrowserApp::ProcessNextEvent()
{
    EventRecord     macEvent;

        // When on duty (application is in the foreground), adjust the
        // cursor shape before waiting for the next event. Except for the
        // very first time, this is the same as adjusting the cursor
        // after every event.

    if (IsOnDuty()) {

            // Calling OSEventAvail with a zero event mask will always
            // pass back a null event. However, it fills the EventRecord
            // with the information we need to set the cursor shape--
            // the mouse location in global coordinates and the state
            // of the modifier keys.

        ::OSEventAvail(0, &macEvent);
        AdjustCursor(macEvent);
    }

        // Retrieve the next event. Context switch could happen here.

    SetUpdateCommandStatus(false);
    Boolean gotEvent = ::WaitNextEvent(everyEvent, &macEvent, mSleepTime,
                                        mMouseRgn);

        // Let Attachments process the event. Continue with normal
        // event dispatching unless suppressed by an Attachment.

    if (LAttachable::ExecuteAttachments(msg_Event, &macEvent)) {
        if (gotEvent) {
#if DEBUG
         if (!SIOUXHandleOneEvent(&macEvent))
#endif
            DispatchEvent(macEvent);
        } else {
            UseIdleTime(macEvent);

           Repeater::DoIdlers(macEvent);
         // yield to other threads
         ::PR_Sleep(PR_INTERVAL_NO_WAIT);
        }
    }

                            // Repeaters get time after every event
    LPeriodical::DevoteTimeToRepeaters(macEvent);
    Repeater::DoRepeaters(macEvent);

                            // Update status of menu items
    if (IsOnDuty() && GetUpdateCommandStatus()) {
        UpdateMenus();
    }
}

モジラに特殊なイベント処理の1つは、ネット処理などのモジラのバックグラウンド処理を動かす為に、Repeaterクラスのstaticメンバをコールすることです。Repeater::DoIdlers()をnullイベント毎に、Repeater::DoRepeaters()をイベントループ毎に呼びます。

他に、Debug Build時には、デバッグコンソール用のSIOUXのイベント処理を行います。

■ CBrowserApp::ObeyCommand() - コマンド処理

cmd_New処理を行います。PowerPlant固有の方法により、メインウインドウを生成し、これにURLをロードします。ここでは固定で"http://www.mozilla.org"をロードしています。

Boolean
CBrowserApp::ObeyCommand(
    PP_PowerPlant::CommandT inCommand,
    void                    *ioParam)
{
    Boolean     cmdHandled = true;

    switch (inCommand) {

        case PP_PowerPlant::cmd_New:
            {
            CBrowserWindow  *theWindow = dynamic_cast<CBrowserWindow*
               (LWindow::CreateWindow(wind_BrowserWindow, this));
            ThrowIfNil_(theWindow);
            // LWindow is not initially visible in PPob resource
            theWindow->Show();

            // Just for demo sake, load a URL
            LStr255     urlString("http://www.mozilla.org");
            theWindow->GetBrowserShell()->LoadURL((Ptr)&urlString[1],
                urlString.Length());
            }
            break;

        // Any that you don't handle, such as cmd_About and cmd_Quit,
        // will be passed up to LApplication
        default:
            cmdHandled = PP_PowerPlant::LApplication::ObeyCommand(inCommand, ioParam);
            break;
    }

    return cmdHandled;
}


◆ CBrowserWindowクラス ◆

■ クラス定義

CBrowserWindowクラスの定義では、モジラ関連のメンバ変数として、メインウインドウのモジラ的表現であるウィンドウウィジェットへのポインタ、子コントロールとして抱える各インスタンスへのポインタ、および、クロームインスタンスへのポインタを持ちます。

class CBrowserWindow : public LWindow,
                       public LListener,
                       public LBroadcaster
{
private:
    typedef LWindow Inherited;

   friend class CWebBrowserChrome;

public:
    enum { class_ID = FOUR_CHAR_CODE('BroW') };

                           CBrowserWindow();
                           CBrowserWindow(LStream* inStream);

    virtual                ~CBrowserWindow();
    .
    .
protected:
    nsCOMPtr<nsIWidget>  mWindow;

    CBrowserShell*       mBrowserShell;
    CWebBrowserChrome*   mBrowserChrome;
    LEditText*           mURLField;
    LStaticText*         mStatusBar;
    CThrobber*           mThrobber;
    LBevelButton         *mBackButton, *mForwardButton, *mStopButton;
    LProgressBar*        mProgressBar;
};

■ CBrowserWindow::CBrowserWindow() - コンストラクタ

CBrowserWindowクラスのコンストラクタでは、メインウインドウ用のモジラウィジェットのインスタンスを生成します。また、ブラウザクロームを生成し、自分自身と関連付けます。

CBrowserWindow::CBrowserWindow(LStream* inStream)
    : LWindow(inStream),
   mBrowserShell(NULL), mBrowserChrome(NULL),
   mURLField(NULL), mStatusBar(NULL), mThrobber(NULL),
   mBackButton(NULL), mForwardButton(NULL), mStopButton(NULL),
   mProgressBar(NULL)
{
    nsresult rv = CommonConstruct();
    if (NS_FAILED(rv))
        Throw_(NS_ERROR_GET_CODE(rv));
}

NS_IMETHODIMP CBrowserWindow::CommonConstruct()
{
   nsresult rv;
   
   // Make the base widget
   mWindow = do_CreateInstance(kWindowCID, &rv);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

   // Make our CWebBrowserChrome
   mBrowserChrome = new CWebBrowserChrome;
   NS_ENSURE_TRUE(mBrowserChrome, NS_ERROR_OUT_OF_MEMORY);
   NS_ADDREF(mBrowserChrome);
   mBrowserChrome->BrowserWindow() = this;

   return NS_OK;
}

PowerPlantでの各ビジュアルパーツの初期化処理は、以下の順でコールされます。

  1. 上位から順に、コンストラクタ
  2. 上位から順に、FinishCreate()
  3. 下位から順に、FinishCreateSelf()

■ CBrowserWindow::~CBrowserWindow() - デストラクタ

CBrowserWindowクラスのデストラクタでは、ブラウザクロームを破棄します。

CBrowserWindow::~CBrowserWindow()
{
   if (mBrowserShell)
      mBrowserShell->SetTopLevelWindow(nsnull);
   
   if (mBrowserChrome)
   {
      mBrowserChrome->BrowserShell() = nsnull;
      mBrowserChrome->BrowserWindow() = nsnull;
      NS_RELEASE(mBrowserChrome);
   }
}

■ CBrowserWindow::FinishCreate() - 当CBrowserWindow生成後の最終処理

コンストラクタで生成したウィジェットより実際のモジラウインドウを作成します。

void CBrowserWindow::FinishCreate()
{
   // Initialize the top level widget
   // This needs to be done AFTER the subviews are constructed
   // but BEFORE the subviews do FinishCreateSelf.
   
    Rect portRect = GetMacPort()->portRect;
    nsRect r(0, 0, portRect.right - portRect.left, portRect.bottom - portRect.top);

    nsresult rv = mWindow->Create((nsNativeWidget)GetMacPort()
                      r, nsnull, nsnull, nsnull, nsnull, nsnull);
    if (NS_FAILED(rv))
       Throw_(NS_ERROR_GET_CODE(rv));

   Inherited::FinishCreate();   
}

■ CBrowserWindow::FinishCreateSelf() - 全階層構築後の最終処理

ここでのモジラ固有の処理は、CWebBrowserChromeの設定、初期化、CBrowserShellとCWebBrowserChromeの関連付け、および、各子コントロールのメンバ変数への設定です。

void CBrowserWindow::FinishCreateSelf()
{
    mBrowserShell = dynamic_cast<CBrowserShell*>(FindPaneByID(paneID_WebShellView));
    ThrowIfNULL_(mBrowserShell);  // Curtains if we don't have this

    // Tell our CBrowserShell about the chrome 
    mBrowserShell->SetTopLevelWindow(mBrowserChrome);
    // Tell our chrome about the CBrowserShell 
    mBrowserChrome->BrowserShell() = mBrowserShell;

    // Find our subviews - When we have a way of creating this
    // window with various chrome flags, we may or may not have
    // all of these subviews so don't fail if they don't exist
    mURLField = dynamic_cast<LEditText*>(FindPaneByID(paneID_URLField));
    if (mURLField)
        SwitchTarget(mURLField);

    mStatusBar = dynamic_cast<LStaticText*>(FindPaneByID(paneID_StatusBar));
    mThrobber = dynamic_cast<CThrobber*>(FindPaneByID(paneID_Throbber));
    mProgressBar = dynamic_cast<LProgressBar*>(FindPaneByID(paneID_ProgressBar));
    if (mProgressBar)
       mProgressBar->Hide();

    mBackButton = dynamic_cast<LBevelButton*>(FindPaneByID(paneID_BackButton));
    if (mBackButton)
        mBackButton->Disable();
    mForwardButton = dynamic_cast<LBevelButton*>(FindPaneByID(paneID_ForwardButton));
    if (mForwardButton)
        mForwardButton->Disable();
    mStopButton = dynamic_cast<LBevelButton*>(FindPaneByID(paneID_StopButton));
    if (mStopButton)
        mStopButton->Disable();

    UReanimator::LinkListenerToControls(this, this, mUserCon);
    StartListening();
    StartBroadcasting();
}

■ CBrowserWindow::ResizeFrameBy() - リサイズ処理

■ CBrowserWindow::ShowSelf() - 表示

メインウィンドウの表示/非表示、リサイズなどの形状処理は、nsCOMPtr<nsIWidget> mWindowを介してモジラウィジェットに依頼します。

void CBrowserWindow::ResizeFrameBy(SInt16    inWidthDelta,
                                   SInt16    inHeightDelta,
                                   Boolean   inRefresh)
{
    // Resize the widget BEFORE subviews get resized
    Rect portRect = GetMacPort()->portRect;
    mWindow->Resize(portRect.right - portRect.left, portRect.bottom - portRect.top
                      inRefresh);

    Inherited::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh);
}

void CBrowserWindow::ShowSelf()
{
   Inherited::ShowSelf();
   mWindow->Show(PR_TRUE);
}

■ CBrowserWindow::ObeyCommand() - コマンド処理

メインウィンドウが抱える子コントロールの処理、およびファインド系のメニューの処理を行います。全てCBrowserShellに処理を依頼します。

Boolean CBrowserWindow::ObeyCommand(CommandT inCommand,
                                     voi      *ioParam)
{
#pragma unused(ioParam)

    Boolean cmdHandled = true;

    switch (inCommand)
    {
        case paneID_BackButton:
            mBrowserShell->Back();
            break;

        case paneID_ForwardButton:
            mBrowserShell->Forward();
            break;

        case paneID_StopButton:
            mBrowserShell->Stop();
            break;

        case paneID_URLField:
            {
            SInt32    urlTextLen;
            mURLField->GetText(nil, 0, &urlTextLen);
            StPointerBlock  urlTextPtr(urlTextLen, true, false);
            mURLField->GetText(urlTextPtr.Get(), urlTextLen, &urlTextLen);
            mBrowserShell->LoadURL(urlTextPtr.Get(), urlTextLen);
            }
            break;

        case CBrowserShell::cmd_Find:
            mBrowserShell->Find();
            break;

        case CBrowserShell::cmd_FindNext:
            mBrowserShell->FindNext();
            break;

        default:
           cmdHandled = false;
           break;
    }

    if (!cmdHandled)
        cmdHandled = Inherited::ObeyCommand(inCommand, ioParam);
    return cmdHandled;
}

■ CBrowserWindow::SetStatus() - ステータス文字列セット

■ CBrowserWindow::SetLocation() - ロケーションバー文字列セット

CWebBrowserChrome (ブラウザクローム)からコールされるメソッドです。文字列は、nsAutoString、UMacUnicodeを使用して、Unicode -> nsString -> Str255 変換されています。

NS_METHOD CBrowserWindow::SetStatus(const PRUnichar* aStatus)
{
   if (mStatusBar)
   {
        nsAutoString statusStr(aStatus);
        Str255 aStr;

        UMacUnicode::StringToStr255(statusStr, aStr);
        mStatusBar->SetDescriptor(aStr);
   }
   return NS_OK;
}

NS_METHOD CBrowserWindow::SetLocation(const nsString& aLocation)
{
    if (mURLField)
    {
        Str255 aStr;

        UMacUnicode::StringToStr255(aLocation, aStr);
        mURLField->SetDescriptor(aStr);
    }
    return NS_OK;
}

■ CBrowserWindow::OnStatusNetStart() - ネット処理開始

ネット処理の開始時にCWebBrowserChromeからコールされるメソッドです。プログレスバー、スロッバーのスタート、Stopボタンのイネーブルを行います。

NS_METHOD CBrowserWindow::OnStatusNetStart(nsIWebProgress *progress, nsIRequest *request,
                                           PRInt32 progressStateFlags, PRUint32 status)
{
    if (mProgressBar) {
       mProgressBar->Show();
       mProgressBar->SetIndeterminateFlag(true, true);
   }
   
    if (mThrobber)
        mThrobber->Start();

    if (mStopButton)
        mStopButton->Enable();

    // Inform any other interested parties
    // Actually, all of the above stuff should done through
    // broadcasters and listeners. But for demo's sake this
    // better shows what's happening.
    LBroadcaster::BroadcastMessage(msg_OnStartLoadDocument, 0);
   
   return NS_OK;
}

■ CBrowserWindow::OnStatusNetStop() - ネット処理終了

ネット処理の終了時にCWebBrowserChromeからコールされるメソッドです。プログレスバー、スロッバーのストップ、Back、Forwardボタンのステータス設定、Stopボタンのディスエーブルを行います。

NS_METHOD CBrowserWindow::OnStatusNetStop(nsIWebProgress *progress, 
                  nsIRequest *request,  PRInt32 progressStateFlags, PRUint32 status)
{
    if (mThrobber)
        mThrobber->Stop();

    if (mProgressBar) {
       if (mProgressBar->IsIndeterminate())
          mProgressBar->Stop();
       mProgressBar->Hide();
    }

    // Enable back, forward, stop
    if (mBackButton)
        mBrowserShell->CanGoBack() ?
            mBackButton->Enable() : mBackButton->Disable();
    if (mForwardButton)
        mBrowserShell->CanGoForward() ?
            mForwardButton->Enable() : mForwardButton->Disable();
    if (mStopButton)
        mStopButton->Disable();

    // Inform any other interested parties
    // Actually, all of the above stuff should done through
    // broadcasters and listeners. But for demo's sake this
    // better shows what's happening.
    LBroadcaster::BroadcastMessage(msg_OnEndLoadDocument, 0);

   return NS_OK;
}

■ CBrowserWindow::OnProgressChange() - プログレスチェンジ

ネット処理の更新時にCWebBrowserChromeからコールされるメソッドです。プログレスバーの値を更新しています。

NS_METHOD CBrowserWindow::OnProgressChange(nsIWebProgress *progress, nsIRequest *request,
                                       PRInt32 curSelfProgress, PRInt32 maxSelfProgress, 
                                       PRInt32 curTotalProgress, PRInt32 maxTotalProgress)
{
   if (mProgressBar) {
      if (maxTotalProgress != -1 && mProgressBar->IsIndeterminate())
         mProgressBar->SetIndeterminateFlag(false, false);
      else if (maxTotalProgress == -1 && !mProgressBar->IsIndeterminate())
         mProgressBar->SetIndeterminateFlag(true, true);
      
      if (!mProgressBar->IsIndeterminate()) {
         PRInt32 aMax = max(0, maxTotalProgress);
         PRInt32 aVal = min(aMax, max(0, curTotalProgress));
         mProgressBar->SetMaxValue(aMax);
         mProgressBar->SetValue(aVal);
      }
   }
   return NS_OK;
}


◆ CBrowserShellクラス ◆

■ クラス定義

CBrowserShellクラスの定義では、モジラ関連のメンバ変数として、初期URL文字列、WebBrowser関連インターフェースへのポインタ、および、ファインドコンポーネントへのポインタを持ちます。また、モジラへのイベントの渡し口であるメッセージシンクをstaticメンバとして持ちます。

class CBrowserShell : public LView,
                      public LCommander,
                      public LPeriodical,
                      public LListener
{
  
private:
    typedef LView Inherited;

public:
    enum { class_ID = FOUR_CHAR_CODE('BroS') };

    enum { cmd_Find = 'Find', cmd_FindNext = 'FNxt' };

                                CBrowserShell();
                                CBrowserShell(LStream* inStream);

    virtual                     ~CBrowserShell();
    .
    .
protected:
   static nsMacMessageSink mMessageSink;
   
   LStr255                    mInitURL;
      
   nsCOMPtr<nsIWebBrowser>    mWebBrowser;          // The thing we actually create
   nsCOMPtr<nsIBaseWindow>    mWebBrowserAsBaseWin; // Convenience interface to above 
   nsCOMPtr<nsIWebNavigation> mWebBrowserAsWebNav;  // Ditto
   
   CFindComponent*            mFinder;
};

【CBrowserShell.cp】

// CBrowserShell static variables
nsMacMessageSink	CBrowserShell::mMessageSink;

モジラのイベント処理は、widgetモジュール内に存在します。エンベッディングの場合、フレームワークで受けた各種イベントを、nsMacMessageSinkを使用して、mMessageSink.DispatchOSEvent()によりモジラに送り込んで行きます。

エンベッディングでは、このCBrowserShellクラス、および、CWebBrowserChromeクラスにXPCOMの世界が展開されます。XPCOMでは、ある1つのXPCOMインスタンスが、その用途ごとに分類された複数のインターフェースを抱えています。XPCOMインスタンスに何かの処理を依頼する場合、その処理を含むインターフェースをQueryInterface()により取得し、そのインターフェースポインタから当のメソッドをコールすることになります。

■ CBrowserShell::CBrowserShell() - コンストラクタ

CBrowserShellクラスのコンストラクタでは、ブラウザ (HTML部分)のXPCOMインスタンスを生成します。

CBrowserShell::CBrowserShell(LStream* inStream) :
    LView(inStream),
    mFinder(nsnull)
{
    *inStream >> (StringPtr) mInitURL;

    nsresult rv = CommonConstruct();
    if (rv != NS_OK)
       // If this fails, there's no reason to live anymore :(
       Throw_Err(NS_ERROR_GET_CODE(rv)) 
}

NS_IMETHODIMP CBrowserShell::CommonConstruct()
{
    nsresult  rv;

    mWebBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);

    nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(mWebBrowser));
    NS_ENSURE_TRUE(baseWin, NS_ERROR_FAILURE);
    mWebBrowserAsBaseWin = baseWin;

    nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mWebBrowser));
    NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
    mWebBrowserAsWebNav = webNav;

    return NS_OK;
}

ブラウザは、nsWebBrowserクラスのインスタンスです。そのソースは、embeddingモジュール内に存在します。nsWebBrowserは、do_CreateInstance(NS_WEBBROWSER_CONTRACTID, &rv); によりインスタンス生成され、その代表的インターフェースである、nsIWebBrowerを返します。これをmWebBrowserメンバに格納しています。

nsWebBrowserを扱う場合、このnsIWebBrower mWebBrowserだけで十分で、他のインターフェースは必要な時にQueryInterface()でそのつど取得しても良いのですが、ここでは頻繁に使用するインターフェースである、nsIBaseWindow、nsIWebNavigationも、同時に取得してメンバ変数に格納しています。

■ CBrowserShell::~CBrowserWindow() - デストラクタ

CBrowserShellクラスのデストラクタでは、ファインドコンポーネントを破棄します。

CBrowserShell::~CBrowserShell()
{
    delete mFinder;

    // nsCOMPtr destructors, do your thing
}

■ CBrowserShell::FinishCreateSelf() - 全階層構築後の最終処理

ここでのモジラ固有の処理は、nsWebBrowserの形状(位置、サイズなど)を初期化することです。形状関連のインターフェースである nsIBaseWindow mWebBrowserAsBaseWin の InitWindow()、Create() により、とりあえず初期化し、その後、AdjustFrame() 共通メソッドにより、正しく位置決めしています。

void CBrowserShell::FinishCreateSelf()
{
    FocusDraw();

    CBrowserWindow *ourWindow = dynamic_cast<CBrowserWindow*
                       >(LWindow::FetchWindowObject(GetMacPort()));
    ThrowIfNil_(ourWindow);
    ourWindow->AddListener(this);

    nsCOMPtr<nsIWidget>  aWidget;
    ourWindow->GetWidget(getter_AddRefs(aWidget));
    ThrowIfNil_(aWidget);

    Rect portFrame;
    CalcPortFrameRect(portFrame);
    nsRect   r(portFrame.left, portFrame.top
               portFrame.right - portFrame.left, portFrame.bottom - portFrame.top);

    mWebBrowserAsBaseWin->InitWindow(aWidget->GetNativeData(NS_NATIVE_WIDGET),
        nsnull, r.x, r.y, r.width, r.height);
    mWebBrowserAsBaseWin->Create();
   
    AdjustFrame();   
    StartRepeating();
    StartListening();
}

■ CBrowserShell::SetTopLevelWindow() - ブラウザクロームの設定、初期化

CBrowserWindow::FinishCreateSelf() からコールされます。ブラウザ初期化の最終段階です。nsIWebBrowser::SetContainerWindow() により、nsWebBrowser にCWebBrowserChromeオブジェクトを、クロームとして認識させます。

また、コメントにあるようにnsIDocShell関連の初期化が必要であれば、合わせて行います。

NS_IMETHODIMP CBrowserShell::SetTopLevelWindow(nsIWebBrowserChrome *aTopLevelWindow)
{
    mWebBrowser->SetContainerWindow(aTopLevelWindow);  

    /*
    In case we needed to do something with the underlying docshell...   

    nsCOMPtr<nsIDocShell> ourDocShell(do_GetInterface(mWebBrowser));
    NS_ENSURE_TRUE(ourDocShell, NS_ERROR_FAILURE);
    */
     
    return NS_OK;
}

■ CBrowserShell::ResizeFrameBy() - リサイズ処理

■ CBrowserShell::MoveBy() - ムーブ処理

■ CBrowserShell::AdjustFrame() - フレーム調整共通処理

nsWebBrowserの形状(位置、サイズなど)が変化する時にコールされます。PowerPlant固有処理に加え、最終的には、AdjustFrame() 共通メソッドにより、正しく位置決めしています。AdjustFrame() では、nsIBaseWindow::SetPositionAndSize() により、ブラウザに形状を通知します。

void CBrowserShell::ResizeFrameBy(SInt16    inWidthDelta,
                                  SInt16    inHeightDelta,
                                  Boolean   inRefresh)
{
    LView::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh);
    AdjustFrame();
}


void CBrowserShell::MoveBy(SInt32   inHorizDelta,
                           SInt32   inVertDelta,
                           Boolean  inRefresh)
{
    LView::MoveBy(inHorizDelta, inVertDelta, inRefresh);
    AdjustFrame();
}

void CBrowserShell::AdjustFrame()
{
    FocusDraw();

    Rect portFrame;
    CalcPortFrameRect(portFrame);
    nsRect r(portFrame.left, portFrame.top
            portFrame.right - portFrame.left, portFrame.bottom - portFrame.top);

    mWebBrowserAsBaseWin->SetPositionAndSize(r.x, r.y, r.width, r.height, PR_TRUE);
}

■ CBrowserShell::ShowSelf() - 表示

nsIBaseWindow::SetVisibility() により、ブラウザを表示状態にします。

void CBrowserShell::ShowSelf()
{
    mWebBrowserAsBaseWin->SetVisibility(PR_TRUE);
}

イベント関連

■ CBrowserShell::ClickSelf() - マウスダウン処理

■ CBrowserShell::EventMouseUp() - マウスアップ処理

■ CBrowserShell::AdjustCursorSelf() - マウスムーブ処理

■ CBrowserShell::HandleMouseMoved() - マウスムーブ共通処理

■ CBrowserShell::HandleKeyPress() - キープレス処理

■ CBrowserShell::SpendTime() - アイドル処理 (SuspendResume)

イベント関連の処理です。ブラウザへは、nsMacMessageSinkを使用して、DispatchOSEvent() によりイベントを送り込みます。

void CBrowserShell::ClickSelf(const SMouseDownEvent &inMouseDown)
{
    if (!IsTarget())
        SwitchTarget(this);

    FocusDraw();
    mMessageSink.DispatchOSEvent((EventRecord&)inMouseDown.macEvent, GetMacPort());
}


void CBrowserShell::EventMouseUp(const EventRecord &inMacEvent)
{
    FocusDraw();
    mMessageSink.DispatchOSEvent((EventRecord&)inMacEvent, GetMacPort());
    
    LEventDispatcher *dispatcher = LEventDispatcher::GetCurrentEventDispatcher();
    if (dispatcher)
        dispatcher->UpdateMenus();
}


void CBrowserShell::AdjustCursorSelf(Point              /* inPortPt */,
                                     const EventRecord& inMacEvent)
{
    static Point    lastWhere = {0, 0};

    if ((*(long*)&lastWhere != *(long*)&inMacEvent.where))
    {
        HandleMouseMoved(inMacEvent);
        lastWhere = inMacEvent.where;
    }
}

void CBrowserShell::HandleMouseMoved(const EventRecord& inMacEvent)
{
    if (IsActive())
    {
        FocusDraw();
        mMessageSink.DispatchOSEvent(const_cast<EventRecord&>(inMacEvent), GetMacPort());
    }
}

Boolean CBrowserShell::HandleKeyPress(const EventRecord &inKeyEvent)
{
    // set the QuickDraw origin
    FocusDraw();

    // dispatch the event
    Boolean keyHandled = mMessageSink.DispatchOSEvent((EventRecord&)inKeyEvent, GetMacPort());

    return keyHandled;
}

void CBrowserShell::SpendTime(const EventRecord& inMacEvent)
{
    switch (inMacEvent.what)
    {
        case osEvt:
        {
            // The MacMessageSink will not set the cursor if we are in the backgroun
           // d - which is right.
            // We have to feed it suspendResumeMessages for it to know

            unsigned char eventType = ((inMacEvent.message >> 24) & 0x00ff);
            if (eventType == suspendResumeMessage)
            mMessageSink.DispatchOSEvent(const_cast<EventRecord&>(inMacEvent), GetMacPort());
        }
        break;
    }
}

■ CBrowserShell::ObeyCommand() - コマンド処理

コピー、ペースト等のクリップボード処理を行っています。

Boolean CBrowserShell::ObeyCommand(PP_PowerPlant::CommandT inCommand, void* ioParam)
{
    Boolean     cmdHandled = true;

    nsresult rv;
    nsCOMPtr<nsIClipboardCommands> clipCmd;

    switch (inCommand)
    {
        case cmd_Cut:
            rv = GetClipboardHandler(getter_AddRefs(clipCmd));
            if (NS_SUCCEEDED(rv))
                clipCmd->CutSelection();
            break;

        case cmd_Copy:
            rv = GetClipboardHandler(getter_AddRefs(clipCmd));
            if (NS_SUCCEEDED(rv))
                clipCmd->CopySelection();
            break;

        case cmd_Paste:
            rv = GetClipboardHandler(getter_AddRefs(clipCmd));
            if (NS_SUCCEEDED(rv))
                clipCmd->PasteSelection();
            break;

        case cmd_SelectAll:
            rv = GetClipboardHandler(getter_AddRefs(clipCmd));
            if (NS_SUCCEEDED(rv))
                clipCmd->SelectAll();
            break;

        default:
            cmdHandled = LCommander::ObeyCommand(inCommand, ioParam);
            break;
    }
    return cmdHandled;
}

nsresult CBrowserShell::GetClipboardHandler(nsIClipboardCommands **aCommand)
{
    NS_ENSURE_ARG_POINTER(aCommand);

    nsCOMPtr<nsIDocShell> docShell(do_GetInterface(mWebBrowser));
    NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
    nsCOMPtr<nsIClipboardCommands> clipCmd(do_QueryInterface(docShell));
    NS_ENSURE_TRUE(clipCmd, NS_ERROR_FAILURE);

    *aCommand = clipCmd;
    NS_ADDREF(*aCommand);
    return NS_OK;
}

上記では、nsIWebBrowserインターフェースから、nsIDocShellインターフェースを取得しています。
nsDocShellは、nsWebBrowserに、間接的に抱えられているので、do_QueryInterface() ではなく、do_GetInterface() によりインターフェースを取得します。

ナビゲーション関連

■ CBrowserShell::CanGoBack() - Back可能?

■ CBrowserShell::CanGoForward() - Forward可能?

■ CBrowserShell::Back() - Back処理

■ CBrowserShell::Forward() - Forward処理

■ CBrowserShell::Stop() - Stop処理

全て、nsIWebNavigationインターフェースに処理を依頼します。

Boolean CBrowserShell::CanGoBack()
{
    PRBool      canDo;
    nsresult    rv;

    rv = mWebBrowserAsWebNav->GetCanGoBack(&canDo);
    return (NS_SUCCEEDED(rv) && canDo);
}

Boolean CBrowserShell::CanGoForward()
{
    PRBool      canDo;
    nsresult    rv;

    rv = mWebBrowserAsWebNav->GetCanGoForward(&canDo);
    return (NS_SUCCEEDED(rv) && canDo);
}

void CBrowserShell::Back()
{
    if (CanGoBack())
        mWebBrowserAsWebNav->GoBack();
    else
        ::SysBeep(5);
}

void CBrowserShell::Forward()
{
    if (CanGoForward())
        mWebBrowserAsWebNav->GoForward();
    else
        ::SysBeep(5);
}

void CBrowserShell::Stop()
{
    mWebBrowserAsWebNav->Stop();
}

■ CBrowserShell::LoadURL() - URLのロード

同じく、nsIWebNavigationインターフェースに処理を依頼します。プレーン文字列版と、nsString版が、オーバーロードされています。

void CBrowserShell::LoadURL(Ptr urlText, SInt32 urlTextLen)
{
    nsAutoString urlString; urlString.AssignWithConversion(urlText, urlTextLen);
    LoadURL(urlString);
}

void CBrowserShell::LoadURL(const nsString& urlText)
{
    nsresult rv = mWebBrowserAsWebNav->LoadURI(urlText.GetUnicode(),
         nsIWebNavigation::LOAD_FLAGS_NONE);
    if (NS_FAILED(rv))
        Throw_(NS_ERROR_GET_CODE(rv));
}

■ CBrowserShell::GetWebBrowser() - ブラウザゲッター

■ CBrowserShell::SetWebBrowser() - ブラウザセッター

CWebBrowserChromeからコールされるメソッドです。クロームクラスが使用する、ブラウザ (nsIWebBrowser) の、ゲッター(取得)、セッター(設定) です。

NS_METHOD CBrowserShell::GetWebBrowser(nsIWebBrowser** aBrowser)
{
    NS_ENSURE_ARG_POINTER(aBrowser);

    *aBrowser = mWebBrowser;
    NS_IF_ADDREF(*aBrowser);
    return NS_OK;
}

NS_METHOD CBrowserShell::SetWebBrowser(nsIWebBrowser* aBrowser)
{
    NS_ENSURE_ARG(aBrowser);

    FocusDraw();

    CBrowserWindow *ourWindow = dynamic_cast<CBrowserWindow*
       >(LWindow::FetchWindowObject(GetMacPort()));
    NS_ENSURE_TRUE(ourWindow, NS_ERROR_FAILURE);

    nsCOMPtr<nsIWidget>  aWidget;
    ourWindow->GetWidget(getter_AddRefs(aWidget));
    NS_ENSURE_TRUE(aWidget, NS_ERROR_FAILURE);

    mWebBrowser = aBrowser;

    nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(mWebBrowser));
    NS_ENSURE_TRUE(baseWin, NS_ERROR_FAILURE);
    mWebBrowserAsBaseWin = baseWin;

    nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mWebBrowser));
    NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
    mWebBrowserAsWebNav = webNav;

    Rect portFrame;
    CalcPortFrameRect(portFrame);
    nsRect   r(portFrame.left, portFrame.top,
        portFrame.right - portFrame.left, portFrame.bottom - portFrame.top);

    mWebBrowserAsBaseWin->InitWindow(aWidget->GetNativeData(NS_NATIVE_WIDGET),
        nsnull, r.x, r.y, r.width, r.height);
    mWebBrowserAsBaseWin->Create();

    AdjustFrame();   

    return NS_OK;
}


◆ CWebBrowserChromeクラス ◆

このクラスは、幾つかの定められたXPCOMインターフェースを装備し、ブラウザクラスと関連付けられることにより、モジラ側との様々なやり取りを管理します。実際に装備しているインターフェースは、以下のものです。

  • nsIWebBrowserChrome - ブラウザクロームとしての基本的インターフェース
  • nsIWebProgressListener - ページローディングの進行状況の通知を受ける為のインターフェース
  • nsIBaseWindow - 一般ウィンドウとしての操作を司るインターフェース
  • nsIPrompt - 各種プロンプトダイアログを表示する為のインターフェース
  • nsIInterfaceRequestor - オブジェクトがインプリメントしているインターフェースを取得する方法を定義するインターフェース

nsIInterfaceRequestorは、一般のXPCOMとは少し異なった形でインターフェースを装備する為のインターフェースです。一般のXPCOMでは、Interface A から Interface B が QI() できる場合、その逆の Interface B から Interface A が QI() できますが、nsIInterfaceRequestorは、一方向の取得を可能にします。この場合は、QI() ではなく、GetInterface() で取得します。

前述の nsIDocShell は、nsWebBrowser により、nsIInterfaceRequestor経由で抱えられています。よって、nsIWebBrowserより、QueryInterface() ではなく、GetInterface() により、nsIDocShell を取得します。

■ クラス定義

CWebBrowserChromeクラスの定義では、装備するインターフェースを継承し、それらのメソッドの定義をします。このメソッドの定義は、NS_DECL_ISUPPORTS、NS_DECL_NSIWEBBROWSERCHROME、などのマクロにより、展開されます。

メンバ変数として、ブラウザウインドウ、ブラウザシェルとの関連付けを保持する為に、CBrowserWindow、CBrowserShellへのポインタを持ちます。また、ブラウザリスト (生成した全てのクロームインスタンスを保持するCWebBrowserChrom*型のSTL vector配列 ) をstatic変数として持ちます。

また、CBrowserWindowクラスとC++のfriendの関係となり、CBrowserWindowクラスのメンバへのアクセスを容易にしています。

class CWebBrowserChrome : public nsIWebBrowserChrome,
                           public nsIWebProgressListener,
                           public nsIBaseWindow,
                           public nsIPrompt,
                           public nsIInterfaceRequestor
{
friend class CBrowserWindow;

public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIWEBBROWSERCHROME
   NS_DECL_NSIWEBPROGRESSLISTENER
   NS_DECL_NSIBASEWINDOW
   NS_DECL_NSIPROMPT
   NS_DECL_NSIINTERFACEREQUESTOR

protected:
   CWebBrowserChrome();
   virtual ~CWebBrowserChrome();

   CBrowserWindow*& BrowserWindow();
   CBrowserShell*& BrowserShell();

protected:
   CBrowserWindow*  mBrowserWindow;
   CBrowserShell*   mBrowserShell;
   
   static vector<CWebBrowserChrome*> mgBrowserList;
};

【CWebBrowserChrome.cp】

// Static Variables
vector<CWebBrowserChrome*> CWebBrowserChrome::mgBrowserList;
							
//*****************************************************************************
// CWebBrowserChrome::nsISupports
//*****************************************************************************

NS_IMPL_ADDREF(CWebBrowserChrome)
NS_IMPL_RELEASE(CWebBrowserChrome)

NS_INTERFACE_MAP_BEGIN(CWebBrowserChrome)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
NS_INTERFACE_MAP_ENTRY(nsIPrompt)
NS_INTERFACE_MAP_END
また、上記マクロにより、AddRef()、Release()、QueryInterface() を実装しています。

■ CWebBrowserChrome::CWebBrowserChrome() - コンストラクタ

CWebBrowserChromeクラスのコンストラクタでは、ブラウザリストに自分自身を追加します。

CWebBrowserChrome::CWebBrowserChrome() :
   mBrowserWindow(nsnull), mBrowserShell(nsnull)
{
    NS_INIT_REFCNT();

    mgBrowserList.push_back(this);
}

■ CWebBrowserChrome::~CWebBrowserChrome() - デストラクタ

CWebBrowserChromeクラスのデストラクタでは、ブラウザリストより自分自身を削除します。

CWebBrowserChrome::~CWebBrowserChrome()
{
  vector<CWebBrowserChrome*>::iterato  iter = find(mgBrowserList.begin()
      mgBrowserList.end(), this);
  if (iter != mgBrowserList.end())
    mgBrowserList.erase(iter);
}

■ CWebBrowserChrome::BrowserWindow() - BrowserWindowアクセッサー

■ CWebBrowserChrome::BrowserShell() - BrowserShellアクセッサー

このクロームインスタンスに関連付けられた、CBrowserWindow、CBrowserShell のアクセッサーメソッドです。ポインタへの参照を使用して、右辺値参照、左辺値代入の両方ができます。

CBrowserWindow*& CWebBrowserChrome::BrowserWindow()
{
   return mBrowserWindow;
}

CBrowserShell*& CWebBrowserChrome::BrowserShell()
{
   return mBrowserShell;
}

◆◆◆ nsIInterfaceRequestorインターフェース ◆◆◆

■ CWebBrowserChrome::GetInterface() - インターフェースの取得

外部よりのGetInterface() を処理します。ここでは、全てQueryInterface() に振ることにより、特別な処理は行っていません。

NS_IMETHODIMP CWebBrowserChrome::GetInterface(const nsIID &aIID, void** aInstancePtr)
{
   return QueryInterface(aIID, aInstancePtr);
}

◆◆◆ nsIWebBrowserChromeインターフェース ◆◆◆

■ CWebBrowserChrome::SetStatus() - ステータス通知

HTMLドキュメントからのステータス文字列の通知です。

NS_IMETHODIMP CWebBrowserChrome::SetStatus(PRUint32 statusType, const PRUnichar *status)
{
   NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED);

   if (statusType == STATUS_SCRIPT) 
      mBrowserWindow->SetStatus(status);
   else if (statusType == STATUS_LINK)
      mBrowserWindow->SetOverLink(status);

   return NS_OK;
}

STATUS_SCRIPTはJavascriptからのもの、STATUS_LINKはHTMLドキュメント上のリンクのhref文字列です。どちらも、CBrowserWindowに、ステータスバー表示を依頼しています。

■ CWebBrowserChrome::GetWebBrowser() - ブラウザ取得

■ CWebBrowserChrome::SetWebBrowser() - ブラウザ設定

モジラ側からのブラウザ所得、設定の通知です。どちらも、CBrowserShellに処理を振っています。

NS_IMETHODIMP CWebBrowserChrome::GetWebBrowser(nsIWebBrowser** aWebBrowser)
{
   NS_ENSURE_ARG_POINTER(aWebBrowser);
   NS_ENSURE_TRUE(mBrowserShell, NS_ERROR_NOT_INITIALIZED);

   mBrowserShell->GetWebBrowser(aWebBrowser);
   return NS_OK;
}

NS_IMETHODIMP CWebBrowserChrome::SetWebBrowser(nsIWebBrowser* aWebBrowser)
{
   NS_ENSURE_ARG(aWebBrowser);   // Passing nsnull is NOT OK
   NS_ENSURE_TRUE(mBrowserShell, NS_ERROR_NOT_INITIALIZED);

   mBrowserShell->SetWebBrowser(aWebBrowser);
   return NS_OK;
}

■ CWebBrowserChrome::CreateBrowserWindow() - ブラウザウィンドウ作成

モジラ側からのブラウザウィンドウの作成依頼です。これはHTMLドキュメント内のリンククリックなどで新しいウィンドウが作成される時にモジラから呼ばれます。PPBrowserでは、Layout = 130 のPlainBrowserWindowを固定で作成します。(ブラウザ1つのみを持つシンプルなウィンドウ) 本来は、chromeMaskの値により、適切なパーツを持ったウィンドウを作成するべきでしょう。

NS_IMETHODIMP CWebBrowserChrome::CreateBrowserWindow(PRUint32 chromeMask,
    PRInt32 aX, PRInt32 aY, PRInt32 aCX, PRInt32 aCY, nsIWebBrowser **aWebBrowser)
{
   NS_ENSURE_ARG_POINTER(aWebBrowser);
   *aWebBrowser = nsnull;

   // Note: For now, until we can create a window with specific chrome flags, this will
   // put up a plain window without navigation controls or location text. This is
   // most likely being used to pop up an add.
   
   CBrowserWindow	*theWindow;
   try
   {
      // CreateWindow can throw an we're being called from mozilla, so we need to catch
      theWindow = dynamic_cast<CBrowserWindow*
        >(LWindow::CreateWindow(wind_PlainBrowserWindow, LCommander::GetTopCommander()));
   }
   catch (...)
   {
      theWindow = nsnull;
   }
   NS_ENSURE_TRUE(theWindow, NS_ERROR_FAILURE);
   CBrowserShell *aBrowserShell = theWindow->GetBrowserShell();
   NS_ENSURE_TRUE(aBrowserShell, NS_ERROR_FAILURE);
   return aBrowserShell->GetWebBrowser(aWebBrowser);    
}

■ CWebBrowserChrome::FindNamedBrowserItem() - 名前によるブラウザアイテムの検索

指定された名前に対応するブラウザアイテムを検索して返します。

NS_IMETHODIMP CWebBrowserChrome::FindNamedBrowserItem(const PRUnichar* aName,
                                          nsIDocShellTreeItem ** aBrowserItem)
{
   NS_ENSURE_ARG(aName);
   NS_ENSURE_ARG_POINTER(aBrowserItem);
   *aBrowserItem = nsnull;

   vector<CWebBrowserChrome*>::iterator  iter = mgBrowserList.begin();
   while (iter < mgBrowserList.end())
   {
      CWebBrowserChrome* aChrome = *iter++;
      if (aChrome == this)
      	continue;	// Our tree has already been searched???

      NS_ENSURE_TRUE(aChrome->BrowserShell(), NS_ERROR_FAILURE);
      nsCOMPtr<nsIWebBrowser> webBrowser;
      aChrome->BrowserShell()->GetWebBrowser(getter_AddRefs(webBrowser));
      nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(webBrowser));
      NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);

      docShellAsItem->FindItemWithName(aName,
          NS_STATIC_CAST(nsIWebBrowserChrome*, this), aBrowserItem);

      if (*aBrowserItem)
         break;
   }

   return NS_OK; // Return OK even if we didn't find it???
}
 

ブラウザリストをイテレートして、docShellAsItem::FindItemWithName() により検索しています。

■ CWebBrowserChrome::SizeBrowserTo() - サイズ処理

ブラウザのサイズ変更通知です。

// Constants
const PRInt32     kGrowIconSize = 15;

NS_IMETHODIMP CWebBrowserChrome::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY)
{
   mBrowserWindow->ResizeFrameTo(aCX, aCY + kGrowIconSize, true);
   return NS_OK;}

ブラウザのサイズよりウインドウのクライアントエリアのサイズを割り出し、CBrowserWindowにリサイズを依頼しています。

■ CWebBrowserChrome::GetChromeFlags()

■ CWebBrowserChrome::SetChromeFlags()

■ CWebBrowserChrome::IsWindowModal()

■ CWebBrowserChrome::ShowAsModal()

■ CWebBrowserChrome::ExitModalEventLoop()

■ CWebBrowserChrome::SetPersistence()

■ CWebBrowserChrome::GetPersistence()

PPBrowserでは、これらの実装は空です。

◆◆◆ nsIWebProgressListenerインターフェース ◆◆◆

■ CWebBrowserChrome::OnProgressChange() - プログレスチェンジ

ドキュメントロードの進行状況が変化した時にコールされます。CBrowserWindowに処理を依頼し、プログレスバーの更新などを行います。

NS_IMETHODIMP CWebBrowserChrome::OnProgressChange(nsIWebProgress *progress,
                                 nsIRequest *request,
                                  PRInt32 curSelfProgress, PRInt32 maxSelfProgress,
                                  PRInt32 curTotalProgress, PRInt32 maxTotalProgress)
{
    NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED);

   return mBrowserWindow->OnProgressChange(progress, request,
                                           curSelfProgress, maxSelfProgress,
                                           curTotalProgress, maxTotalProgress);
}

■ CWebBrowserChrome::OnStateChange() - ステータスチェンジ

ネット処理のステータスが変化した時にコールされます。CBrowserWindowに処理を依頼し、プログレスバー、スロッバー、各種ボタンの更新などを行います。

NS_IMETHODIMP CWebBrowserChrome::OnStateChange(nsIWebProgress *progress,
                                          nsIRequest *request,
                                           PRInt32 progressStateFlags, PRUint32 status)
{
    NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED);

    if (progressStateFlags & STATE_IS_NETWORK) {
      if (progressStateFlags & STATE_START)
         mBrowserWindow->OnStatusNetStart(progress, request, progressStateFlags, status);
      else if (progressStateFlags & STATE_STOP)
          mBrowserWindow->OnStatusNetStop(progress, request, progressStateFlags, status);
    }

   return NS_OK;
}

■ CWebBrowserChrome::OnLocationChange() - ロケーションチェンジ

新しいページがロードされた時にコールされます。CBrowserWindowに処理を依頼し、ロケーションバーに解決済みのURLを表示しています。

NS_IMETHODIMP CWebBrowserChrome::OnLocationChange(nsIWebProgress* aWebProgress,
                                                  nsIRequest* aRequest,
                                                  nsIURI *location)
{
    NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED);

    char *buf = nsnull;

    if (location)
        location->GetSpec(&buf);

    nsAutoString tmp; tmp.AssignWithConversion(buf);
    mBrowserWindow->SetLocation(tmp);

    if (buf)
        Recycle(buf);

    return NS_OK;
}
 

■ CWebBrowserChrome::OnStatusChange()

■ CWebBrowserChrome::OnSecurityChange()

PPBrowserでは、これらの実装は空です。

◆◆◆ nsIBaseWindowインターフェース ◆◆◆

■ CWebBrowserChrome::InitWindow() - ウィンドウ初期化

ウィンドウを初期化します。同インターフェース内のSetPositionAndSize() により、位置とサイズを設定しています。

NS_IMETHODIMP CWebBrowserChrome::InitWindow(nativeWindow aParentNativeWindow,
   nsIWidget* parentWidget, PRInt32 x, PRInt32 y, PRInt32 cx, PRInt32 cy)   
{
   // Ignore wigdet parents for now.  Don't think those are a vaild thing to call.
   NS_ENSURE_SUCCESS(SetPositionAndSize(x, y, cx, cy, PR_FALSE), NS_ERROR_FAILURE);

   return NS_OK;
}

■ CWebBrowserChrome::SetPosition() - 位置設定

■ CWebBrowserChrome::GetPosition() - 位置取得

■ CWebBrowserChrome::SetSize() - サイズ設定

■ CWebBrowserChrome::GetSize() - サイズ取得

■ CWebBrowserChrome::SetPositionAndSize() - 位置サイズ設定

■ CWebBrowserChrome::GetPositionAndSize() - 位置サイズ取得

ウインドウの位置、サイズの設定、取得を行います。全て、CBrowserWindowに処理を依頼しています。

NS_IMETHODIMP CWebBrowserChrome::SetPosition(PRInt32 x, PRInt32 y)
{
    NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED);

   mBrowserWindow->MoveWindowTo(x, y);
   return NS_OK;
}

NS_IMETHODIMP CWebBrowserChrome::GetPosition(PRInt32* x, PRInt32* y)
{
    NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED);
   NS_ENSURE_ARG_POINTER(x && y);

   Rect  bounds;
   mBrowserWindow->GetGlobalBounds(bounds);
   *x = bounds.left;
   *y = bounds.top;
   return NS_OK;
}

NS_IMETHODIMP CWebBrowserChrome::SetSize(PRInt32 cx, PRInt32 cy, PRBool fRepaint)
{
    NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED);

   mBrowserWindow->ResizeFrameTo(cx, cy + kGrowIconSize, fRepaint);
   return NS_OK;
}

NS_IMETHODIMP CWebBrowserChrome::GetSize(PRInt32* cx, PRInt32* cy)
{
   NS_ENSURE_ARG_POINTER(cx && cy);
    NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED);

   Rect  bounds;
   mBrowserWindow->GetGlobalBounds(bounds);
   *cx = bounds.right - bounds.left;
   *cy = bounds.bottom - bounds.top - kGrowIconSize;
   return NS_OK;
}

NS_IMETHODIMP CWebBrowserChrome::SetPositionAndSize(PRInt32 x, PRInt32 y,
                    PRInt32 cx, PRInt32 cy, PRBool fRepaint)
{
    NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED);

   Rect  bounds;
   bounds.top = y;
   bounds.left = x;
   bounds.bottom = y + cy + kGrowIconSize;
   bounds.right = x + cx;

   mBrowserWindow->DoSetBounds(bounds);
   return NS_OK;
}

NS_IMETHODIMP CWebBrowserChrome::GetPositionAndSize(PRInt32* x, PRInt32* y,
                    PRInt32* cx, PRInt32* cy)
{
   NS_ENSURE_ARG_POINTER(x && y && cx && cy);
    NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED);

   Rect  bounds;
   mBrowserWindow->GetGlobalBounds(bounds);
   *x = bounds.left;
   *y = bounds.top;
   *cx = bounds.right - bounds.left;
   *cy = bounds.bottom - bounds.top - kGrowIconSize;

   return NS_OK;
}

■ CWebBrowserChrome::Repaint() - リペイント

ウインドウの再描画をします。CBrowserWindowに処理を依頼しています。aFourceが偽の時は、Updateイベント送信により、aFourceが真の時は、直接描画により、再描画しています。

NS_IMETHODIMP CWebBrowserChrome::Repaint(PRBool aForce)
{
    NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED);

   mBrowserWindow->Refresh();
   if (aForce)
      mBrowserWindow->UpdatePort();
      
   return NS_OK;
}

■ CWebBrowserChrome::GetVisibility() - 表示取得

■ CWebBrowserChrome::SetVisibility()- 表示設定

ウインドウの表示/非表示属性を設定/取得します。CBrowserWindowに処理を依頼しています。

NS_IMETHODIMP CWebBrowserChrome::GetVisibility(PRBool* aVisibility)
{
   NS_ENSURE_ARG_POINTER(aVisibility);
    NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED);

   *aVisibility = mBrowserWindow->IsVisible();
   return NS_OK;
}

NS_IMETHODIMP CWebBrowserChrome::SetVisibility(PRBool aVisibility)
{
    NS_ENSURE_TRUE(mBrowserWindow, NS_ERROR_NOT_INITIALIZED);

   if (aVisibility)
   {
      mBrowserWindow->Show();
      mBrowserWindow->Select();
   }
   else
      mBrowserWindow->Hide();
      
   return NS_OK;
}

■ CWebBrowserChrome::GetTitle() - タイトル取得

■ CWebBrowserChrome::SetTitle() - タイトル設定

ウィンドウのタイトルを設定/取得します。CBrowserWindowに処理を依頼しています。

NS_IMETHODIMP CWebBrowserChrome::GetTitle(PRUnichar** aTitle)
{
   NS_ENSURE_ARG_POINTER(aTitle);
   NS_ENSURE_STATE(mBrowserWindow);

   Str255         aStr;
   nsAutoString   titleStr;
   
   mBrowserWindow->GetDescriptor(aStr);
   UMacUnicode::Str255ToString(aStr, titleStr);
   *aTitle = titleStr.ToNewUnicode();
   
   return NS_OK;
}

NS_IMETHODIMP CWebBrowserChrome::SetTitle(const PRUnichar* aTitle)
{
   NS_ENSURE_STATE(mBrowserWindow);

    nsAutoString   titleStr(aTitle);
    Str255         aStr;

    UMacUnicode::StringToStr255(titleStr, aStr);
   mBrowserWindow->SetDescriptor(aStr);
   
   return NS_OK;
}

■ CWebBrowserChrome::Create()

■ CWebBrowserChrome::Destroy()

■ CWebBrowserChrome::GetParentWidget()

■ CWebBrowserChrome::SetParentWidget()

■ CWebBrowserChrome::GetParentNativeWindow()

■ CWebBrowserChrome::SetParentNativeWindow()

■ CWebBrowserChrome::GetMainWidget()

■ CWebBrowserChrome::SetFocus()

■ CWebBrowserChrome::FocusAvailable()

PPBrowserでは、これらの実装は空です。


◆◆◆ nsIPromptインターフェース ◆◆◆

■ CWebBrowserChrome::Alert() - アラート表示

モジラ側からのアラートダイアログの表示依頼です。PowerPlant固有の方法で、Layoutリソースより、アラートダイアログを表示しています。

NS_IMETHODIMP CWebBrowserChrome::Alert(const PRUnichar *dialogTitle, const PRUnichar *text)
{
    RegisterClass_(LIconControl);
    
    StDialogHandler theHandler(dlog_Alert, mBrowserWindow);
    LWindow          *theDialog = theHandler.GetDialog();
    Str255            aStr;

    UMacUnicode::StringToStr255(nsString(text), aStr);

    LStaticText *msgText = dynamic_cast<LStaticText*>(theDialog->FindPaneByID('Msg '));
    msgText->SetDescriptor(aStr);

    theDialog->Show();
    theDialog->Select();

    while (true)  // This is our modal dialog event loop
    {
        MessageT    hitMessage = theHandler.DoDialog();

        if (hitMessage == msg_OK)
            break;
    }

    return NS_OK;
}

■ CWebBrowserChrome::AlertCheck() - アラートチェック付き表示

■ CWebBrowserChrome::Confirm() - コンファーム表示

■ CWebBrowserChrome::ConfirmCheck() - コンファームチェック付き表示

■ CWebBrowserChrome::Prompt() - プロンプト表示

■ CWebBrowserChrome::PromptUsernameAndPassword() - ユーザー名パスワードプロンプト表示

■ CWebBrowserChrome::PromptPassword() - パスワードプロンプト表示

■ CWebBrowserChrome::Select() - セレクト表示

■ CWebBrowserChrome::UniversalDialog() - ユニバーサルダイアログ表示

各種ダイアログの表示依頼です。ダイアログ上のパーツが異なるだけで、Alert() と基本的インプリメントは同じですので、コードは割愛します。Select()、UniversalDialog() は、未インプリメントです。

c_o_n_t_a_c_t
Copyright (C) 2000-2002 Symphony, Inc. All Rights Reserved.
English