mazilla mozilla
Introduction
What's mozilla
Purpose of this page
Characteristics of mozilla
Survey of mozilla
Module
Web tool
Technology of mozilla
Other resource
Building mozilla
Construction of environment
for building
Checkout of source
Procedure for building
Image of after-building
Execute mozilla
Embedding
What's embedding
Concept of embedding
Structure of PPBrowser
Analysis of PPBrowser
Structure of embedding
Structure of marbrow
Analysis of marbrow
Fizzilla
What's fizzilla
Build fizzilla
Embedding of fizzilla
FAQ
Talk with Mr. Yatsugi

Analysis of PPBrowser

Let's analyze PPBrowser!!


On this section, I analyze the code of PPBrowser in practice.


CBrowserApp class

main() - Main function

After initializing Toolbox related things, this creates CBrowserApp class and dives into Event loop.

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;
}

In mozilla/lib/, there is InitializeMacToolbox() function that initializes Macintosh Toolbox related matters. But, PPBRowser uses PowerPlant and plain Macintosh functions to initialize Toolbox.

CBrowserApp::CBrowserApp() - Constructor

Most important process in this is to initialize EmbeddingAPI. This gets application's directory and by passing it to NS_InitEmbedding(), initializes it.

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);

And this initializes the preference "PP Browser" in system's preferences folder and sets English font size to 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() - Destructor

Most important process in this is to terminate EmbeddingAPI. In addition, to save preference, to clean up UMacUnicode.

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

   UMacUnicode::ReleaseUnit();

   NS_TermEmbedding();
}

CBrowserApp::StartUp() - Startup

In PowerPlant specific way, show initial main window.

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

CBrowserApp::ProcessNextEvent() - Event process

To do event processing necessary to mozilla, this overrides 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();
    }
}

One of event processings unique to mozilla is to call static member of Repeater class to make background process such as net process worked. This calls Repeater::DoIdlers() at each null event and calls Repeater::DoRepeaters() at each event loop.

Besides, this does SIOUX event processing for debug console when Debug Building is in effect.

CBrowserApp::ObeyCommand() - Command process

This does cmd_New processing. In a way specific to PowerPlant, this creates main window and load URL into it. Here, URL is fixed up on "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 class

Class definition

Class definition of CBrowserWindow has, as member variable associated with mozilla, a pointer to window widget that is representation unique to mozilla of the main window, a pointer to each instance held as child control and a pointer to chrome instance.

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() - Constructor

Constructor of CBrowserWindow class creates an instance of mozilla widget for main window. And this creates browser chrome and associates browser chrome with itself.

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;
}

Initializing process of each visual parts in PowerPlant is called in the order shown below.

  1. Constructor in order from upper to lower
  2. FinishCreate() in order from upper to lower
  3. FinishCreateSelf() in order from lower to upper

CBrowserWindow::~CBrowserWindow() - Destructor

Destructor of CBrowserWindow class disposes of browser chrome.

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

CBrowserWindow::FinishCreate() - Final process after creation of the said CBrowserWindow

By widget instance created in constructor, this creates an actual mozilla window.

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() - Final process after construction of all hierarchy

Mozilla specific process in this method is to set up and initialize CWebBrowserChrome, to associate CBrowserShell with CWebBrowserChrome and to set up each child control to member variables.

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*>(FindPaneBy   ID(paneID_StopButton));
    if (mStopButton)
        mStopButton->Disable();

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

CBrowserWindow::ResizeFrameBy() - Resize process

CBrowserWindow::ShowSelf() - Shown

Main window's geometric manipuration such as showing/hiding or resizing are requested to mozilla widget by way of 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() - Command process

This procedure does menu related matters. Instructions to child controls held by main window and Find procedure. All of them are requested to 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() - Setting up character string of status bar

CBrowserWindow::SetLocation() - Setting up character string of location bar

Method called by CWebBrowserChrome (browser chrome). Character string is converted to Unicode -> nsString -> Str255 by using nsAutoString, UMacUnicode.

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() - Starting net process

