LCOV - code coverage report
Current view: directory - xpfe/appshell/src - nsWebShellWindow.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 285 0 0.0 %
Date: 2012-06-02 Functions: 20 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla Communicator client code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Pierre Phaneuf <pp@ludusdesign.com>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : 
      40                 : #include "nsWebShellWindow.h"
      41                 : 
      42                 : #include "nsLayoutCID.h"
      43                 : #include "nsContentCID.h"
      44                 : #include "nsIWeakReference.h"
      45                 : #include "nsIContentViewer.h"
      46                 : #include "nsIComponentManager.h"
      47                 : #include "nsIServiceManager.h"
      48                 : #include "nsIURL.h"
      49                 : #include "nsIIOService.h"
      50                 : #include "nsIURL.h"
      51                 : #include "nsNetCID.h"
      52                 : #include "nsIStringBundle.h"
      53                 : #include "nsReadableUtils.h"
      54                 : 
      55                 : #include "nsEscape.h"
      56                 : #include "nsPIDOMWindow.h"
      57                 : #include "nsIDOMEventTarget.h"
      58                 : #include "nsIPrivateDOMEvent.h"
      59                 : #include "nsIWebNavigation.h"
      60                 : #include "nsIWindowWatcher.h"
      61                 : 
      62                 : #include "nsIDOMXULElement.h"
      63                 : 
      64                 : #include "nsGUIEvent.h"
      65                 : #include "nsWidgetsCID.h"
      66                 : #include "nsIWidget.h"
      67                 : 
      68                 : #include "nsIDOMCharacterData.h"
      69                 : #include "nsIDOMNodeList.h"
      70                 : 
      71                 : #include "nsITimer.h"
      72                 : #include "nsXULPopupManager.h"
      73                 : 
      74                 : #include "prmem.h"
      75                 : 
      76                 : #include "nsIDOMXULDocument.h"
      77                 : 
      78                 : #include "nsFocusManager.h"
      79                 : 
      80                 : #include "nsIWebProgress.h"
      81                 : #include "nsIWebProgressListener.h"
      82                 : 
      83                 : #include "nsIDocument.h"
      84                 : #include "nsIDOMDocument.h"
      85                 : #include "nsIDOMNode.h"
      86                 : #include "nsIDOMElement.h"
      87                 : #include "nsIDocumentLoaderFactory.h"
      88                 : #include "nsIObserverService.h"
      89                 : #include "prprf.h"
      90                 : 
      91                 : #include "nsIScreenManager.h"
      92                 : #include "nsIScreen.h"
      93                 : 
      94                 : #include "nsIContent.h" // for menus
      95                 : 
      96                 : // For calculating size
      97                 : #include "nsIFrame.h"
      98                 : #include "nsIPresShell.h"
      99                 : #include "nsPresContext.h"
     100                 : 
     101                 : #include "nsIBaseWindow.h"
     102                 : #include "nsIDocShellTreeItem.h"
     103                 : #include "nsIDocShellTreeNode.h"
     104                 : 
     105                 : #include "nsIMarkupDocumentViewer.h"
     106                 : 
     107                 : #ifdef XP_MACOSX
     108                 : #include "nsINativeMenuService.h"
     109                 : #define USE_NATIVE_MENUS
     110                 : #endif
     111                 : 
     112                 : using namespace mozilla;
     113                 : 
     114                 : /* Define Class IDs */
     115                 : static NS_DEFINE_CID(kWindowCID,           NS_WINDOW_CID);
     116                 : 
     117                 : #define SIZE_PERSISTENCE_TIMEOUT 500 // msec
     118                 : 
     119               0 : nsWebShellWindow::nsWebShellWindow(PRUint32 aChromeFlags)
     120                 :   : nsXULWindow(aChromeFlags)
     121               0 :   , mSPTimerLock("nsWebShellWindow.mSPTimerLock")
     122                 : {
     123               0 : }
     124                 : 
     125                 : 
     126               0 : nsWebShellWindow::~nsWebShellWindow()
     127                 : {
     128               0 :   if (mWindow) {
     129               0 :     mWindow->SetClientData(0);
     130               0 :     mWindow->Destroy();
     131               0 :     mWindow = nsnull; // Force release here.
     132                 :   }
     133                 : 
     134               0 :   MutexAutoLock lock(mSPTimerLock);
     135               0 :   if (mSPTimer)
     136               0 :     mSPTimer->Cancel();
     137               0 : }
     138                 : 
     139               0 : NS_IMPL_ADDREF_INHERITED(nsWebShellWindow, nsXULWindow)
     140               0 : NS_IMPL_RELEASE_INHERITED(nsWebShellWindow, nsXULWindow)
     141                 : 
     142               0 : NS_INTERFACE_MAP_BEGIN(nsWebShellWindow)
     143               0 :   NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
     144               0 : NS_INTERFACE_MAP_END_INHERITING(nsXULWindow)
     145                 : 
     146               0 : nsresult nsWebShellWindow::Initialize(nsIXULWindow* aParent,
     147                 :                                       nsIXULWindow* aOpener,
     148                 :                                       nsIURI* aUrl,
     149                 :                                       PRInt32 aInitialWidth,
     150                 :                                       PRInt32 aInitialHeight,
     151                 :                                       bool aIsHiddenWindow,
     152                 :                                       nsWidgetInitData& widgetInitData)
     153                 : {
     154                 :   nsresult rv;
     155               0 :   nsCOMPtr<nsIWidget> parentWidget;
     156                 : 
     157               0 :   mIsHiddenWindow = aIsHiddenWindow;
     158                 : 
     159               0 :   PRInt32 initialX = 0, initialY = 0;
     160               0 :   nsCOMPtr<nsIBaseWindow> base(do_QueryInterface(aOpener));
     161               0 :   if (base) {
     162               0 :     rv = base->GetPositionAndSize(&mOpenerScreenRect.x,
     163                 :                                   &mOpenerScreenRect.y,
     164                 :                                   &mOpenerScreenRect.width,
     165               0 :                                   &mOpenerScreenRect.height);
     166               0 :     if (NS_FAILED(rv)) {
     167               0 :       mOpenerScreenRect.SetEmpty();
     168                 :     } else {
     169               0 :       initialX = mOpenerScreenRect.x;
     170               0 :       initialY = mOpenerScreenRect.y;
     171               0 :       ConstrainToOpenerScreen(&initialX, &initialY);
     172                 :     }
     173                 :   }
     174                 : 
     175                 :   // XXX: need to get the default window size from prefs...
     176                 :   // Doesn't come from prefs... will come from CSS/XUL/RDF
     177               0 :   nsIntRect r(initialX, initialY, aInitialWidth, aInitialHeight);
     178                 :   
     179                 :   // Create top level window
     180               0 :   mWindow = do_CreateInstance(kWindowCID, &rv);
     181               0 :   if (NS_OK != rv) {
     182               0 :     return rv;
     183                 :   }
     184                 : 
     185                 :   /* This next bit is troublesome. We carry two different versions of a pointer
     186                 :      to our parent window. One is the parent window's widget, which is passed
     187                 :      to our own widget. The other is a weak reference we keep here to our
     188                 :      parent WebShellWindow. The former is useful to the widget, and we can't
     189                 :      trust its treatment of the parent reference because they're platform-
     190                 :      specific. The latter is useful to this class.
     191                 :        A better implementation would be one in which the parent keeps strong
     192                 :      references to its children and closes them before it allows itself
     193                 :      to be closed. This would mimic the behaviour of OSes that support
     194                 :      top-level child windows in OSes that do not. Later.
     195                 :   */
     196               0 :   nsCOMPtr<nsIBaseWindow> parentAsWin(do_QueryInterface(aParent));
     197               0 :   if (parentAsWin) {
     198               0 :     parentAsWin->GetMainWidget(getter_AddRefs(parentWidget));
     199               0 :     mParentWindow = do_GetWeakReference(aParent);
     200                 :   }
     201                 : 
     202               0 :   mWindow->SetClientData(this);
     203               0 :   mWindow->Create((nsIWidget *)parentWidget,          // Parent nsIWidget
     204                 :                   nsnull,                             // Native parent widget
     205                 :                   r,                                  // Widget dimensions
     206                 :                   nsWebShellWindow::HandleEvent,      // Event handler function
     207                 :                   nsnull,                             // Device context
     208               0 :                   &widgetInitData);                   // Widget initialization data
     209               0 :   mWindow->GetClientBounds(r);
     210                 :   // Match the default background color of content. Important on windows
     211                 :   // since we no longer use content child widgets.
     212               0 :   mWindow->SetBackgroundColor(NS_RGB(255,255,255));
     213                 : 
     214                 :   // Create web shell
     215               0 :   mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
     216               0 :   NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
     217                 : 
     218                 :   // Make sure to set the item type on the docshell _before_ calling
     219                 :   // Create() so it knows what type it is.
     220               0 :   nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
     221               0 :   NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
     222               0 :   NS_ENSURE_SUCCESS(EnsureChromeTreeOwner(), NS_ERROR_FAILURE);
     223                 : 
     224               0 :   docShellAsItem->SetTreeOwner(mChromeTreeOwner);
     225               0 :   docShellAsItem->SetItemType(nsIDocShellTreeItem::typeChrome);
     226                 : 
     227               0 :   r.x = r.y = 0;
     228               0 :   nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
     229               0 :   NS_ENSURE_SUCCESS(docShellAsWin->InitWindow(nsnull, mWindow, 
     230                 :    r.x, r.y, r.width, r.height), NS_ERROR_FAILURE);
     231               0 :   NS_ENSURE_SUCCESS(docShellAsWin->Create(), NS_ERROR_FAILURE);
     232                 : 
     233                 :   // Attach a WebProgress listener.during initialization...
     234               0 :   nsCOMPtr<nsIWebProgress> webProgress(do_GetInterface(mDocShell, &rv));
     235               0 :   if (webProgress) {
     236               0 :     webProgress->AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_NETWORK);
     237                 :   }
     238                 : 
     239               0 :   if (nsnull != aUrl)  {
     240               0 :     nsCString tmpStr;
     241                 : 
     242               0 :     rv = aUrl->GetSpec(tmpStr);
     243               0 :     if (NS_FAILED(rv)) return rv;
     244                 : 
     245               0 :     NS_ConvertUTF8toUTF16 urlString(tmpStr);
     246               0 :     nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
     247               0 :     NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
     248               0 :     rv = webNav->LoadURI(urlString.get(),
     249                 :                          nsIWebNavigation::LOAD_FLAGS_NONE,
     250                 :                          nsnull,
     251                 :                          nsnull,
     252               0 :                          nsnull);
     253               0 :     NS_ENSURE_SUCCESS(rv, rv);
     254                 :   }
     255                 :                      
     256               0 :   return rv;
     257                 : }
     258                 : 
     259                 : 
     260                 : /*
     261                 :  * Toolbar
     262                 :  */
     263                 : nsresult
     264               0 : nsWebShellWindow::Toolbar()
     265                 : {
     266               0 :     nsCOMPtr<nsIXULWindow> kungFuDeathGrip(this);
     267               0 :     nsCOMPtr<nsIWebBrowserChrome> wbc(do_GetInterface(kungFuDeathGrip));
     268               0 :     if (!wbc)
     269               0 :       return NS_ERROR_UNEXPECTED;
     270                 : 
     271                 :     // rjc: don't use "nsIWebBrowserChrome::CHROME_EXTRA"
     272                 :     //      due to components with multiple sidebar components
     273                 :     //      (such as Mail/News, Addressbook, etc)... and frankly,
     274                 :     //      Mac IE, OmniWeb, and other Mac OS X apps all work this way
     275                 : 
     276                 :     PRUint32    chromeMask = (nsIWebBrowserChrome::CHROME_TOOLBAR |
     277                 :                               nsIWebBrowserChrome::CHROME_LOCATIONBAR |
     278               0 :                               nsIWebBrowserChrome::CHROME_PERSONAL_TOOLBAR);
     279                 : 
     280               0 :     PRUint32    chromeFlags, newChromeFlags = 0;
     281               0 :     wbc->GetChromeFlags(&chromeFlags);
     282               0 :     newChromeFlags = chromeFlags & chromeMask;
     283               0 :     if (!newChromeFlags)    chromeFlags |= chromeMask;
     284               0 :     else                    chromeFlags &= (~newChromeFlags);
     285               0 :     wbc->SetChromeFlags(chromeFlags);
     286               0 :     return NS_OK;
     287                 : }
     288                 : 
     289                 : 
     290                 : /*
     291                 :  * Event handler function...
     292                 :  *
     293                 :  * This function is called to process events for the nsIWidget of the 
     294                 :  * nsWebShellWindow...
     295                 :  */
     296                 : nsEventStatus
     297               0 : nsWebShellWindow::HandleEvent(nsGUIEvent *aEvent)
     298                 : {
     299               0 :   nsEventStatus result = nsEventStatus_eIgnore;
     300               0 :   nsIDocShell* docShell = nsnull;
     301               0 :   nsWebShellWindow *eventWindow = nsnull;
     302                 : 
     303                 :   // Get the WebShell instance...
     304               0 :   if (nsnull != aEvent->widget) {
     305                 :     void* data;
     306                 : 
     307               0 :     aEvent->widget->GetClientData(data);
     308               0 :     if (data != nsnull) {
     309               0 :       eventWindow = reinterpret_cast<nsWebShellWindow *>(data);
     310               0 :       docShell = eventWindow->mDocShell;
     311                 :     }
     312                 :   }
     313                 : 
     314               0 :   if (docShell) {
     315               0 :     switch(aEvent->message) {
     316                 :       /*
     317                 :        * For size events, the DocShell must be resized to fill the entire
     318                 :        * client area of the window...
     319                 :        */
     320                 :       case NS_MOVE: {
     321                 :         // Adjust any child popups so that their widget offsets and coordinates
     322                 :         // are correct with respect to the new position of the window
     323               0 :         nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
     324               0 :         if (pm) {
     325               0 :           nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(docShell);
     326               0 :           pm->AdjustPopupsOnWindowChange(window);
     327                 :         }
     328                 : 
     329                 :         // persist position, but not immediately, in case this OS is firing
     330                 :         // repeated move events as the user drags the window
     331               0 :         eventWindow->SetPersistenceTimer(PAD_POSITION);
     332               0 :         break;
     333                 :       }
     334                 :       case NS_SIZE: {
     335               0 :         nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
     336               0 :         if (pm) {
     337               0 :           nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(docShell);
     338               0 :           pm->AdjustPopupsOnWindowChange(window);
     339                 :         }
     340                 :  
     341               0 :         nsSizeEvent* sizeEvent = (nsSizeEvent*)aEvent;
     342               0 :         nsCOMPtr<nsIBaseWindow> shellAsWin(do_QueryInterface(docShell));
     343               0 :         shellAsWin->SetPositionAndSize(0, 0, sizeEvent->windowSize->width, 
     344               0 :           sizeEvent->windowSize->height, false);  
     345                 :         // persist size, but not immediately, in case this OS is firing
     346                 :         // repeated size events as the user drags the sizing handle
     347               0 :         if (!eventWindow->IsLocked())
     348               0 :           eventWindow->SetPersistenceTimer(PAD_POSITION | PAD_SIZE | PAD_MISC);
     349               0 :         result = nsEventStatus_eConsumeNoDefault;
     350                 :         break;
     351                 :       }
     352                 :       case NS_SIZEMODE: {
     353               0 :         nsSizeModeEvent* modeEvent = (nsSizeModeEvent*)aEvent;
     354                 : 
     355                 :         // an alwaysRaised (or higher) window will hide any newly opened
     356                 :         // normal browser windows. here we just drop a raised window
     357                 :         // to the normal zlevel if it's maximized. we make no provision
     358                 :         // for automatically re-raising it when restored.
     359               0 :         if (modeEvent->mSizeMode == nsSizeMode_Maximized ||
     360                 :             modeEvent->mSizeMode == nsSizeMode_Fullscreen) {
     361                 :           PRUint32 zLevel;
     362               0 :           eventWindow->GetZLevel(&zLevel);
     363               0 :           if (zLevel > nsIXULWindow::normalZ)
     364               0 :             eventWindow->SetZLevel(nsIXULWindow::normalZ);
     365                 :         }
     366                 : 
     367               0 :         aEvent->widget->SetSizeMode(modeEvent->mSizeMode);
     368                 : 
     369                 :         // persist mode, but not immediately, because in many (all?)
     370                 :         // cases this will merge with the similar call in NS_SIZE and
     371                 :         // write the attribute values only once.
     372               0 :         eventWindow->SetPersistenceTimer(PAD_MISC);
     373               0 :         result = nsEventStatus_eConsumeDoDefault;
     374                 : 
     375               0 :         nsCOMPtr<nsPIDOMWindow> ourWindow = do_GetInterface(docShell);
     376               0 :         if (ourWindow) {
     377                 :           // Let the application know if it's in fullscreen mode so it
     378                 :           // can update its UI.
     379               0 :           if (modeEvent->mSizeMode == nsSizeMode_Fullscreen) {
     380               0 :             ourWindow->SetFullScreen(true);
     381                 :           }
     382               0 :           else if (modeEvent->mSizeMode != nsSizeMode_Minimized) {
     383               0 :             ourWindow->SetFullScreen(false);
     384                 :           }
     385                 : 
     386                 :           // And always fire a user-defined sizemodechange event on the window
     387               0 :           ourWindow->DispatchCustomEvent("sizemodechange");
     388                 :         }
     389                 : 
     390                 :         // Note the current implementation of SetSizeMode just stores
     391                 :         // the new state; it doesn't actually resize. So here we store
     392                 :         // the state and pass the event on to the OS. The day is coming
     393                 :         // when we'll handle the event here, and the return result will
     394                 :         // then need to be different.
     395                 :         break;
     396                 :       }
     397                 :       case NS_OS_TOOLBAR: {
     398               0 :         nsCOMPtr<nsIXULWindow> kungFuDeathGrip(eventWindow);
     399               0 :         eventWindow->Toolbar();
     400                 :         break;
     401                 :       }
     402                 :       case NS_XUL_CLOSE: {
     403                 :         // Calling ExecuteCloseHandler may actually close the window
     404                 :         // (it probably shouldn't, but you never know what the users JS 
     405                 :         // code will do).  Therefore we add a death-grip to the window
     406                 :         // for the duration of the close handler.
     407               0 :         nsCOMPtr<nsIXULWindow> kungFuDeathGrip(eventWindow);
     408               0 :         if (!eventWindow->ExecuteCloseHandler())
     409               0 :           eventWindow->Destroy();
     410                 :         break;
     411                 :       }
     412                 :       /*
     413                 :        * Notify the ApplicationShellService that the window is being closed...
     414                 :        */
     415                 :       case NS_DESTROY: {
     416               0 :         eventWindow->Destroy();
     417               0 :         break;
     418                 :       }
     419                 : 
     420                 :       case NS_UISTATECHANGED: {
     421               0 :         nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(docShell);
     422               0 :         if (window) {
     423               0 :           nsUIStateChangeEvent* event = (nsUIStateChangeEvent*)aEvent;
     424               0 :           window->SetKeyboardIndicators(event->showAccelerators, event->showFocusRings);
     425                 :         }
     426                 :         break;
     427                 :       }
     428                 : 
     429                 :       case NS_SETZLEVEL: {
     430               0 :         nsZLevelEvent *zEvent = (nsZLevelEvent *) aEvent;
     431                 : 
     432                 :         zEvent->mAdjusted = eventWindow->ConstrainToZLevel(zEvent->mImmediate,
     433                 :                               &zEvent->mPlacement,
     434               0 :                               zEvent->mReqBelow, &zEvent->mActualBelow);
     435               0 :         break;
     436                 :       }
     437                 : 
     438                 :       case NS_ACTIVATE: {
     439                 : #if defined(DEBUG_saari) || defined(DEBUG_smaug)
     440                 :         printf("nsWebShellWindow::NS_ACTIVATE\n");
     441                 : #endif
     442                 :         // focusing the window could cause it to close, so keep a reference to it
     443               0 :         nsCOMPtr<nsIXULWindow> kungFuDeathGrip(eventWindow);
     444                 : 
     445               0 :         nsCOMPtr<nsIDOMWindow> window = do_GetInterface(docShell);
     446               0 :         nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
     447               0 :         if (fm && window)
     448               0 :           fm->WindowRaised(window);
     449                 : 
     450               0 :         if (eventWindow->mChromeLoaded) {
     451                 :           eventWindow->PersistentAttributesDirty(
     452               0 :                              PAD_POSITION | PAD_SIZE | PAD_MISC);
     453               0 :           eventWindow->SavePersistentAttributes();
     454                 :         }
     455                 : 
     456                 :         break;
     457                 :       }
     458                 : 
     459                 :       case NS_DEACTIVATE: {
     460                 : #if defined(DEBUG_saari) || defined(DEBUG_smaug)
     461                 :         printf("nsWebShellWindow::NS_DEACTIVATE\n");
     462                 : #endif
     463                 : 
     464               0 :         nsCOMPtr<nsIDOMWindow> window = do_GetInterface(docShell);
     465               0 :         nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
     466               0 :         if (fm && window)
     467               0 :           fm->WindowLowered(window);
     468                 :         break;
     469                 :       }
     470                 :       
     471                 :       case NS_GETACCESSIBLE: {
     472               0 :         nsCOMPtr<nsIPresShell> presShell;
     473               0 :         docShell->GetPresShell(getter_AddRefs(presShell));
     474               0 :         if (presShell) {
     475               0 :           presShell->HandleEventWithTarget(aEvent, nsnull, nsnull, &result);
     476                 :         }
     477                 :         break;
     478                 :       }
     479                 :       default:
     480               0 :         break;
     481                 : 
     482                 :     }
     483                 :   }
     484               0 :   return result;
     485                 : }
     486                 : 
     487                 : #ifdef USE_NATIVE_MENUS
     488                 : static void LoadNativeMenus(nsIDOMDocument *aDOMDoc, nsIWidget *aParentWindow)
     489                 : {
     490                 :   // Find the menubar tag (if there is more than one, we ignore all but
     491                 :   // the first).
     492                 :   nsCOMPtr<nsIDOMNodeList> menubarElements;
     493                 :   aDOMDoc->GetElementsByTagNameNS(NS_LITERAL_STRING("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"),
     494                 :                                   NS_LITERAL_STRING("menubar"),
     495                 :                                   getter_AddRefs(menubarElements));
     496                 : 
     497                 :   nsCOMPtr<nsIDOMNode> menubarNode;
     498                 :   if (menubarElements)
     499                 :     menubarElements->Item(0, getter_AddRefs(menubarNode));
     500                 :   if (!menubarNode)
     501                 :     return;
     502                 : 
     503                 :   nsCOMPtr<nsINativeMenuService> nms = do_GetService("@mozilla.org/widget/nativemenuservice;1");
     504                 :   nsCOMPtr<nsIContent> menubarContent(do_QueryInterface(menubarNode));
     505                 :   if (nms && menubarContent)
     506                 :     nms->CreateNativeMenuBar(aParentWindow, menubarContent);
     507                 : }
     508                 : #endif
     509                 : 
     510                 : void
     511               0 : nsWebShellWindow::SetPersistenceTimer(PRUint32 aDirtyFlags)
     512                 : {
     513               0 :   MutexAutoLock lock(mSPTimerLock);
     514               0 :   if (!mSPTimer) {
     515                 :     nsresult rv;
     516               0 :     mSPTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
     517               0 :     if (NS_SUCCEEDED(rv)) {
     518               0 :       NS_ADDREF_THIS(); // for the timer, which holds a reference to this window
     519                 :     }
     520                 :   }
     521               0 :   mSPTimer->InitWithFuncCallback(FirePersistenceTimer, this,
     522               0 :                                  SIZE_PERSISTENCE_TIMEOUT, nsITimer::TYPE_ONE_SHOT);
     523               0 :   PersistentAttributesDirty(aDirtyFlags);
     524               0 : }
     525                 : 
     526                 : void
     527               0 : nsWebShellWindow::FirePersistenceTimer(nsITimer *aTimer, void *aClosure)
     528                 : {
     529               0 :   nsWebShellWindow *win = static_cast<nsWebShellWindow *>(aClosure);
     530               0 :   MutexAutoLock lock(win->mSPTimerLock);
     531               0 :   win->SavePersistentAttributes();
     532               0 : }
     533                 : 
     534                 : 
     535                 : //----------------------------------------
     536                 : // nsIWebProgessListener implementation
     537                 : //----------------------------------------
     538                 : NS_IMETHODIMP
     539               0 : nsWebShellWindow::OnProgressChange(nsIWebProgress *aProgress,
     540                 :                                    nsIRequest *aRequest,
     541                 :                                    PRInt32 aCurSelfProgress,
     542                 :                                    PRInt32 aMaxSelfProgress,
     543                 :                                    PRInt32 aCurTotalProgress,
     544                 :                                    PRInt32 aMaxTotalProgress)
     545                 : {
     546               0 :   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
     547               0 :   return NS_OK;
     548                 : }
     549                 : 
     550                 : NS_IMETHODIMP
     551               0 : nsWebShellWindow::OnStateChange(nsIWebProgress *aProgress,
     552                 :                                 nsIRequest *aRequest,
     553                 :                                 PRUint32 aStateFlags,
     554                 :                                 nsresult aStatus)
     555                 : {
     556                 :   // If the notification is not about a document finishing, then just
     557                 :   // ignore it...
     558               0 :   if (!(aStateFlags & nsIWebProgressListener::STATE_STOP) || 
     559               0 :       !(aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK)) {
     560               0 :     return NS_OK;
     561                 :   }
     562                 : 
     563               0 :   if (mChromeLoaded)
     564               0 :     return NS_OK;
     565                 : 
     566                 :   // If this document notification is for a frame then ignore it...
     567               0 :   nsCOMPtr<nsIDOMWindow> eventWin;
     568               0 :   aProgress->GetDOMWindow(getter_AddRefs(eventWin));
     569               0 :   nsCOMPtr<nsPIDOMWindow> eventPWin(do_QueryInterface(eventWin));
     570               0 :   if (eventPWin) {
     571               0 :     nsPIDOMWindow *rootPWin = eventPWin->GetPrivateRoot();
     572               0 :     if (eventPWin != rootPWin)
     573               0 :       return NS_OK;
     574                 :   }
     575                 : 
     576               0 :   mChromeLoaded = true;
     577               0 :   mLockedUntilChromeLoad = false;
     578                 : 
     579                 : #ifdef USE_NATIVE_MENUS
     580                 :   ///////////////////////////////
     581                 :   // Find the Menubar DOM  and Load the menus, hooking them up to the loaded commands
     582                 :   ///////////////////////////////
     583                 :   nsCOMPtr<nsIContentViewer> cv;
     584                 :   mDocShell->GetContentViewer(getter_AddRefs(cv));
     585                 :   if (cv) {
     586                 :     nsCOMPtr<nsIDOMDocument> menubarDOMDoc(do_QueryInterface(cv->GetDocument()));
     587                 :     if (menubarDOMDoc)
     588                 :       LoadNativeMenus(menubarDOMDoc, mWindow);
     589                 :   }
     590                 : #endif // USE_NATIVE_MENUS
     591                 : 
     592               0 :   OnChromeLoaded();
     593               0 :   LoadContentAreas();
     594                 : 
     595               0 :   return NS_OK;
     596                 : }
     597                 : 
     598                 : NS_IMETHODIMP
     599               0 : nsWebShellWindow::OnLocationChange(nsIWebProgress *aProgress,
     600                 :                                    nsIRequest *aRequest,
     601                 :                                    nsIURI *aURI,
     602                 :                                    PRUint32 aFlags)
     603                 : {
     604               0 :   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
     605               0 :   return NS_OK;
     606                 : }
     607                 : 
     608                 : NS_IMETHODIMP 
     609               0 : nsWebShellWindow::OnStatusChange(nsIWebProgress* aWebProgress,
     610                 :                                  nsIRequest* aRequest,
     611                 :                                  nsresult aStatus,
     612                 :                                  const PRUnichar* aMessage)
     613                 : {
     614               0 :   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
     615               0 :   return NS_OK;
     616                 : }
     617                 : 
     618                 : NS_IMETHODIMP
     619               0 : nsWebShellWindow::OnSecurityChange(nsIWebProgress *aWebProgress,
     620                 :                                    nsIRequest *aRequest,
     621                 :                                    PRUint32 state)
     622                 : {
     623               0 :   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
     624               0 :   return NS_OK;
     625                 : }
     626                 : 
     627                 : 
     628                 : //----------------------------------------
     629                 : 
     630                 : // if the main document URL specified URLs for any content areas, start them loading
     631               0 : void nsWebShellWindow::LoadContentAreas() {
     632                 : 
     633               0 :   nsAutoString searchSpec;
     634                 : 
     635                 :   // fetch the chrome document URL
     636               0 :   nsCOMPtr<nsIContentViewer> contentViewer;
     637                 :   // yes, it's possible for the docshell to be null even this early
     638                 :   // see bug 57514.
     639               0 :   if (mDocShell)
     640               0 :     mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
     641               0 :   if (contentViewer) {
     642               0 :     nsIDocument* doc = contentViewer->GetDocument();
     643               0 :     if (doc) {
     644               0 :       nsIURI* mainURL = doc->GetDocumentURI();
     645                 : 
     646               0 :       nsCOMPtr<nsIURL> url = do_QueryInterface(mainURL);
     647               0 :       if (url) {
     648               0 :         nsCAutoString search;
     649               0 :         url->GetQuery(search);
     650                 : 
     651               0 :         AppendUTF8toUTF16(search, searchSpec);
     652                 :       }
     653                 :     }
     654                 :   }
     655                 : 
     656                 :   // content URLs are specified in the search part of the URL
     657                 :   // as <contentareaID>=<escapedURL>[;(repeat)]
     658               0 :   if (!searchSpec.IsEmpty()) {
     659                 :     PRInt32     begPos,
     660                 :                 eqPos,
     661                 :                 endPos;
     662               0 :     nsString    contentAreaID,
     663               0 :                 contentURL;
     664                 :     char        *urlChar;
     665                 :     nsresult rv;
     666               0 :     for (endPos = 0; endPos < (PRInt32)searchSpec.Length(); ) {
     667                 :       // extract contentAreaID and URL substrings
     668               0 :       begPos = endPos;
     669               0 :       eqPos = searchSpec.FindChar('=', begPos);
     670               0 :       if (eqPos < 0)
     671               0 :         break;
     672                 : 
     673               0 :       endPos = searchSpec.FindChar(';', eqPos);
     674               0 :       if (endPos < 0)
     675               0 :         endPos = searchSpec.Length();
     676               0 :       searchSpec.Mid(contentAreaID, begPos, eqPos-begPos);
     677               0 :       searchSpec.Mid(contentURL, eqPos+1, endPos-eqPos-1);
     678               0 :       endPos++;
     679                 : 
     680                 :       // see if we have a docshell with a matching contentAreaID
     681               0 :       nsCOMPtr<nsIDocShellTreeItem> content;
     682               0 :       rv = GetContentShellById(contentAreaID.get(), getter_AddRefs(content));
     683               0 :       if (NS_SUCCEEDED(rv) && content) {
     684               0 :         nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(content));
     685               0 :         if (webNav) {
     686               0 :           urlChar = ToNewCString(contentURL);
     687               0 :           if (urlChar) {
     688               0 :             nsUnescape(urlChar);
     689               0 :             contentURL.AssignWithConversion(urlChar);
     690               0 :             webNav->LoadURI(contentURL.get(),
     691                 :                           nsIWebNavigation::LOAD_FLAGS_NONE,
     692                 :                           nsnull,
     693                 :                           nsnull,
     694               0 :                           nsnull);
     695               0 :             nsMemory::Free(urlChar);
     696                 :           }
     697                 :         }
     698                 :       }
     699                 :     }
     700                 :   }
     701               0 : }
     702                 : 
     703                 : /**
     704                 :  * ExecuteCloseHandler - Run the close handler, if any.
     705                 :  * @return true iff we found a close handler to run.
     706                 :  */
     707               0 : bool nsWebShellWindow::ExecuteCloseHandler()
     708                 : {
     709                 :   /* If the event handler closes this window -- a likely scenario --
     710                 :      things get deleted out of order without this death grip.
     711                 :      (The problem may be the death grip in nsWindow::windowProc,
     712                 :      which forces this window's widget to remain alive longer
     713                 :      than it otherwise would.) */
     714               0 :   nsCOMPtr<nsIXULWindow> kungFuDeathGrip(this);
     715                 : 
     716               0 :   nsCOMPtr<nsPIDOMWindow> window(do_GetInterface(mDocShell));
     717               0 :   nsCOMPtr<nsIDOMEventTarget> eventTarget = do_QueryInterface(window);
     718                 : 
     719               0 :   if (eventTarget) {
     720               0 :     nsCOMPtr<nsIContentViewer> contentViewer;
     721               0 :     mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
     722               0 :     if (contentViewer) {
     723               0 :       nsRefPtr<nsPresContext> presContext;
     724               0 :       contentViewer->GetPresContext(getter_AddRefs(presContext));
     725                 : 
     726               0 :       nsEventStatus status = nsEventStatus_eIgnore;
     727                 :       nsMouseEvent event(true, NS_XUL_CLOSE, nsnull,
     728               0 :                          nsMouseEvent::eReal);
     729                 : 
     730                 :       nsresult rv =
     731               0 :         eventTarget->DispatchDOMEvent(&event, nsnull, presContext, &status);
     732               0 :       if (NS_SUCCEEDED(rv) && status == nsEventStatus_eConsumeNoDefault)
     733               0 :         return true;
     734                 :       // else fall through and return false
     735                 :     }
     736                 :   }
     737                 : 
     738               0 :   return false;
     739                 : } // ExecuteCloseHandler
     740                 : 
     741               0 : void nsWebShellWindow::ConstrainToOpenerScreen(PRInt32* aX, PRInt32* aY)
     742                 : {
     743               0 :   if (mOpenerScreenRect.IsEmpty()) {
     744               0 :     *aX = *aY = 0;
     745               0 :     return;
     746                 :   }
     747                 : 
     748                 :   PRInt32 left, top, width, height;
     749                 :   // Constrain initial positions to the same screen as opener
     750               0 :   nsCOMPtr<nsIScreenManager> screenmgr = do_GetService("@mozilla.org/gfx/screenmanager;1");
     751               0 :   if (screenmgr) {
     752               0 :     nsCOMPtr<nsIScreen> screen;
     753               0 :     screenmgr->ScreenForRect(mOpenerScreenRect.x, mOpenerScreenRect.y,
     754                 :                              mOpenerScreenRect.width, mOpenerScreenRect.height,
     755               0 :                              getter_AddRefs(screen));
     756               0 :     if (screen) {
     757               0 :       screen->GetAvailRect(&left, &top, &width, &height);
     758               0 :       if (*aX < left || *aX > left + width) {
     759               0 :         *aX = left;
     760                 :       }
     761               0 :       if (*aY < top || *aY > top + height) {
     762               0 :         *aY = top;
     763                 :       }
     764                 :     }
     765                 :   }
     766                 : }
     767                 : 
     768                 : // nsIBaseWindow
     769               0 : NS_IMETHODIMP nsWebShellWindow::Destroy()
     770                 : {
     771                 :   nsresult rv;
     772               0 :   nsCOMPtr<nsIWebProgress> webProgress(do_GetInterface(mDocShell, &rv));
     773               0 :   if (webProgress) {
     774               0 :     webProgress->RemoveProgressListener(this);
     775                 :   }
     776                 : 
     777               0 :   nsCOMPtr<nsIXULWindow> kungFuDeathGrip(this);
     778                 :   {
     779               0 :     MutexAutoLock lock(mSPTimerLock);
     780               0 :     if (mSPTimer) {
     781               0 :       mSPTimer->Cancel();
     782               0 :       SavePersistentAttributes();
     783               0 :       mSPTimer = nsnull;
     784               0 :       NS_RELEASE_THIS(); // the timer held a reference to us
     785                 :     }
     786                 :   }
     787               0 :   return nsXULWindow::Destroy();
     788                 : }

Generated by: LCOV version 1.7