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.

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

mercurial