Method called by CWebBrowserChrome at the start time of net process. This starts progress bar and throbber and enables Stop button.

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() - Terminating net process

Method called by CWebBrowserChrome at the end of net process. This stops progress bar and throbber, sets up status of Back & Forward buttons and disables Stop button.

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() - Progress change

Method called by CWebBrowserChrome at the progress change of net process. This updates the value of progress bar.

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 class

Class definition

Class definition of CBrowserShell has, as member variables associated with mozilla, initial URL character string, a pointer to interface associated with WebBrowser and a pointer to Find Component. And, this has, as a static member, message sink with which events are send to mozilla.

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;
};

yCBrowserShell.cpz

// CBrowserShell static variables
nsMacMessageSink	CBrowserShell::mMessageSink;

Actual event processing code of mozilla exists in the widget module. In case of embedding, various events gotten at framework are sent to mozilla by way of nsMacMessageSink's mMessageSink.DispatchOSEvent().

As far as embedding, the XPCOM world is spread all over in CBrowserShell class and CWebBrowserChrome class. In XPCOM, one XPCOM instance holds multiple interfaces classified by their usage. When you want to request a XPCOM instance to do something, you should get the interface you hope via QueryInterface() and call the method through that interface pointer.

CBrowserShell::CBrowserShell() - Constructor

Constructor of CBrowserShell class creates XPCOM instance of browser (HTML part).

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;
}

Browser is an instance of nsWebBrowser class. Its source code exists in the embedding module. nsWebBrowser is instanciated by do_CreateInstance(NS_WEBBROWSER_CONTRACTID, &rv); and returns nsIWebBrower that is his typical interface. It is housed in mWebBrowser member variable.

In case that you manipulate nsWebBrowser, all you have to keep is this nsIWebBrower mWebBrowser and that's enough, and you can get whatever interfaces you want by QI()ing via nsIWebBrowser whenever other interfaces are necessary. But in this procedure, nsIBaseWindow, nsIWebNavigation are gotten and kept in member variables in this timing, 'cause afterwards they are referenced very often.

CBrowserShell::~CBrowserWindow() - Destructor

Destrutor of CBrowserShell class disposes of Find Component.

CBrowserShell::~CBrowserShell()
{
    delete mFinder;

    // nsCOMPtr destructors, do your thing
}

CBrowserShell::FinishCreateSelf() - Final process after the construction of all hierarchy

In this procedure, process specific to mozilla is to initialize the geometry of nsWebBrowser (position, size and so on). By InitWindow() and Create() of nsIBaseWindow mWebBrowserAsBaseWin, that is the interface associated with the geometry, initialization is done anyway. Then, by AdjustFrame() common method, the position and size are arranged precisely.

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() - Initializing and setting up the browser chrome

This is called by CBrowserWindow::FinishCreateSelf(). The final stage of browser initialization. By calling nsIWebBrowser::SetContainerWindow(), nsWebBrowser recognizes CWebBrowserChrome object as a chrome.

And, as the code comment says, if you want to initialize nsIDocShell related matters, it can be done here also.

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() - Resize process

CBrowserShell::MoveBy() - Move process

CBrowserShell::AdjustFrame() - Frame adjustment common process

This is called when the geometry of nsWebBrowser (position, size and so on) changes. In addition to the processes specific to PowerPlant, after all, the position and size are adjusted correctly by AdjustFrame() common method. In AdjustFrame(), by nsIBaseWindow::SetPositionAndSize(), the browser is informed of new geometry.

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() - Shown

nsIBaseWindow::SetVisibility() makes a browser shown.

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

Associated with event

CBrowserShell::ClickSelf() - Mouse down process

CBrowserShell::EventMouseUp() - Mouse up process

CBrowserShell::AdjustCursorSelf() - Mouse move process

CBrowserShell::HandleMouseMoved() - Mouse move common process

CBrowserShell::HandleKeyPress() - Key press process

CBrowserShell::SpendTime() - Idle process (SuspendResume)

