LCOV - code coverage report
Current view: top level - xpfe/appshell - nsAppShellWindowEnumerator.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 80 246 32.5 %
Date: 2017-07-14 16:53:18 Functions: 16 50 32.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13