Bug 1880273 [wpt PR 44583] - WebKit export of https://bugs.webkit.org/show_bug.cgi...
[gecko.git] / xpfe / appshell / nsContentTreeOwner.cpp
blob72fa807bbace65a4dfb1036f4e0b23bfe33e1231
1 /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=2 sw=2 et tw=80:
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 // Local Includes
9 #include "nsContentTreeOwner.h"
10 #include "AppWindow.h"
12 // Interfaces needed to be included
13 #include "nsGlobalWindowOuter.h"
14 #include "nsIDOMWindow.h"
15 #include "nsIBrowserDOMWindow.h"
16 #include "nsIOpenWindowInfo.h"
17 #include "nsIPrompt.h"
18 #include "nsIAuthPrompt.h"
19 #include "nsIXULBrowserWindow.h"
20 #include "nsIPrincipal.h"
21 #include "nsIURIFixup.h"
22 #include "nsIWebNavigation.h"
23 #include "nsDocShellCID.h"
24 #include "nsIMIMEInfo.h"
25 #include "nsIWidget.h"
26 #include "nsWindowWatcher.h"
27 #include "nsIWindowMediator.h"
28 #include "mozilla/Components.h"
29 #include "mozilla/NullPrincipal.h"
30 #include "nsDocShell.h"
31 #include "nsDocShellLoadState.h"
32 #include "nsQueryActor.h"
34 #include "nsIScriptObjectPrincipal.h"
35 #include "nsIURI.h"
36 #include "mozilla/dom/Document.h"
37 #if defined(XP_MACOSX)
38 # include "nsThreadUtils.h"
39 #endif
41 #include "mozilla/Preferences.h"
42 #include "mozilla/Try.h"
43 #include "mozilla/dom/Element.h"
44 #include "mozilla/dom/ScriptSettings.h"
45 #include "mozilla/dom/UserActivation.h"
47 using namespace mozilla;
49 //*****************************************************************************
50 //*** nsContentTreeOwner: Object Management
51 //*****************************************************************************
53 nsContentTreeOwner::nsContentTreeOwner(bool fPrimary)
54 : mAppWindow(nullptr), mPrimary(fPrimary) {}
56 //*****************************************************************************
57 // nsContentTreeOwner::nsISupports
58 //*****************************************************************************
60 NS_IMPL_ADDREF(nsContentTreeOwner)
61 NS_IMPL_RELEASE(nsContentTreeOwner)
63 NS_INTERFACE_MAP_BEGIN(nsContentTreeOwner)
64 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellTreeOwner)
65 NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner)
66 NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
67 NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
68 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
69 NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
70 NS_INTERFACE_MAP_END
72 //*****************************************************************************
73 // nsContentTreeOwner::nsIInterfaceRequestor
74 //*****************************************************************************
76 NS_IMETHODIMP nsContentTreeOwner::GetInterface(const nsIID& aIID,
77 void** aSink) {
78 NS_ENSURE_ARG_POINTER(aSink);
79 *aSink = nullptr;
81 if (aIID.Equals(NS_GET_IID(nsIPrompt))) {
82 NS_ENSURE_STATE(mAppWindow);
83 return mAppWindow->GetInterface(aIID, aSink);
85 if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
86 NS_ENSURE_STATE(mAppWindow);
87 return mAppWindow->GetInterface(aIID, aSink);
89 if (aIID.Equals(NS_GET_IID(nsIDocShellTreeItem))) {
90 NS_ENSURE_STATE(mAppWindow);
91 nsCOMPtr<nsIDocShell> shell;
92 mAppWindow->GetDocShell(getter_AddRefs(shell));
93 if (shell) return shell->QueryInterface(aIID, aSink);
94 return NS_ERROR_FAILURE;
97 if (aIID.Equals(NS_GET_IID(nsIDOMWindow)) ||
98 aIID.Equals(NS_GET_IID(nsPIDOMWindowOuter))) {
99 NS_ENSURE_STATE(mAppWindow);
100 nsCOMPtr<nsIDocShellTreeItem> shell;
101 mAppWindow->GetPrimaryContentShell(getter_AddRefs(shell));
102 if (shell) {
103 nsCOMPtr<nsIInterfaceRequestor> thing(do_QueryInterface(shell));
104 if (thing) return thing->GetInterface(aIID, aSink);
106 return NS_ERROR_FAILURE;
109 if (aIID.Equals(NS_GET_IID(nsIAppWindow))) {
110 NS_ENSURE_STATE(mAppWindow);
111 return mAppWindow->QueryInterface(aIID, aSink);
114 return QueryInterface(aIID, aSink);
117 //*****************************************************************************
118 // nsContentTreeOwner::nsIDocShellTreeOwner
119 //*****************************************************************************
121 NS_IMETHODIMP
122 nsContentTreeOwner::ContentShellAdded(nsIDocShellTreeItem* aContentShell,
123 bool aPrimary) {
124 NS_ENSURE_STATE(mAppWindow);
125 return mAppWindow->ContentShellAdded(aContentShell, aPrimary);
128 NS_IMETHODIMP
129 nsContentTreeOwner::ContentShellRemoved(nsIDocShellTreeItem* aContentShell) {
130 NS_ENSURE_STATE(mAppWindow);
131 return mAppWindow->ContentShellRemoved(aContentShell);
134 NS_IMETHODIMP
135 nsContentTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem** aShell) {
136 NS_ENSURE_STATE(mAppWindow);
137 return mAppWindow->GetPrimaryContentShell(aShell);
140 NS_IMETHODIMP
141 nsContentTreeOwner::RemoteTabAdded(nsIRemoteTab* aTab, bool aPrimary) {
142 NS_ENSURE_STATE(mAppWindow);
143 return mAppWindow->RemoteTabAdded(aTab, aPrimary);
146 NS_IMETHODIMP
147 nsContentTreeOwner::RemoteTabRemoved(nsIRemoteTab* aTab) {
148 NS_ENSURE_STATE(mAppWindow);
149 return mAppWindow->RemoteTabRemoved(aTab);
152 NS_IMETHODIMP
153 nsContentTreeOwner::GetPrimaryRemoteTab(nsIRemoteTab** aTab) {
154 NS_ENSURE_STATE(mAppWindow);
155 return mAppWindow->GetPrimaryRemoteTab(aTab);
158 NS_IMETHODIMP
159 nsContentTreeOwner::GetPrimaryContentBrowsingContext(
160 mozilla::dom::BrowsingContext** aBc) {
161 NS_ENSURE_STATE(mAppWindow);
162 return mAppWindow->GetPrimaryContentBrowsingContext(aBc);
165 NS_IMETHODIMP
166 nsContentTreeOwner::GetPrimaryContentSize(int32_t* aWidth, int32_t* aHeight) {
167 NS_ENSURE_STATE(mAppWindow);
168 return mAppWindow->GetPrimaryContentSize(aWidth, aHeight);
171 NS_IMETHODIMP
172 nsContentTreeOwner::SetPrimaryContentSize(int32_t aWidth, int32_t aHeight) {
173 NS_ENSURE_STATE(mAppWindow);
174 return mAppWindow->SetPrimaryContentSize(aWidth, aHeight);
177 NS_IMETHODIMP
178 nsContentTreeOwner::GetRootShellSize(int32_t* aWidth, int32_t* aHeight) {
179 NS_ENSURE_STATE(mAppWindow);
180 return mAppWindow->GetRootShellSize(aWidth, aHeight);
183 NS_IMETHODIMP
184 nsContentTreeOwner::SetRootShellSize(int32_t aWidth, int32_t aHeight) {
185 NS_ENSURE_STATE(mAppWindow);
186 return mAppWindow->SetRootShellSize(aWidth, aHeight);
189 NS_IMETHODIMP nsContentTreeOwner::SizeShellTo(nsIDocShellTreeItem* aShellItem,
190 int32_t aCX, int32_t aCY) {
191 NS_ENSURE_STATE(mAppWindow);
192 return mAppWindow->SizeShellTo(aShellItem, aCX, aCY);
195 NS_IMETHODIMP
196 nsContentTreeOwner::SetPersistence(bool aPersistPosition, bool aPersistSize,
197 bool aPersistSizeMode) {
198 NS_ENSURE_STATE(mAppWindow);
199 nsCOMPtr<dom::Element> docShellElement = mAppWindow->GetWindowDOMElement();
200 if (!docShellElement) return NS_ERROR_FAILURE;
202 nsAutoString persistString;
203 docShellElement->GetAttr(nsGkAtoms::persist, persistString);
205 bool saveString = false;
206 int32_t index;
208 // Set X
209 index = persistString.Find(u"screenX");
210 if (!aPersistPosition && index >= 0) {
211 persistString.Cut(index, 7);
212 saveString = true;
213 } else if (aPersistPosition && index < 0) {
214 persistString.AppendLiteral(" screenX");
215 saveString = true;
217 // Set Y
218 index = persistString.Find(u"screenY");
219 if (!aPersistPosition && index >= 0) {
220 persistString.Cut(index, 7);
221 saveString = true;
222 } else if (aPersistPosition && index < 0) {
223 persistString.AppendLiteral(" screenY");
224 saveString = true;
226 // Set CX
227 index = persistString.Find(u"width");
228 if (!aPersistSize && index >= 0) {
229 persistString.Cut(index, 5);
230 saveString = true;
231 } else if (aPersistSize && index < 0) {
232 persistString.AppendLiteral(" width");
233 saveString = true;
235 // Set CY
236 index = persistString.Find(u"height");
237 if (!aPersistSize && index >= 0) {
238 persistString.Cut(index, 6);
239 saveString = true;
240 } else if (aPersistSize && index < 0) {
241 persistString.AppendLiteral(" height");
242 saveString = true;
244 // Set SizeMode
245 index = persistString.Find(u"sizemode");
246 if (!aPersistSizeMode && (index >= 0)) {
247 persistString.Cut(index, 8);
248 saveString = true;
249 } else if (aPersistSizeMode && (index < 0)) {
250 persistString.AppendLiteral(" sizemode");
251 saveString = true;
254 ErrorResult rv;
255 if (saveString) {
256 docShellElement->SetAttribute(u"persist"_ns, persistString, rv);
259 return NS_OK;
262 NS_IMETHODIMP
263 nsContentTreeOwner::GetPersistence(bool* aPersistPosition, bool* aPersistSize,
264 bool* aPersistSizeMode) {
265 NS_ENSURE_STATE(mAppWindow);
266 nsCOMPtr<dom::Element> docShellElement = mAppWindow->GetWindowDOMElement();
267 if (!docShellElement) return NS_ERROR_FAILURE;
269 nsAutoString persistString;
270 docShellElement->GetAttr(nsGkAtoms::persist, persistString);
272 // data structure doesn't quite match the question, but it's close enough
273 // for what we want (since this method is never actually called...)
274 if (aPersistPosition) {
275 *aPersistPosition = persistString.Find(u"screenX") >= 0 ||
276 persistString.Find(u"screenY") >= 0;
278 if (aPersistSize) {
279 *aPersistSize =
280 persistString.Find(u"width") >= 0 || persistString.Find(u"height") >= 0;
282 if (aPersistSizeMode) {
283 *aPersistSizeMode = persistString.Find(u"sizemode") >= 0;
286 return NS_OK;
289 NS_IMETHODIMP
290 nsContentTreeOwner::GetTabCount(uint32_t* aResult) {
291 if (mAppWindow) {
292 return mAppWindow->GetTabCount(aResult);
295 *aResult = 0;
296 return NS_OK;
299 NS_IMETHODIMP
300 nsContentTreeOwner::GetHasPrimaryContent(bool* aResult) {
301 NS_ENSURE_STATE(mAppWindow);
302 return mAppWindow->GetHasPrimaryContent(aResult);
305 //*****************************************************************************
306 // nsContentTreeOwner::nsIWebBrowserChrome
307 //*****************************************************************************
309 NS_IMETHODIMP nsContentTreeOwner::SetLinkStatus(const nsAString& aStatusText) {
310 NS_ENSURE_STATE(mAppWindow);
312 nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow;
313 mAppWindow->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow));
315 if (xulBrowserWindow) {
316 xulBrowserWindow->SetOverLink(aStatusText);
319 return NS_OK;
322 NS_IMETHODIMP nsContentTreeOwner::SetChromeFlags(uint32_t aChromeFlags) {
323 NS_ENSURE_STATE(mAppWindow);
324 return mAppWindow->SetChromeFlags(aChromeFlags);
327 NS_IMETHODIMP nsContentTreeOwner::GetChromeFlags(uint32_t* aChromeFlags) {
328 NS_ENSURE_STATE(mAppWindow);
329 return mAppWindow->GetChromeFlags(aChromeFlags);
332 NS_IMETHODIMP nsContentTreeOwner::ShowAsModal() {
333 NS_ENSURE_STATE(mAppWindow);
334 return mAppWindow->ShowModal();
337 NS_IMETHODIMP nsContentTreeOwner::IsWindowModal(bool* _retval) {
338 NS_ENSURE_STATE(mAppWindow);
339 *_retval = mAppWindow->mContinueModalLoop;
340 return NS_OK;
343 //*****************************************************************************
344 // nsContentTreeOwner::nsIBaseWindow
345 //*****************************************************************************
347 NS_IMETHODIMP nsContentTreeOwner::InitWindow(nativeWindow aParentNativeWindow,
348 nsIWidget* parentWidget, int32_t x,
349 int32_t y, int32_t cx,
350 int32_t cy) {
351 // Ignore wigdet parents for now. Don't think those are a vaild thing to
352 // call.
353 NS_ENSURE_SUCCESS(SetPositionAndSize(x, y, cx, cy, 0), NS_ERROR_FAILURE);
355 return NS_OK;
358 NS_IMETHODIMP nsContentTreeOwner::Destroy() {
359 NS_ENSURE_STATE(mAppWindow);
360 return mAppWindow->Destroy();
363 double nsContentTreeOwner::GetWidgetCSSToDeviceScale() {
364 return mAppWindow ? mAppWindow->GetWidgetCSSToDeviceScale() : 1.0;
367 NS_IMETHODIMP nsContentTreeOwner::GetDevicePixelsPerDesktopPixel(
368 double* aScale) {
369 NS_ENSURE_STATE(mAppWindow);
370 return mAppWindow->GetDevicePixelsPerDesktopPixel(aScale);
373 NS_IMETHODIMP nsContentTreeOwner::SetPositionDesktopPix(int32_t aX,
374 int32_t aY) {
375 NS_ENSURE_STATE(mAppWindow);
376 return mAppWindow->SetPositionDesktopPix(aX, aY);
379 NS_IMETHODIMP nsContentTreeOwner::SetPosition(int32_t aX, int32_t aY) {
380 NS_ENSURE_STATE(mAppWindow);
381 return mAppWindow->SetPosition(aX, aY);
384 NS_IMETHODIMP nsContentTreeOwner::GetPosition(int32_t* aX, int32_t* aY) {
385 NS_ENSURE_STATE(mAppWindow);
386 return mAppWindow->GetPosition(aX, aY);
389 NS_IMETHODIMP nsContentTreeOwner::SetSize(int32_t aCX, int32_t aCY,
390 bool aRepaint) {
391 NS_ENSURE_STATE(mAppWindow);
392 return mAppWindow->SetSize(aCX, aCY, aRepaint);
395 NS_IMETHODIMP nsContentTreeOwner::GetSize(int32_t* aCX, int32_t* aCY) {
396 NS_ENSURE_STATE(mAppWindow);
397 return mAppWindow->GetSize(aCX, aCY);
400 NS_IMETHODIMP nsContentTreeOwner::SetPositionAndSize(int32_t aX, int32_t aY,
401 int32_t aCX, int32_t aCY,
402 uint32_t aFlags) {
403 NS_ENSURE_STATE(mAppWindow);
404 return mAppWindow->SetPositionAndSize(aX, aY, aCX, aCY, aFlags);
407 NS_IMETHODIMP nsContentTreeOwner::GetPositionAndSize(int32_t* aX, int32_t* aY,
408 int32_t* aCX,
409 int32_t* aCY) {
410 NS_ENSURE_STATE(mAppWindow);
411 return mAppWindow->GetPositionAndSize(aX, aY, aCX, aCY);
414 NS_IMETHODIMP
415 nsContentTreeOwner::SetDimensions(DimensionRequest&& aRequest) {
416 NS_ENSURE_STATE(mAppWindow);
417 if (aRequest.mDimensionKind == DimensionKind::Outer) {
418 return mAppWindow->SetDimensions(std::move(aRequest));
421 MOZ_TRY(aRequest.SupplementFrom(this));
422 return aRequest.ApplyInnerTo(this, /* aAsRootShell */ false);
425 NS_IMETHODIMP
426 nsContentTreeOwner::GetDimensions(DimensionKind aDimensionKind, int32_t* aX,
427 int32_t* aY, int32_t* aCX, int32_t* aCY) {
428 NS_ENSURE_STATE(mAppWindow);
429 if (aDimensionKind == DimensionKind::Outer) {
430 return mAppWindow->GetDimensions(aDimensionKind, aX, aY, aCX, aCY);
432 if (aY || aX) {
433 return NS_ERROR_NOT_IMPLEMENTED;
435 return GetPrimaryContentSize(aCX, aCY);
438 NS_IMETHODIMP nsContentTreeOwner::Repaint(bool aForce) {
439 NS_ENSURE_STATE(mAppWindow);
440 return mAppWindow->Repaint(aForce);
443 NS_IMETHODIMP nsContentTreeOwner::GetParentWidget(nsIWidget** aParentWidget) {
444 NS_ENSURE_STATE(mAppWindow);
445 return mAppWindow->GetParentWidget(aParentWidget);
448 NS_IMETHODIMP nsContentTreeOwner::SetParentWidget(nsIWidget* aParentWidget) {
449 NS_ASSERTION(false, "You can't call this");
450 return NS_ERROR_NOT_IMPLEMENTED;
453 NS_IMETHODIMP nsContentTreeOwner::GetParentNativeWindow(
454 nativeWindow* aParentNativeWindow) {
455 NS_ENSURE_STATE(mAppWindow);
456 return mAppWindow->GetParentNativeWindow(aParentNativeWindow);
459 NS_IMETHODIMP nsContentTreeOwner::SetParentNativeWindow(
460 nativeWindow aParentNativeWindow) {
461 NS_ASSERTION(false, "You can't call this");
462 return NS_ERROR_NOT_IMPLEMENTED;
465 NS_IMETHODIMP nsContentTreeOwner::GetNativeHandle(nsAString& aNativeHandle) {
466 NS_ENSURE_STATE(mAppWindow);
467 return mAppWindow->GetNativeHandle(aNativeHandle);
470 NS_IMETHODIMP nsContentTreeOwner::GetVisibility(bool* aVisibility) {
471 NS_ENSURE_STATE(mAppWindow);
472 return mAppWindow->GetVisibility(aVisibility);
475 NS_IMETHODIMP nsContentTreeOwner::SetVisibility(bool aVisibility) {
476 NS_ENSURE_STATE(mAppWindow);
477 return mAppWindow->SetVisibility(aVisibility);
480 NS_IMETHODIMP nsContentTreeOwner::GetEnabled(bool* aEnabled) {
481 NS_ENSURE_STATE(mAppWindow);
482 return mAppWindow->GetEnabled(aEnabled);
485 NS_IMETHODIMP nsContentTreeOwner::SetEnabled(bool aEnable) {
486 NS_ENSURE_STATE(mAppWindow);
487 return mAppWindow->SetEnabled(aEnable);
490 NS_IMETHODIMP nsContentTreeOwner::GetMainWidget(nsIWidget** aMainWidget) {
491 NS_ENSURE_ARG_POINTER(aMainWidget);
492 NS_ENSURE_STATE(mAppWindow);
494 *aMainWidget = mAppWindow->mWindow;
495 NS_IF_ADDREF(*aMainWidget);
497 return NS_OK;
500 NS_IMETHODIMP nsContentTreeOwner::GetTitle(nsAString& aTitle) {
501 NS_ENSURE_STATE(mAppWindow);
503 return mAppWindow->GetTitle(aTitle);
506 NS_IMETHODIMP nsContentTreeOwner::SetTitle(const nsAString& aTitle) {
507 return NS_OK;
510 //*****************************************************************************
511 // nsContentTreeOwner: nsIWindowProvider
512 //*****************************************************************************
513 NS_IMETHODIMP
514 nsContentTreeOwner::ProvideWindow(
515 nsIOpenWindowInfo* aOpenWindowInfo, uint32_t aChromeFlags,
516 bool aCalledFromJS, nsIURI* aURI, const nsAString& aName,
517 const nsACString& aFeatures,
518 const mozilla::dom::UserActivation::Modifiers& aModifiers,
519 bool aForceNoOpener, bool aForceNoReferrer, bool aIsPopupRequested,
520 nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
521 dom::BrowsingContext** aReturn) {
522 NS_ENSURE_ARG_POINTER(aOpenWindowInfo);
524 RefPtr<dom::BrowsingContext> parent = aOpenWindowInfo->GetParent();
526 *aReturn = nullptr;
528 if (!mAppWindow) {
529 // Nothing to do here
530 return NS_OK;
533 #ifdef DEBUG
534 nsCOMPtr<nsIDocShell> docshell = parent->GetDocShell();
535 nsCOMPtr<nsIDocShellTreeOwner> parentOwner = do_GetInterface(docshell);
536 NS_ASSERTION(
537 SameCOMIdentity(parentOwner, static_cast<nsIDocShellTreeOwner*>(this)),
538 "Parent from wrong docshell tree?");
539 #endif
541 int32_t openLocation = nsWindowWatcher::GetWindowOpenLocation(
542 parent->GetDOMWindow(), aChromeFlags, aModifiers, aCalledFromJS,
543 aOpenWindowInfo->GetIsForPrinting());
545 if (openLocation != nsIBrowserDOMWindow::OPEN_NEWTAB &&
546 openLocation != nsIBrowserDOMWindow::OPEN_NEWTAB_BACKGROUND &&
547 openLocation != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW &&
548 openLocation != nsIBrowserDOMWindow::OPEN_PRINT_BROWSER) {
549 // Just open a window normally
550 return NS_OK;
553 nsCOMPtr<mozIDOMWindowProxy> domWin;
554 mAppWindow->GetWindowDOMWindow(getter_AddRefs(domWin));
555 if (!domWin || !nsGlobalWindowOuter::Cast(domWin)->IsChromeWindow()) {
556 // Really odd... but whatever
557 NS_WARNING("AppWindow's DOMWindow is not a chrome window");
558 return NS_OK;
561 nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin =
562 nsGlobalWindowOuter::Cast(domWin)->GetBrowserDOMWindow();
563 if (!browserDOMWin) {
564 return NS_OK;
567 *aWindowIsNew = (openLocation != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW);
570 dom::AutoNoJSAPI nojsapi;
572 uint32_t flags = nsIBrowserDOMWindow::OPEN_NEW;
573 if (aForceNoOpener) {
574 flags |= nsIBrowserDOMWindow::OPEN_NO_OPENER;
576 if (aForceNoReferrer) {
577 flags |= nsIBrowserDOMWindow::OPEN_NO_REFERRER;
580 // Get a new rendering area from the browserDOMWin.
581 // Since we are not loading any URI, we follow the principle of least
582 // privilege and use a nullPrincipal as the triggeringPrincipal.
584 // This method handles setting the opener for us, so we don't need to set it
585 // ourselves.
586 RefPtr<NullPrincipal> nullPrincipal =
587 NullPrincipal::CreateWithoutOriginAttributes();
588 return browserDOMWin->CreateContentWindow(aURI, aOpenWindowInfo,
589 openLocation, flags,
590 nullPrincipal, nullptr, aReturn);
594 //*****************************************************************************
595 // nsContentTreeOwner: Accessors
596 //*****************************************************************************
598 void nsContentTreeOwner::AppWindow(mozilla::AppWindow* aAppWindow) {
599 mAppWindow = aAppWindow;
602 mozilla::AppWindow* nsContentTreeOwner::AppWindow() { return mAppWindow; }
604 /* this implementation focuses another window. if there isn't another
605 window to focus, we do nothing. */
606 NS_IMETHODIMP
607 nsContentTreeOwner::Blur() {
608 NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID);
610 nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
611 nsCOMPtr<nsIAppWindow> appWindow;
612 bool more, foundUs;
615 nsCOMPtr<nsIWindowMediator> windowMediator(
616 do_GetService(kWindowMediatorCID));
617 if (windowMediator) {
618 windowMediator->GetZOrderAppWindowEnumerator(
619 nullptr, true, getter_AddRefs(windowEnumerator));
623 if (!windowEnumerator) return NS_ERROR_FAILURE;
625 // step through the top-level windows
626 foundUs = false;
627 windowEnumerator->HasMoreElements(&more);
628 while (more) {
629 nsCOMPtr<nsISupports> nextWindow;
630 nsCOMPtr<nsIAppWindow> nextAppWindow;
632 windowEnumerator->GetNext(getter_AddRefs(nextWindow));
633 nextAppWindow = do_QueryInterface(nextWindow);
635 // got it!(?)
636 if (foundUs) {
637 appWindow = nextAppWindow;
638 break;
641 // remember the very first one, in case we have to wrap
642 if (!appWindow) appWindow = nextAppWindow;
644 // look for us
645 if (nextAppWindow == mAppWindow) {
646 foundUs = true;
649 windowEnumerator->HasMoreElements(&more);
652 // change focus to the window we just found
653 if (appWindow) {
654 nsCOMPtr<nsIDocShell> docshell;
655 appWindow->GetDocShell(getter_AddRefs(docshell));
656 if (!docshell) {
657 return NS_OK;
660 nsCOMPtr<nsPIDOMWindowOuter> domWindow = docshell->GetWindow();
661 if (domWindow) domWindow->Focus(mozilla::dom::CallerType::System);
663 return NS_OK;