These are event processings. nsMacMessageSink's DispatchOSEvent() send the event to the browser.

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() - Command process

Clipboard processes such as copy, paste and so on.

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;
}

In the above, nsIDocShell interface is gotten from nsIWebBrowser interface.
Because nsDocShell is held indirectly by nsWebBrowser, the interface is gotten not by do_QueryInterface() but by do_GetInterface().

Associated with navigation

CBrowserShell::CanGoBack() - Able to go back?

CBrowserShell::CanGoForward() - Able to go forward?

CBrowserShell::Back() - Back process

CBrowserShell::Forward() - Forward process

CBrowserShell::Stop() - Stop process

All actual processes are requested to nsIWebNavigation interface.

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() - Loading URL

This also requests nsIWebNavigation interface to do the process. Two methods are overloaded, one for plain character string, one for 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() - Browser getter

CBrowserShell::SetWebBrowser() - Browser setter

These are methods called by CWebBrowserChrome, and are getter & setter of a browser (nsIWebBrowser) used by the chrome class.

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 class

By implementing some pre-defined XPCOM interfaces and being associated with the browser class, this class manages all sorts of exchange with mozilla side. I show the interfaces actually implemented below.

  • nsIWebBrowserChrome - Basic interface as a browser chrome
  • nsIWebProgressListener - Interface for receiveing the information about progress status of page loading
  • nsIBaseWindow - Interface for adding functions as a general window
  • nsIPrompt - Interface for showing various prompt dialogs
  • nsIInterfaceRequestor - Interface defining method to get an intergface the object implements

nsIInterfaceRequestor interface is used when you want to implement some interfaces in a little different way from general XPCOM. In general XPCOM, if it is possible to do QI() on Interface A to get to Interface B, conversely, it also must be possible to do QI() on Interface B to get to Interface A. But, nsIInterfaceRequestor enables one-way getting. In this case, interfaces are gotton not by QI() but by GetInterface().

Above-mentioned nsIDocShell is held by nsWebBrowser via nsIInterfaceRequestor. Therefore, on nsIWebBrowser, nsIDocShell interface should be gotton to, not by QueryInterface() but by GetInterface().

Class definition

Class definition of CWebBrowserChrome inherits from the interfaces it implements and defines these methods. These method definitions are expanded by the macro such as NS_DECL_ISUPPORTS, NS_DECL_NSIWEBBROWSERCHROME.

As member variables, this has a pointer to CBrowserWindow and CBrowserShell to keep association with them. And, as a static variable, this has the browser list (STL vector array of CWebBrowserChrom* type keeping all chrome instances it creates).

And, this class becoms "C++ friend" of CBrowserWindow class, and that makes it easier to access CBrowserWindow class members.

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;
};

yCWebBrowserChrome.cpz

// 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

Moreover, by above-mentioned macro, this implements AddRef(), Release() and QueryInterface().

CWebBrowserChrome::CWebBrowserChrome() - Constructor

Constructor of CWebBrowserChrome class adds itself to the browser list.

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

    mgBrowserList.push_back(this);
}

CWebBrowserChrome::~CWebBrowserChrome() - Destructor

Destructor of CWebBrowserChrome class deletes itself from the browser list.

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

CWebBrowserChrome::BrowserWindow() - BrowserWindow accessor

CWebBrowserChrome::BrowserShell() - BrowserShell accessor

Accessor methods to CBrowserWindow and CBrowserShell associated with this chrome instance. This code uses the reference to a pointer and can do both right side value reference and left side value assignment.

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

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

nsIInterfaceRequestor interface

CWebBrowserChrome::GetInterface() - Getting an interface

This processes GetInterface() from the outside. In this code, all GetInterface() are processed as QueryInterface(), and nothing special.

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

nsIWebBrowserChrome interface

CWebBrowserChrome::SetStatus() - Informing of the status

This method is called when HTML document informs the chrome of status string.

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 is from Javascript and STATUS_LINK is href character string of a link on HTML document. Both request CBrowserWindow to show the status bar.

