LCOV - code coverage report
Current view: directory - xpfe/appshell/src - nsAppShellWindowEnumerator.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 238 34 14.3 %
Date: 2012-06-02 Functions: 51 13 25.5 %

       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.org 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) 2001
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : #include "nsAppShellWindowEnumerator.h"
      39                 : 
      40                 : #include "nsIContentViewer.h"
      41                 : #include "nsIDocShell.h"
      42                 : #include "nsIDocument.h"
      43                 : #include "nsIDOMDocument.h"
      44                 : #include "nsIDOMElement.h"
      45                 : #include "nsIDOMWindow.h"
      46                 : #include "nsIFactory.h"
      47                 : #include "nsIInterfaceRequestor.h"
      48                 : #include "nsIInterfaceRequestorUtils.h"
      49                 : #include "nsIXULWindow.h"
      50                 : 
      51                 : #include "nsWindowMediator.h"
      52                 : 
      53                 : //
      54                 : // static helper functions
      55                 : //
      56                 : 
      57                 : static nsresult GetDOMWindow(nsIXULWindow* inWindow,
      58                 :                              nsCOMPtr<nsIDOMWindow> &outDOMWindow);
      59                 : static nsCOMPtr<nsIDOMNode> GetDOMNodeFromDocShell(nsIDocShell *aShell);
      60                 : static void GetAttribute(nsIXULWindow *inWindow, const nsAString &inAttribute,
      61                 :                          nsAString &outValue);
      62                 : static void GetWindowType(nsIXULWindow* inWindow, nsString &outType);
      63                 : 
      64                 : // fetch the nsIDOMWindow(Internal) from a XUL Window
      65               0 : nsresult GetDOMWindow(nsIXULWindow *aWindow, nsCOMPtr<nsIDOMWindow> &aDOMWindow)
      66                 : {
      67               0 :   nsCOMPtr<nsIDocShell> docShell;
      68                 : 
      69               0 :   aWindow->GetDocShell(getter_AddRefs(docShell));
      70               0 :   aDOMWindow = do_GetInterface(docShell);
      71               0 :   return aDOMWindow ? NS_OK : NS_ERROR_FAILURE;
      72                 : }
      73                 : 
      74               0 : nsCOMPtr<nsIDOMNode> GetDOMNodeFromDocShell(nsIDocShell *aShell)
      75                 : {
      76               0 :   nsCOMPtr<nsIDOMNode> node;
      77                 : 
      78               0 :   nsCOMPtr<nsIContentViewer> cv;
      79               0 :   aShell->GetContentViewer(getter_AddRefs(cv));
      80               0 :   if (cv) {
      81               0 :     nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(cv->GetDocument()));
      82               0 :     if (domdoc) {
      83               0 :       nsCOMPtr<nsIDOMElement> element;
      84               0 :       domdoc->GetDocumentElement(getter_AddRefs(element));
      85               0 :       if (element)
      86               0 :         node = element;
      87                 :     }
      88                 :   }
      89                 : 
      90                 :   return node;
      91                 : }
      92                 : 
      93                 : // generic "retrieve the value of a XUL attribute" function
      94               0 : void GetAttribute(nsIXULWindow *inWindow, const nsAString &inAttribute,
      95                 :                   nsAString &outValue)
      96                 : {
      97               0 :   nsCOMPtr<nsIDocShell> shell;
      98               0 :   if (inWindow && NS_SUCCEEDED(inWindow->GetDocShell(getter_AddRefs(shell)))) {
      99               0 :     nsCOMPtr<nsIDOMNode> node(GetDOMNodeFromDocShell(shell));
     100               0 :     if (node) {
     101               0 :       nsCOMPtr<nsIDOMElement> webshellElement(do_QueryInterface(node));
     102               0 :       if (webshellElement)
     103               0 :         webshellElement->GetAttribute(inAttribute, outValue);
     104                 :     }
     105                 :   }
     106               0 : }
     107                 : 
     108                 : // retrieve the window type, stored as the value of a particular
     109                 : // attribute in its XUL window tag
     110               0 : void GetWindowType(nsIXULWindow* aWindow, nsString &outType)
     111                 : {
     112               0 :   GetAttribute(aWindow, NS_LITERAL_STRING("windowtype"), outType);
     113               0 : }
     114                 : 
     115                 : //
     116                 : // nsWindowInfo
     117                 : //
     118                 : 
     119               0 : nsWindowInfo::nsWindowInfo(nsIXULWindow* inWindow, PRInt32 inTimeStamp) :
     120               0 :   mWindow(inWindow),mTimeStamp(inTimeStamp),mZLevel(nsIXULWindow::normalZ)
     121                 : {
     122               0 :   ReferenceSelf(true, true);
     123               0 : }
     124                 : 
     125               0 : nsWindowInfo::~nsWindowInfo()
     126                 : {
     127               0 : }
     128                 : 
     129                 : // return true if the window described by this WindowInfo has a type
     130                 : // equal to the given type
     131               0 : bool nsWindowInfo::TypeEquals(const nsAString &aType)
     132                 : { 
     133               0 :   nsAutoString rtnString;
     134               0 :   GetWindowType(mWindow, rtnString);
     135               0 :   return rtnString == aType;
     136                 : }
     137                 : 
     138                 : // insert the struct into their two linked lists, in position after the
     139                 : // given (independent) method arguments
     140               0 : void nsWindowInfo::InsertAfter(nsWindowInfo *inOlder , nsWindowInfo *inHigher)
     141                 : {
     142               0 :   if (inOlder) {
     143               0 :     mOlder = inOlder;
     144               0 :     mYounger = inOlder->mYounger;
     145               0 :     mOlder->mYounger = this;
     146               0 :     if (mOlder->mOlder == mOlder)
     147               0 :       mOlder->mOlder = this;
     148               0 :     mYounger->mOlder = this;
     149               0 :     if (mYounger->mYounger == mYounger)
     150               0 :       mYounger->mYounger = this;
     151                 :   }
     152               0 :   if (inHigher) {
     153               0 :     mHigher = inHigher;
     154               0 :     mLower = inHigher->mLower;
     155               0 :     mHigher->mLower = this;
     156               0 :     if (mHigher->mHigher == mHigher)
     157               0 :       mHigher->mHigher = this;
     158               0 :     mLower->mHigher = this;
     159               0 :     if (mLower->mLower == mLower)
     160               0 :       mLower->mLower = this;
     161                 :   }
     162               0 : }
     163                 : 
     164                 : // remove the struct from its linked lists
     165               0 : void nsWindowInfo::Unlink(bool inAge, bool inZ)
     166                 : {
     167               0 :   if (inAge) {
     168               0 :     mOlder->mYounger = mYounger;
     169               0 :     mYounger->mOlder = mOlder;
     170                 :   }
     171               0 :   if (inZ) {
     172               0 :     mLower->mHigher = mHigher;
     173               0 :     mHigher->mLower = mLower;
     174                 :   }
     175               0 :   ReferenceSelf(inAge, inZ);
     176               0 : }
     177                 : 
     178                 : // initialize the struct to be a valid linked list of one element
     179               0 : void nsWindowInfo::ReferenceSelf(bool inAge, bool inZ)
     180                 : {
     181               0 :   if (inAge) {
     182               0 :     mYounger = this;
     183               0 :     mOlder = this;
     184                 :   }
     185               0 :   if (inZ) {
     186               0 :     mLower = this;
     187               0 :     mHigher = this;
     188                 :   }
     189               0 : }
     190                 : 
     191                 : //
     192                 : // nsAppShellWindowEnumerator
     193                 : //
     194                 : 
     195            7703 : NS_IMPL_ISUPPORTS1(nsAppShellWindowEnumerator, nsISimpleEnumerator)
     196                 : 
     197             837 : nsAppShellWindowEnumerator::nsAppShellWindowEnumerator(
     198                 :     const PRUnichar* aTypeString,
     199                 :     nsWindowMediator& aMediator) :
     200             837 :       mWindowMediator(&aMediator), mType(aTypeString), mCurrentPosition(nsnull)
     201                 : {
     202             837 :   mWindowMediator->AddEnumerator(this);
     203             837 :   NS_ADDREF(mWindowMediator);
     204             837 : }
     205                 : 
     206            1674 : nsAppShellWindowEnumerator::~nsAppShellWindowEnumerator()
     207                 : {
     208             837 :   mWindowMediator->RemoveEnumerator(this);
     209             837 :   NS_RELEASE(mWindowMediator);
     210            1674 : }
     211                 : 
     212                 : // after mCurrentPosition has been initialized to point to the beginning
     213                 : // of the appropriate list, adjust it if necessary
     214             837 : void nsAppShellWindowEnumerator::AdjustInitialPosition()
     215                 : {
     216             837 :   if (!mType.IsEmpty() && mCurrentPosition && !mCurrentPosition->TypeEquals(mType))
     217               0 :     mCurrentPosition = FindNext();
     218             837 : }
     219                 : 
     220             520 : NS_IMETHODIMP nsAppShellWindowEnumerator::HasMoreElements(bool *retval)
     221                 : {
     222             520 :   if (!retval)
     223               0 :     return NS_ERROR_INVALID_ARG;
     224                 : 
     225             520 :   *retval = mCurrentPosition ? true : false;
     226             520 :   return NS_OK;
     227                 : }
     228                 : 
     229                 : // if a window is being removed adjust the iterator's current position
     230               0 : void nsAppShellWindowEnumerator::WindowRemoved(nsWindowInfo *inInfo)
     231                 : {
     232               0 :   if (mCurrentPosition == inInfo)
     233               0 :     mCurrentPosition = FindNext();
     234               0 : }
     235                 : 
     236                 : //
     237                 : // nsASDOMWindowEnumerator
     238                 : //
     239                 : 
     240             837 : nsASDOMWindowEnumerator::nsASDOMWindowEnumerator(
     241                 :     const PRUnichar* aTypeString,
     242                 :     nsWindowMediator& aMediator) :
     243             837 :       nsAppShellWindowEnumerator(aTypeString, aMediator)
     244                 : {
     245             837 : }
     246                 : 
     247             837 : nsASDOMWindowEnumerator::~nsASDOMWindowEnumerator()
     248                 : {
     249            1674 : }
     250                 : 
     251             317 : NS_IMETHODIMP nsASDOMWindowEnumerator::GetNext(nsISupports **retval)
     252                 : {
     253             317 :   if (!retval)
     254               0 :     return NS_ERROR_INVALID_ARG;
     255                 : 
     256             317 :   *retval = nsnull;
     257             317 :   if (mCurrentPosition) {
     258               0 :     nsCOMPtr<nsIDOMWindow> domWindow;
     259               0 :     GetDOMWindow(mCurrentPosition->mWindow, domWindow);
     260               0 :     CallQueryInterface(domWindow, retval);
     261               0 :     mCurrentPosition = FindNext();
     262                 :   }
     263             317 :   return NS_OK;
     264                 : }
     265                 : 
     266                 : //
     267                 : // nsASXULWindowEnumerator
     268                 : //
     269                 : 
     270               0 : nsASXULWindowEnumerator::nsASXULWindowEnumerator(
     271                 :     const PRUnichar* aTypeString,
     272                 :     nsWindowMediator& aMediator) :
     273               0 :       nsAppShellWindowEnumerator(aTypeString, aMediator)
     274                 : {
     275               0 : }
     276                 : 
     277               0 : nsASXULWindowEnumerator::~nsASXULWindowEnumerator()
     278                 : {
     279               0 : }
     280                 : 
     281               0 : NS_IMETHODIMP nsASXULWindowEnumerator::GetNext(nsISupports **retval)
     282                 : {
     283               0 :   if (!retval)
     284               0 :     return NS_ERROR_INVALID_ARG;
     285                 : 
     286               0 :   *retval = nsnull;
     287               0 :   if (mCurrentPosition) {
     288               0 :     CallQueryInterface(mCurrentPosition->mWindow, retval);
     289               0 :     mCurrentPosition = FindNext();
     290                 :   }
     291               0 :   return NS_OK;
     292                 : }
     293                 : 
     294                 : //
     295                 : // nsASDOMWindowEarlyToLateEnumerator
     296                 : //
     297                 : 
     298             837 : nsASDOMWindowEarlyToLateEnumerator::nsASDOMWindowEarlyToLateEnumerator(
     299                 :     const PRUnichar *aTypeString,
     300                 :     nsWindowMediator &aMediator) :
     301             837 :       nsASDOMWindowEnumerator(aTypeString, aMediator)
     302                 : {
     303             837 :   mCurrentPosition = aMediator.mOldestWindow;
     304             837 :   AdjustInitialPosition();
     305             837 : }
     306                 : 
     307            1674 : nsASDOMWindowEarlyToLateEnumerator::~nsASDOMWindowEarlyToLateEnumerator()
     308                 : {
     309            3348 : }
     310                 : 
     311               0 : nsWindowInfo *nsASDOMWindowEarlyToLateEnumerator::FindNext()
     312                 : {
     313                 :   nsWindowInfo *info,
     314                 :                *listEnd;
     315               0 :   bool          allWindows = mType.IsEmpty();
     316                 : 
     317                 :   // see nsXULWindowEarlyToLateEnumerator::FindNext
     318               0 :   if (!mCurrentPosition)
     319               0 :     return nsnull;
     320                 : 
     321               0 :   info = mCurrentPosition->mYounger;
     322               0 :   listEnd = mWindowMediator->mOldestWindow;
     323                 : 
     324               0 :   while (info != listEnd) {
     325               0 :     if (allWindows || info->TypeEquals(mType))
     326               0 :       return info;
     327               0 :     info = info->mYounger;
     328                 :   }
     329                 : 
     330               0 :   return nsnull;
     331                 : }
     332                 : 
     333                 : //
     334                 : // nsASXULWindowEarlyToLateEnumerator
     335                 : //
     336                 : 
     337               0 : nsASXULWindowEarlyToLateEnumerator::nsASXULWindowEarlyToLateEnumerator(
     338                 :     const PRUnichar *aTypeString,
     339                 :     nsWindowMediator &aMediator) :
     340               0 :       nsASXULWindowEnumerator(aTypeString, aMediator)
     341                 : {
     342               0 :   mCurrentPosition = aMediator.mOldestWindow;
     343               0 :   AdjustInitialPosition();
     344               0 : }
     345                 : 
     346               0 : nsASXULWindowEarlyToLateEnumerator::~nsASXULWindowEarlyToLateEnumerator()
     347                 : {
     348               0 : }
     349                 : 
     350               0 : nsWindowInfo *nsASXULWindowEarlyToLateEnumerator::FindNext()
     351                 : {
     352                 :   nsWindowInfo *info,
     353                 :                *listEnd;
     354               0 :   bool          allWindows = mType.IsEmpty();
     355                 : 
     356                 :   /* mCurrentPosition null is assumed to mean that the enumerator has run
     357                 :      its course and is now basically useless. It could also be interpreted
     358                 :      to mean that it was created at a time when there were no windows. In
     359                 :      that case it would probably be more appropriate to check to see whether
     360                 :      windows have subsequently been added. But it's not guaranteed that we'll
     361                 :      pick up newly added windows anyway (if they occurred previous to our
     362                 :      current position) so we just don't worry about that. */
     363               0 :   if (!mCurrentPosition)
     364               0 :     return nsnull;
     365                 : 
     366               0 :   info = mCurrentPosition->mYounger;
     367               0 :   listEnd = mWindowMediator->mOldestWindow;
     368                 : 
     369               0 :   while (info != listEnd) {
     370               0 :     if (allWindows || info->TypeEquals(mType))
     371               0 :       return info;
     372               0 :     info = info->mYounger;
     373                 :   }
     374                 : 
     375               0 :   return nsnull;
     376                 : }
     377                 : 
     378                 : //
     379                 : // nsASDOMWindowFrontToBackEnumerator
     380                 : //
     381                 : 
     382               0 : nsASDOMWindowFrontToBackEnumerator::nsASDOMWindowFrontToBackEnumerator(
     383                 :     const PRUnichar *aTypeString,
     384                 :     nsWindowMediator &aMediator) :
     385               0 :       nsASDOMWindowEnumerator(aTypeString, aMediator)
     386                 : {
     387               0 :   mCurrentPosition = aMediator.mTopmostWindow;
     388               0 :   AdjustInitialPosition();
     389               0 : }
     390                 : 
     391               0 : nsASDOMWindowFrontToBackEnumerator::~nsASDOMWindowFrontToBackEnumerator()
     392                 : {
     393               0 : }
     394                 : 
     395               0 : nsWindowInfo *nsASDOMWindowFrontToBackEnumerator::FindNext()
     396                 : {
     397                 :   nsWindowInfo *info,
     398                 :                *listEnd;
     399               0 :   bool          allWindows = mType.IsEmpty();
     400                 : 
     401                 :   // see nsXULWindowEarlyToLateEnumerator::FindNext
     402               0 :   if (!mCurrentPosition)
     403               0 :     return nsnull;
     404                 : 
     405               0 :   info = mCurrentPosition->mLower;
     406               0 :   listEnd = mWindowMediator->mTopmostWindow;
     407                 : 
     408               0 :   while (info != listEnd) {
     409               0 :     if (allWindows || info->TypeEquals(mType))
     410               0 :       return info;
     411               0 :     info = info->mLower;
     412                 :   }
     413                 : 
     414               0 :   return nsnull;
     415                 : }
     416                 : 
     417                 : //
     418                 : // nsASXULWindowFrontToBackEnumerator
     419                 : //
     420                 : 
     421               0 : nsASXULWindowFrontToBackEnumerator::nsASXULWindowFrontToBackEnumerator(
     422                 :     const PRUnichar *aTypeString,
     423                 :     nsWindowMediator &aMediator) :
     424               0 :       nsASXULWindowEnumerator(aTypeString, aMediator)
     425                 : {
     426               0 :   mCurrentPosition = aMediator.mTopmostWindow;
     427               0 :   AdjustInitialPosition();
     428               0 : }
     429                 : 
     430               0 : nsASXULWindowFrontToBackEnumerator::~nsASXULWindowFrontToBackEnumerator()
     431                 : {
     432               0 : }
     433                 : 
     434               0 : nsWindowInfo *nsASXULWindowFrontToBackEnumerator::FindNext()
     435                 : {
     436                 :   nsWindowInfo *info,
     437                 :                *listEnd;
     438               0 :   bool          allWindows = mType.IsEmpty();
     439                 : 
     440                 :   // see nsXULWindowEarlyToLateEnumerator::FindNext
     441               0 :   if (!mCurrentPosition)
     442               0 :     return nsnull;
     443                 : 
     444               0 :   info = mCurrentPosition->mLower;
     445               0 :   listEnd = mWindowMediator->mTopmostWindow;
     446                 : 
     447               0 :   while (info != listEnd) {
     448               0 :     if (allWindows || info->TypeEquals(mType))
     449               0 :       return info;
     450               0 :     info = info->mLower;
     451                 :   }
     452                 : 
     453               0 :   return nsnull;
     454                 : }
     455                 : 
     456                 : //
     457                 : // nsASDOMWindowBackToFrontEnumerator
     458                 : //
     459                 : 
     460               0 : nsASDOMWindowBackToFrontEnumerator::nsASDOMWindowBackToFrontEnumerator(
     461                 :     const PRUnichar *aTypeString,
     462                 :     nsWindowMediator &aMediator) :
     463               0 :   nsASDOMWindowEnumerator(aTypeString, aMediator)
     464                 : {
     465                 :   mCurrentPosition = aMediator.mTopmostWindow ?
     466               0 :                      aMediator.mTopmostWindow->mHigher : nsnull;
     467               0 :   AdjustInitialPosition();
     468               0 : }
     469                 : 
     470               0 : nsASDOMWindowBackToFrontEnumerator::~nsASDOMWindowBackToFrontEnumerator()
     471                 : {
     472               0 : }
     473                 : 
     474               0 : nsWindowInfo *nsASDOMWindowBackToFrontEnumerator::FindNext()
     475                 : {
     476                 :   nsWindowInfo *info,
     477                 :                *listEnd;
     478               0 :   bool          allWindows = mType.IsEmpty();
     479                 : 
     480                 :   // see nsXULWindowEarlyToLateEnumerator::FindNext
     481               0 :   if (!mCurrentPosition)
     482               0 :     return nsnull;
     483                 : 
     484               0 :   info = mCurrentPosition->mHigher;
     485               0 :   listEnd = mWindowMediator->mTopmostWindow;
     486               0 :   if (listEnd)
     487               0 :     listEnd = listEnd->mHigher;
     488                 : 
     489               0 :   while (info != listEnd) {
     490               0 :     if (allWindows || info->TypeEquals(mType))
     491               0 :       return info;
     492               0 :     info = info->mHigher;
     493                 :   }
     494                 : 
     495               0 :   return nsnull;
     496                 : }
     497                 : 
     498                 : //
     499                 : // nsASXULWindowBackToFrontEnumerator
     500                 : //
     501                 : 
     502               0 : nsASXULWindowBackToFrontEnumerator::nsASXULWindowBackToFrontEnumerator(
     503                 :     const PRUnichar *aTypeString,
     504                 :     nsWindowMediator &aMediator) :
     505               0 :       nsASXULWindowEnumerator(aTypeString, aMediator)
     506                 : {
     507                 :   mCurrentPosition = aMediator.mTopmostWindow ?
     508               0 :                      aMediator.mTopmostWindow->mHigher : nsnull;
     509               0 :   AdjustInitialPosition();
     510               0 : }
     511                 : 
     512               0 : nsASXULWindowBackToFrontEnumerator::~nsASXULWindowBackToFrontEnumerator()
     513                 : {
     514               0 : }
     515                 : 
     516               0 : nsWindowInfo *nsASXULWindowBackToFrontEnumerator::FindNext()
     517                 : {
     518                 :   nsWindowInfo *info,
     519                 :                *listEnd;
     520               0 :   bool          allWindows = mType.IsEmpty();
     521                 : 
     522                 :   // see nsXULWindowEarlyToLateEnumerator::FindNext
     523               0 :   if (!mCurrentPosition)
     524               0 :     return nsnull;
     525                 : 
     526               0 :   info = mCurrentPosition->mHigher;
     527               0 :   listEnd = mWindowMediator->mTopmostWindow;
     528               0 :   if (listEnd)
     529               0 :     listEnd = listEnd->mHigher;
     530                 : 
     531               0 :   while (info != listEnd) {
     532               0 :     if (allWindows || info->TypeEquals(mType))
     533               0 :       return info;
     534               0 :     info = info->mHigher;
     535                 :   }
     536                 : 
     537               0 :   return nsnull;
     538                 : }

Generated by: LCOV version 1.7