xpfe/appshell/src/nsAppShellWindowEnumerator.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     6 #include "nsAppShellWindowEnumerator.h"
     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"
    19 #include "nsWindowMediator.h"
    21 //
    22 // static helper functions
    23 //
    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);
    30 nsCOMPtr<nsIDOMNode> GetDOMNodeFromDocShell(nsIDocShell *aShell)
    31 {
    32   nsCOMPtr<nsIDOMNode> node;
    34   nsCOMPtr<nsIContentViewer> cv;
    35   aShell->GetContentViewer(getter_AddRefs(cv));
    36   if (cv) {
    37     nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(cv->GetDocument()));
    38     if (domdoc) {
    39       nsCOMPtr<nsIDOMElement> element;
    40       domdoc->GetDocumentElement(getter_AddRefs(element));
    41       if (element)
    42         node = element;
    43     }
    44   }
    46   return node;
    47 }
    49 // generic "retrieve the value of a XUL attribute" function
    50 void GetAttribute(nsIXULWindow *inWindow, const nsAString &inAttribute,
    51                   nsAString &outValue)
    52 {
    53   nsCOMPtr<nsIDocShell> shell;
    54   if (inWindow && NS_SUCCEEDED(inWindow->GetDocShell(getter_AddRefs(shell)))) {
    55     nsCOMPtr<nsIDOMNode> node(GetDOMNodeFromDocShell(shell));
    56     if (node) {
    57       nsCOMPtr<nsIDOMElement> webshellElement(do_QueryInterface(node));
    58       if (webshellElement)
    59         webshellElement->GetAttribute(inAttribute, outValue);
    60     }
    61   }
    62 }
    64 // retrieve the window type, stored as the value of a particular
    65 // attribute in its XUL window tag
    66 void GetWindowType(nsIXULWindow* aWindow, nsString &outType)
    67 {
    68   GetAttribute(aWindow, NS_LITERAL_STRING("windowtype"), outType);
    69 }
    71 //
    72 // nsWindowInfo
    73 //
    75 nsWindowInfo::nsWindowInfo(nsIXULWindow* inWindow, int32_t inTimeStamp) :
    76   mWindow(inWindow),mTimeStamp(inTimeStamp),mZLevel(nsIXULWindow::normalZ)
    77 {
    78   ReferenceSelf(true, true);
    79 }
    81 nsWindowInfo::~nsWindowInfo()
    82 {
    83 }
    85 // return true if the window described by this WindowInfo has a type
    86 // equal to the given type
    87 bool nsWindowInfo::TypeEquals(const nsAString &aType)
    88 { 
    89   nsAutoString rtnString;
    90   GetWindowType(mWindow, rtnString);
    91   return rtnString == aType;
    92 }
    94 // insert the struct into their two linked lists, in position after the
    95 // given (independent) method arguments
    96 void nsWindowInfo::InsertAfter(nsWindowInfo *inOlder , nsWindowInfo *inHigher)
    97 {
    98   if (inOlder) {
    99     mOlder = inOlder;
   100     mYounger = inOlder->mYounger;
   101     mOlder->mYounger = this;
   102     if (mOlder->mOlder == mOlder)
   103       mOlder->mOlder = this;
   104     mYounger->mOlder = this;
   105     if (mYounger->mYounger == mYounger)
   106       mYounger->mYounger = this;
   107   }
   108   if (inHigher) {
   109     mHigher = inHigher;
   110     mLower = inHigher->mLower;
   111     mHigher->mLower = this;
   112     if (mHigher->mHigher == mHigher)
   113       mHigher->mHigher = this;
   114     mLower->mHigher = this;
   115     if (mLower->mLower == mLower)
   116       mLower->mLower = this;
   117   }
   118 }
   120 // remove the struct from its linked lists
   121 void nsWindowInfo::Unlink(bool inAge, bool inZ)
   122 {
   123   if (inAge) {
   124     mOlder->mYounger = mYounger;
   125     mYounger->mOlder = mOlder;
   126   }
   127   if (inZ) {
   128     mLower->mHigher = mHigher;
   129     mHigher->mLower = mLower;
   130   }
   131   ReferenceSelf(inAge, inZ);
   132 }
   134 // initialize the struct to be a valid linked list of one element
   135 void nsWindowInfo::ReferenceSelf(bool inAge, bool inZ)
   136 {
   137   if (inAge) {
   138     mYounger = this;
   139     mOlder = this;
   140   }
   141   if (inZ) {
   142     mLower = this;
   143     mHigher = this;
   144   }
   145 }
   147 //
   148 // nsAppShellWindowEnumerator
   149 //
   151 NS_IMPL_ISUPPORTS(nsAppShellWindowEnumerator, nsISimpleEnumerator)
   153 nsAppShellWindowEnumerator::nsAppShellWindowEnumerator(
   154     const char16_t* aTypeString,
   155     nsWindowMediator& aMediator) :
   156       mWindowMediator(&aMediator), mType(aTypeString), mCurrentPosition(nullptr)
   157 {
   158   mWindowMediator->AddEnumerator(this);
   159   NS_ADDREF(mWindowMediator);
   160 }
   162 nsAppShellWindowEnumerator::~nsAppShellWindowEnumerator()
   163 {
   164   mWindowMediator->RemoveEnumerator(this);
   165   NS_RELEASE(mWindowMediator);
   166 }
   168 // after mCurrentPosition has been initialized to point to the beginning
   169 // of the appropriate list, adjust it if necessary
   170 void nsAppShellWindowEnumerator::AdjustInitialPosition()
   171 {
   172   if (!mType.IsEmpty() && mCurrentPosition && !mCurrentPosition->TypeEquals(mType))
   173     mCurrentPosition = FindNext();
   174 }
   176 NS_IMETHODIMP nsAppShellWindowEnumerator::HasMoreElements(bool *retval)
   177 {
   178   if (!retval)
   179     return NS_ERROR_INVALID_ARG;
   181   *retval = mCurrentPosition ? true : false;
   182   return NS_OK;
   183 }
   185 // if a window is being removed adjust the iterator's current position
   186 void nsAppShellWindowEnumerator::WindowRemoved(nsWindowInfo *inInfo)
   187 {
   188   if (mCurrentPosition == inInfo)
   189     mCurrentPosition = FindNext();
   190 }
   192 //
   193 // nsASDOMWindowEnumerator
   194 //
   196 nsASDOMWindowEnumerator::nsASDOMWindowEnumerator(
   197     const char16_t* aTypeString,
   198     nsWindowMediator& aMediator) :
   199       nsAppShellWindowEnumerator(aTypeString, aMediator)
   200 {
   201 }
   203 nsASDOMWindowEnumerator::~nsASDOMWindowEnumerator()
   204 {
   205 }
   207 NS_IMETHODIMP nsASDOMWindowEnumerator::GetNext(nsISupports **retval)
   208 {
   209   if (!retval)
   210     return NS_ERROR_INVALID_ARG;
   212   *retval = nullptr;
   213   while (mCurrentPosition) {
   214     nsCOMPtr<nsIDOMWindow> domWindow;
   215     nsWindowMediator::GetDOMWindow(mCurrentPosition->mWindow, domWindow);
   216     mCurrentPosition = FindNext();
   217     if (domWindow)
   218       return CallQueryInterface(domWindow, retval);
   219   }
   220   return NS_OK;
   221 }
   223 //
   224 // nsASXULWindowEnumerator
   225 //
   227 nsASXULWindowEnumerator::nsASXULWindowEnumerator(
   228     const char16_t* aTypeString,
   229     nsWindowMediator& aMediator) :
   230       nsAppShellWindowEnumerator(aTypeString, aMediator)
   231 {
   232 }
   234 nsASXULWindowEnumerator::~nsASXULWindowEnumerator()
   235 {
   236 }
   238 NS_IMETHODIMP nsASXULWindowEnumerator::GetNext(nsISupports **retval)
   239 {
   240   if (!retval)
   241     return NS_ERROR_INVALID_ARG;
   243   *retval = nullptr;
   244   if (mCurrentPosition) {
   245     CallQueryInterface(mCurrentPosition->mWindow, retval);
   246     mCurrentPosition = FindNext();
   247   }
   248   return NS_OK;
   249 }
   251 //
   252 // nsASDOMWindowEarlyToLateEnumerator
   253 //
   255 nsASDOMWindowEarlyToLateEnumerator::nsASDOMWindowEarlyToLateEnumerator(
   256     const char16_t *aTypeString,
   257     nsWindowMediator &aMediator) :
   258       nsASDOMWindowEnumerator(aTypeString, aMediator)
   259 {
   260   mCurrentPosition = aMediator.mOldestWindow;
   261   AdjustInitialPosition();
   262 }
   264 nsASDOMWindowEarlyToLateEnumerator::~nsASDOMWindowEarlyToLateEnumerator()
   265 {
   266 }
   268 nsWindowInfo *nsASDOMWindowEarlyToLateEnumerator::FindNext()
   269 {
   270   nsWindowInfo *info,
   271                *listEnd;
   272   bool          allWindows = mType.IsEmpty();
   274   // see nsXULWindowEarlyToLateEnumerator::FindNext
   275   if (!mCurrentPosition)
   276     return nullptr;
   278   info = mCurrentPosition->mYounger;
   279   listEnd = mWindowMediator->mOldestWindow;
   281   while (info != listEnd) {
   282     if (allWindows || info->TypeEquals(mType))
   283       return info;
   284     info = info->mYounger;
   285   }
   287   return nullptr;
   288 }
   290 //
   291 // nsASXULWindowEarlyToLateEnumerator
   292 //
   294 nsASXULWindowEarlyToLateEnumerator::nsASXULWindowEarlyToLateEnumerator(
   295     const char16_t *aTypeString,
   296     nsWindowMediator &aMediator) :
   297       nsASXULWindowEnumerator(aTypeString, aMediator)
   298 {
   299   mCurrentPosition = aMediator.mOldestWindow;
   300   AdjustInitialPosition();
   301 }
   303 nsASXULWindowEarlyToLateEnumerator::~nsASXULWindowEarlyToLateEnumerator()
   304 {
   305 }
   307 nsWindowInfo *nsASXULWindowEarlyToLateEnumerator::FindNext()
   308 {
   309   nsWindowInfo *info,
   310                *listEnd;
   311   bool          allWindows = mType.IsEmpty();
   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   if (!mCurrentPosition)
   321     return nullptr;
   323   info = mCurrentPosition->mYounger;
   324   listEnd = mWindowMediator->mOldestWindow;
   326   while (info != listEnd) {
   327     if (allWindows || info->TypeEquals(mType))
   328       return info;
   329     info = info->mYounger;
   330   }
   332   return nullptr;
   333 }
   335 //
   336 // nsASDOMWindowFrontToBackEnumerator
   337 //
   339 nsASDOMWindowFrontToBackEnumerator::nsASDOMWindowFrontToBackEnumerator(
   340     const char16_t *aTypeString,
   341     nsWindowMediator &aMediator) :
   342       nsASDOMWindowEnumerator(aTypeString, aMediator)
   343 {
   344   mCurrentPosition = aMediator.mTopmostWindow;
   345   AdjustInitialPosition();
   346 }
   348 nsASDOMWindowFrontToBackEnumerator::~nsASDOMWindowFrontToBackEnumerator()
   349 {
   350 }
   352 nsWindowInfo *nsASDOMWindowFrontToBackEnumerator::FindNext()
   353 {
   354   nsWindowInfo *info,
   355                *listEnd;
   356   bool          allWindows = mType.IsEmpty();
   358   // see nsXULWindowEarlyToLateEnumerator::FindNext
   359   if (!mCurrentPosition)
   360     return nullptr;
   362   info = mCurrentPosition->mLower;
   363   listEnd = mWindowMediator->mTopmostWindow;
   365   while (info != listEnd) {
   366     if (allWindows || info->TypeEquals(mType))
   367       return info;
   368     info = info->mLower;
   369   }
   371   return nullptr;
   372 }
   374 //
   375 // nsASXULWindowFrontToBackEnumerator
   376 //
   378 nsASXULWindowFrontToBackEnumerator::nsASXULWindowFrontToBackEnumerator(
   379     const char16_t *aTypeString,
   380     nsWindowMediator &aMediator) :
   381       nsASXULWindowEnumerator(aTypeString, aMediator)
   382 {
   383   mCurrentPosition = aMediator.mTopmostWindow;
   384   AdjustInitialPosition();
   385 }
   387 nsASXULWindowFrontToBackEnumerator::~nsASXULWindowFrontToBackEnumerator()
   388 {
   389 }
   391 nsWindowInfo *nsASXULWindowFrontToBackEnumerator::FindNext()
   392 {
   393   nsWindowInfo *info,
   394                *listEnd;
   395   bool          allWindows = mType.IsEmpty();
   397   // see nsXULWindowEarlyToLateEnumerator::FindNext
   398   if (!mCurrentPosition)
   399     return nullptr;
   401   info = mCurrentPosition->mLower;
   402   listEnd = mWindowMediator->mTopmostWindow;
   404   while (info != listEnd) {
   405     if (allWindows || info->TypeEquals(mType))
   406       return info;
   407     info = info->mLower;
   408   }
   410   return nullptr;
   411 }
   413 //
   414 // nsASDOMWindowBackToFrontEnumerator
   415 //
   417 nsASDOMWindowBackToFrontEnumerator::nsASDOMWindowBackToFrontEnumerator(
   418     const char16_t *aTypeString,
   419     nsWindowMediator &aMediator) :
   420   nsASDOMWindowEnumerator(aTypeString, aMediator)
   421 {
   422   mCurrentPosition = aMediator.mTopmostWindow ?
   423                      aMediator.mTopmostWindow->mHigher : nullptr;
   424   AdjustInitialPosition();
   425 }
   427 nsASDOMWindowBackToFrontEnumerator::~nsASDOMWindowBackToFrontEnumerator()
   428 {
   429 }
   431 nsWindowInfo *nsASDOMWindowBackToFrontEnumerator::FindNext()
   432 {
   433   nsWindowInfo *info,
   434                *listEnd;
   435   bool          allWindows = mType.IsEmpty();
   437   // see nsXULWindowEarlyToLateEnumerator::FindNext
   438   if (!mCurrentPosition)
   439     return nullptr;
   441   info = mCurrentPosition->mHigher;
   442   listEnd = mWindowMediator->mTopmostWindow;
   443   if (listEnd)
   444     listEnd = listEnd->mHigher;
   446   while (info != listEnd) {
   447     if (allWindows || info->TypeEquals(mType))
   448       return info;
   449     info = info->mHigher;
   450   }
   452   return nullptr;
   453 }
   455 //
   456 // nsASXULWindowBackToFrontEnumerator
   457 //
   459 nsASXULWindowBackToFrontEnumerator::nsASXULWindowBackToFrontEnumerator(
   460     const char16_t *aTypeString,
   461     nsWindowMediator &aMediator) :
   462       nsASXULWindowEnumerator(aTypeString, aMediator)
   463 {
   464   mCurrentPosition = aMediator.mTopmostWindow ?
   465                      aMediator.mTopmostWindow->mHigher : nullptr;
   466   AdjustInitialPosition();
   467 }
   469 nsASXULWindowBackToFrontEnumerator::~nsASXULWindowBackToFrontEnumerator()
   470 {
   471 }
   473 nsWindowInfo *nsASXULWindowBackToFrontEnumerator::FindNext()
   474 {
   475   nsWindowInfo *info,
   476                *listEnd;
   477   bool          allWindows = mType.IsEmpty();
   479   // see nsXULWindowEarlyToLateEnumerator::FindNext
   480   if (!mCurrentPosition)
   481     return nullptr;
   483   info = mCurrentPosition->mHigher;
   484   listEnd = mWindowMediator->mTopmostWindow;
   485   if (listEnd)
   486     listEnd = listEnd->mHigher;
   488   while (info != listEnd) {
   489     if (allWindows || info->TypeEquals(mType))
   490       return info;
   491     info = info->mHigher;
   492   }
   494   return nullptr;
   495 }

mercurial