CWebBrowserChrome::GetWebBrowser() - Getting a browser

CWebBrowserChrome::SetWebBrowser() - Setting up a browser

This is the information from mozilla side of getting and setting up a browser. Both actual processes are left to 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() - Creating a browser window

This is a request from mozilla side to create a browser window. This is called by mozilla when a new window is created by a link click in HTML document etc. In PPBrowser, PlainBrowserWindow of Layout = 130 is always created (a simple window owning only one browser). Ideally, according to the value of chromeMask, a window owning proper parts should be created.

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() - Searching a browser item by its name

This searches a browser item corresponding to the given name and returns it.

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???
}
 

This iterates the browser list and seaches it by docShellAsItem::FindItemWithName().

CWebBrowserChrome::SizeBrowserTo() - Size process

This is the information of a change in size of the brower.

// Constants
const PRInt32     kGrowIconSize = 15;

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

This calcurates size of client area of window from size of browser and requests CBrowserWindow to resize.

CWebBrowserChrome::GetChromeFlags()

CWebBrowserChrome::SetChromeFlags()

CWebBrowserChrome::IsWindowModal()

CWebBrowserChrome::ShowAsModal()

CWebBrowserChrome::ExitModalEventLoop()

CWebBrowserChrome::SetPersistence()

CWebBrowserChrome::GetPersistence()

In PPBrowser, these implementations are empty.

nsIWebProgressListener interface

CWebBrowserChrome::OnProgressChange() - Progress change

This is called when the progress status of document load changes. This requests CBrowserWindow to do the process and updates progress bar etc.

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() - Status change

This is called when the status of net process changes. This requests CBrowserWindow to do the process and updates progress bar, throbber, various buttons and so on.

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() - Location change

This is called when a new page is loaded. This requests CBrowserWindow to do the process and shows resolved URL on location bar.

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()

In PPBrowser, these implementations are empty.

nsIBaseWindow interface

CWebBrowserChrome::InitWindow() - Initializing a window

This initializes a window. By SetPositionAndSize() on the same interface, the position and size are set up.

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() - Setting up the position

CWebBrowserChrome::GetPosition() - Getting the position

CWebBrowserChrome::SetSize() - Setting up the size

CWebBrowserChrome::GetSize() - Getting the size

CWebBrowserChrome::SetPositionAndSize() - Setting up the position and size

CWebBrowserChrome::GetPositionAndSize() - Getting the position and size

This sets up and gets the position and size of window. This requests CBrowserWindow to do each processes.

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() - Repaint

This repaints window and requests CBrowserWindow to do the process. When aFource is false, by sending Update event, and when aFource is true, by direct painting, this repaints it.

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() - Getting a visibility

CWebBrowserChrome::SetVisibility()- Setting up a visibility

This sets up/gets the window's show/hide property. This requests CBrowserWindow to do the process.

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() - Getting a title

CWebBrowserChrome::SetTitle() - Setting up a title

This sets up/gets a title of the window. This requests CBrowserWindow to do the process.

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()

In PPBrowser, these implementations are empty.

nsIPrompt interface

CWebBrowserChrome::Alert() - Showing alert

This is a request from mozilla side to show an alert dialog. In the way specific to PowerPlant, this shows the alert dialog from Layout resource.

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() - Showing an alert with a check

CWebBrowserChrome::Confirm() - Showing a confirm

CWebBrowserChrome::ConfirmCheck() -Showing a confirm with a check

CWebBrowserChrome::Prompt() - Showing a prompt

CWebBrowserChrome::PromptUsernameAndPassword() - Showing the user name and the password prompt

CWebBrowserChrome::PromptPassword() - Showing a password prompt

CWebBrowserChrome::Select() - Showing a select

CWebBrowserChrome::UniversalDialog() - Showing an universal dialog

These are requests to show various dialogs. Basically the procedures are the same as Alert(), and the difference is only the U.I. parts displayed on the dialog. So, I omit these codes. Select() and UniversalDialog() are not implemented yet.

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