1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 // Local Includes
8 #include "nsWebBrowser.h"
9 
10 // Helper Classes
11 #include "nsGfxCIID.h"
12 #include "nsWidgetsCID.h"
13 
14 #include "gfxUtils.h"
15 #include "mozilla/gfx/2D.h"
16 
17 // Interfaces Needed
18 #include "gfxContext.h"
19 #include "nsReadableUtils.h"
20 #include "nsIComponentManager.h"
21 #include "nsIDOMDocument.h"
22 #include "nsIDOMWindow.h"
23 #include "nsIDOMElement.h"
24 #include "nsIInterfaceRequestor.h"
25 #include "nsIInterfaceRequestorUtils.h"
26 #include "nsIWebBrowserChrome.h"
27 #include "nsPIDOMWindow.h"
28 #include "nsIWebProgress.h"
29 #include "nsIWebProgressListener.h"
30 #include "nsIWebBrowserFocus.h"
31 #include "nsIPresShell.h"
32 #include "nsIURIContentListener.h"
33 #include "nsISHistoryListener.h"
34 #include "nsIURI.h"
35 #include "nsIWebBrowserPersist.h"
36 #include "nsCWebBrowserPersist.h"
37 #include "nsIServiceManager.h"
38 #include "nsFocusManager.h"
39 #include "Layers.h"
40 #include "nsILoadContext.h"
41 #include "nsDocShell.h"
42 
43 // for painting the background window
44 #include "mozilla/LookAndFeel.h"
45 
46 // Printing Includes
47 #ifdef NS_PRINTING
48 #include "nsIWebBrowserPrint.h"
49 #include "nsIContentViewer.h"
50 #endif
51 
52 // PSM2 includes
53 #include "nsISecureBrowserUI.h"
54 #include "nsXULAppAPI.h"
55 
56 using namespace mozilla;
57 using namespace mozilla::gfx;
58 using namespace mozilla::layers;
59 
60 static NS_DEFINE_CID(kChildCID, NS_CHILD_CID);
61 
nsWebBrowser()62 nsWebBrowser::nsWebBrowser()
63     : mInitInfo(new nsWebBrowserInitInfo()),
64       mContentType(typeContentWrapper),
65       mActivating(false),
66       mShouldEnableHistory(true),
67       mIsActive(true),
68       mParentNativeWindow(nullptr),
69       mProgressListener(nullptr),
70       mWidgetListenerDelegate(this),
71       mBackgroundColor(0),
72       mPersistCurrentState(nsIWebBrowserPersist::PERSIST_STATE_READY),
73       mPersistResult(NS_OK),
74       mPersistFlags(nsIWebBrowserPersist::PERSIST_FLAGS_NONE),
75       mParentWidget(nullptr) {
76   mWWatch = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
77   NS_ASSERTION(mWWatch, "failed to get WindowWatcher");
78 }
79 
~nsWebBrowser()80 nsWebBrowser::~nsWebBrowser() { InternalDestroy(); }
81 
82 NS_IMETHODIMP
InternalDestroy()83 nsWebBrowser::InternalDestroy() {
84   if (mInternalWidget) {
85     mInternalWidget->SetWidgetListener(nullptr);
86     mInternalWidget->Destroy();
87     mInternalWidget = nullptr;  // Force release here.
88   }
89 
90   SetDocShell(nullptr);
91 
92   if (mDocShellTreeOwner) {
93     mDocShellTreeOwner->WebBrowser(nullptr);
94     mDocShellTreeOwner = nullptr;
95   }
96 
97   mInitInfo = nullptr;
98 
99   mListenerArray = nullptr;
100 
101   return NS_OK;
102 }
103 
104 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWebBrowser)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWebBrowser)105 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWebBrowser)
106 
107 NS_IMPL_CYCLE_COLLECTION(nsWebBrowser, mDocShell, mDocShellAsReq,
108                          mDocShellAsWin, mDocShellAsNav, mDocShellAsScrollable,
109                          mDocShellAsTextScroll, mWebProgress)
110 
111 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWebBrowser)
112   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowser)
113   NS_INTERFACE_MAP_ENTRY(nsIWebBrowser)
114   NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
115   NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
116   NS_INTERFACE_MAP_ENTRY(nsIScrollable)
117   NS_INTERFACE_MAP_ENTRY(nsITextScroll)
118   NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem)
119   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
120   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserSetup)
121   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPersist)
122   NS_INTERFACE_MAP_ENTRY(nsICancelable)
123   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserFocus)
124   NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
125   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
126 NS_INTERFACE_MAP_END
127 
128 ///*****************************************************************************
129 // nsWebBrowser::nsIInterfaceRequestor
130 //*****************************************************************************
131 
132 NS_IMETHODIMP
133 nsWebBrowser::GetInterface(const nsIID& aIID, void** aSink) {
134   NS_ENSURE_ARG_POINTER(aSink);
135 
136   if (NS_SUCCEEDED(QueryInterface(aIID, aSink))) {
137     return NS_OK;
138   }
139 
140   if (mDocShell) {
141 #ifdef NS_PRINTING
142     if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) {
143       nsCOMPtr<nsIContentViewer> viewer;
144       mDocShell->GetContentViewer(getter_AddRefs(viewer));
145       if (!viewer) {
146         return NS_NOINTERFACE;
147       }
148 
149       nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint(do_QueryInterface(viewer));
150       nsIWebBrowserPrint* print = (nsIWebBrowserPrint*)webBrowserPrint.get();
151       NS_ASSERTION(print, "This MUST support this interface!");
152       NS_ADDREF(print);
153       *aSink = print;
154       return NS_OK;
155     }
156 #endif
157     return mDocShellAsReq->GetInterface(aIID, aSink);
158   }
159 
160   return NS_NOINTERFACE;
161 }
162 
163 //*****************************************************************************
164 // nsWebBrowser::nsIWebBrowser
165 //*****************************************************************************
166 
167 // listeners that currently support registration through AddWebBrowserListener:
168 //  - nsIWebProgressListener
169 NS_IMETHODIMP
AddWebBrowserListener(nsIWeakReference * aListener,const nsIID & aIID)170 nsWebBrowser::AddWebBrowserListener(nsIWeakReference* aListener,
171                                     const nsIID& aIID) {
172   NS_ENSURE_ARG_POINTER(aListener);
173 
174   nsresult rv = NS_OK;
175   if (!mWebProgress) {
176     // The window hasn't been created yet, so queue up the listener. They'll be
177     // registered when the window gets created.
178     if (!mListenerArray) {
179       mListenerArray = new nsTArray<nsWebBrowserListenerState>();
180     }
181 
182     nsWebBrowserListenerState* state = mListenerArray->AppendElement();
183     state->mWeakPtr = aListener;
184     state->mID = aIID;
185   } else {
186     nsCOMPtr<nsISupports> supports(do_QueryReferent(aListener));
187     if (!supports) {
188       return NS_ERROR_INVALID_ARG;
189     }
190     rv = BindListener(supports, aIID);
191   }
192 
193   return rv;
194 }
195 
196 NS_IMETHODIMP
BindListener(nsISupports * aListener,const nsIID & aIID)197 nsWebBrowser::BindListener(nsISupports* aListener, const nsIID& aIID) {
198   NS_ENSURE_ARG_POINTER(aListener);
199   NS_ASSERTION(
200       mWebProgress,
201       "this should only be called after we've retrieved a progress iface");
202   nsresult rv = NS_OK;
203 
204   // register this listener for the specified interface id
205   if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) {
206     nsCOMPtr<nsIWebProgressListener> listener =
207         do_QueryInterface(aListener, &rv);
208     if (NS_FAILED(rv)) {
209       return rv;
210     }
211     NS_ENSURE_STATE(mWebProgress);
212     rv =
213         mWebProgress->AddProgressListener(listener, nsIWebProgress::NOTIFY_ALL);
214   } else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) {
215     nsCOMPtr<nsISHistory> shistory(do_GetInterface(mDocShell, &rv));
216     if (NS_FAILED(rv)) {
217       return rv;
218     }
219     nsCOMPtr<nsISHistoryListener> listener(do_QueryInterface(aListener, &rv));
220     if (NS_FAILED(rv)) {
221       return rv;
222     }
223     rv = shistory->AddSHistoryListener(listener);
224   }
225   return rv;
226 }
227 
228 NS_IMETHODIMP
RemoveWebBrowserListener(nsIWeakReference * aListener,const nsIID & aIID)229 nsWebBrowser::RemoveWebBrowserListener(nsIWeakReference* aListener,
230                                        const nsIID& aIID) {
231   NS_ENSURE_ARG_POINTER(aListener);
232 
233   nsresult rv = NS_OK;
234   if (!mWebProgress) {
235     // if there's no-one to register the listener w/, and we don't have a queue
236     // going, the the called is calling Remove before an Add which doesn't make
237     // sense.
238     if (!mListenerArray) {
239       return NS_ERROR_FAILURE;
240     }
241 
242     // iterate the array and remove the queued listener
243     int32_t count = mListenerArray->Length();
244     while (count > 0) {
245       if (mListenerArray->ElementAt(count - 1).Equals(aListener, aIID)) {
246         mListenerArray->RemoveElementAt(count - 1);
247         break;
248       }
249       count--;
250     }
251 
252     // if we've emptied the array, get rid of it.
253     if (0 >= mListenerArray->Length()) {
254       mListenerArray = nullptr;
255     }
256 
257   } else {
258     nsCOMPtr<nsISupports> supports(do_QueryReferent(aListener));
259     if (!supports) {
260       return NS_ERROR_INVALID_ARG;
261     }
262     rv = UnBindListener(supports, aIID);
263   }
264 
265   return rv;
266 }
267 
268 NS_IMETHODIMP
UnBindListener(nsISupports * aListener,const nsIID & aIID)269 nsWebBrowser::UnBindListener(nsISupports* aListener, const nsIID& aIID) {
270   NS_ENSURE_ARG_POINTER(aListener);
271   NS_ASSERTION(
272       mWebProgress,
273       "this should only be called after we've retrieved a progress iface");
274   nsresult rv = NS_OK;
275 
276   // remove the listener for the specified interface id
277   if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) {
278     nsCOMPtr<nsIWebProgressListener> listener =
279         do_QueryInterface(aListener, &rv);
280     if (NS_FAILED(rv)) {
281       return rv;
282     }
283     NS_ENSURE_STATE(mWebProgress);
284     rv = mWebProgress->RemoveProgressListener(listener);
285   } else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) {
286     nsCOMPtr<nsISHistory> shistory(do_GetInterface(mDocShell, &rv));
287     if (NS_FAILED(rv)) {
288       return rv;
289     }
290     nsCOMPtr<nsISHistoryListener> listener(do_QueryInterface(aListener, &rv));
291     if (NS_FAILED(rv)) {
292       return rv;
293     }
294     rv = shistory->RemoveSHistoryListener(listener);
295   }
296   return rv;
297 }
298 
299 NS_IMETHODIMP
EnableGlobalHistory(bool aEnable)300 nsWebBrowser::EnableGlobalHistory(bool aEnable) {
301   NS_ENSURE_STATE(mDocShell);
302 
303   return mDocShell->SetUseGlobalHistory(aEnable);
304 }
305 
306 NS_IMETHODIMP
GetContainerWindow(nsIWebBrowserChrome ** aTopWindow)307 nsWebBrowser::GetContainerWindow(nsIWebBrowserChrome** aTopWindow) {
308   NS_ENSURE_ARG_POINTER(aTopWindow);
309 
310   nsCOMPtr<nsIWebBrowserChrome> top;
311   if (mDocShellTreeOwner) {
312     top = mDocShellTreeOwner->GetWebBrowserChrome();
313   }
314 
315   top.forget(aTopWindow);
316 
317   return NS_OK;
318 }
319 
320 NS_IMETHODIMP
SetContainerWindow(nsIWebBrowserChrome * aTopWindow)321 nsWebBrowser::SetContainerWindow(nsIWebBrowserChrome* aTopWindow) {
322   NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE);
323   return mDocShellTreeOwner->SetWebBrowserChrome(aTopWindow);
324 }
325 
326 NS_IMETHODIMP
GetParentURIContentListener(nsIURIContentListener ** aParentContentListener)327 nsWebBrowser::GetParentURIContentListener(
328     nsIURIContentListener** aParentContentListener) {
329   NS_ENSURE_ARG_POINTER(aParentContentListener);
330   *aParentContentListener = nullptr;
331 
332   // get the interface from the docshell
333   nsCOMPtr<nsIURIContentListener> listener(do_GetInterface(mDocShell));
334 
335   if (listener) {
336     return listener->GetParentContentListener(aParentContentListener);
337   }
338   return NS_OK;
339 }
340 
341 NS_IMETHODIMP
SetParentURIContentListener(nsIURIContentListener * aParentContentListener)342 nsWebBrowser::SetParentURIContentListener(
343     nsIURIContentListener* aParentContentListener) {
344   // get the interface from the docshell
345   nsCOMPtr<nsIURIContentListener> listener(do_GetInterface(mDocShell));
346 
347   if (listener) {
348     return listener->SetParentContentListener(aParentContentListener);
349   }
350   return NS_ERROR_FAILURE;
351 }
352 
353 NS_IMETHODIMP
GetContentDOMWindow(mozIDOMWindowProxy ** aResult)354 nsWebBrowser::GetContentDOMWindow(mozIDOMWindowProxy** aResult) {
355   if (!mDocShell) {
356     return NS_ERROR_UNEXPECTED;
357   }
358 
359   nsCOMPtr<nsPIDOMWindowOuter> retval = mDocShell->GetWindow();
360   retval.forget(aResult);
361   return *aResult ? NS_OK : NS_ERROR_FAILURE;
362 }
363 
364 NS_IMETHODIMP
GetIsActive(bool * aResult)365 nsWebBrowser::GetIsActive(bool* aResult) {
366   *aResult = mIsActive;
367   return NS_OK;
368 }
369 
370 NS_IMETHODIMP
SetIsActive(bool aIsActive)371 nsWebBrowser::SetIsActive(bool aIsActive) {
372   // Set our copy of the value
373   mIsActive = aIsActive;
374 
375   // If we have a docshell, pass on the request
376   if (mDocShell) {
377     return mDocShell->SetIsActive(aIsActive);
378   }
379   return NS_OK;
380 }
381 
SetOriginAttributes(const OriginAttributes & aAttrs)382 void nsWebBrowser::SetOriginAttributes(const OriginAttributes& aAttrs) {
383   mOriginAttributes = aAttrs;
384 }
385 
386 //*****************************************************************************
387 // nsWebBrowser::nsIDocShellTreeItem
388 //*****************************************************************************
389 
390 NS_IMETHODIMP
GetName(nsAString & aName)391 nsWebBrowser::GetName(nsAString& aName) {
392   if (mDocShell) {
393     mDocShell->GetName(aName);
394   } else {
395     aName = mInitInfo->name;
396   }
397 
398   return NS_OK;
399 }
400 
401 NS_IMETHODIMP
SetName(const nsAString & aName)402 nsWebBrowser::SetName(const nsAString& aName) {
403   if (mDocShell) {
404     return mDocShell->SetName(aName);
405   } else {
406     mInitInfo->name = aName;
407   }
408 
409   return NS_OK;
410 }
411 
412 NS_IMETHODIMP
NameEquals(const nsAString & aName,bool * aResult)413 nsWebBrowser::NameEquals(const nsAString& aName, bool* aResult) {
414   NS_ENSURE_ARG_POINTER(aResult);
415   if (mDocShell) {
416     return mDocShell->NameEquals(aName, aResult);
417   } else {
418     *aResult = mInitInfo->name.Equals(aName);
419   }
420 
421   return NS_OK;
422 }
423 
ItemType()424 /* virtual */ int32_t nsWebBrowser::ItemType() { return mContentType; }
425 
426 NS_IMETHODIMP
GetItemType(int32_t * aItemType)427 nsWebBrowser::GetItemType(int32_t* aItemType) {
428   NS_ENSURE_ARG_POINTER(aItemType);
429 
430   *aItemType = ItemType();
431   return NS_OK;
432 }
433 
434 NS_IMETHODIMP
SetItemType(int32_t aItemType)435 nsWebBrowser::SetItemType(int32_t aItemType) {
436   NS_ENSURE_TRUE(
437       aItemType == typeContentWrapper || aItemType == typeChromeWrapper,
438       NS_ERROR_FAILURE);
439   mContentType = aItemType;
440   if (mDocShell) {
441     mDocShell->SetItemType(mContentType == typeChromeWrapper
442                                ? static_cast<int32_t>(typeChrome)
443                                : static_cast<int32_t>(typeContent));
444   }
445 
446   return NS_OK;
447 }
448 
449 NS_IMETHODIMP
GetParent(nsIDocShellTreeItem ** aParent)450 nsWebBrowser::GetParent(nsIDocShellTreeItem** aParent) {
451   *aParent = nullptr;
452   return NS_OK;
453 }
454 
455 NS_IMETHODIMP
GetSameTypeParent(nsIDocShellTreeItem ** aParent)456 nsWebBrowser::GetSameTypeParent(nsIDocShellTreeItem** aParent) {
457   *aParent = nullptr;
458 
459   return NS_OK;
460 }
461 
462 NS_IMETHODIMP
GetRootTreeItem(nsIDocShellTreeItem ** aRootTreeItem)463 nsWebBrowser::GetRootTreeItem(nsIDocShellTreeItem** aRootTreeItem) {
464   NS_ENSURE_ARG_POINTER(aRootTreeItem);
465   *aRootTreeItem = static_cast<nsIDocShellTreeItem*>(this);
466 
467   nsCOMPtr<nsIDocShellTreeItem> parent;
468   NS_ENSURE_SUCCESS(GetParent(getter_AddRefs(parent)), NS_ERROR_FAILURE);
469   while (parent) {
470     *aRootTreeItem = parent;
471     NS_ENSURE_SUCCESS((*aRootTreeItem)->GetParent(getter_AddRefs(parent)),
472                       NS_ERROR_FAILURE);
473   }
474   NS_ADDREF(*aRootTreeItem);
475   return NS_OK;
476 }
477 
478 NS_IMETHODIMP
GetSameTypeRootTreeItem(nsIDocShellTreeItem ** aRootTreeItem)479 nsWebBrowser::GetSameTypeRootTreeItem(nsIDocShellTreeItem** aRootTreeItem) {
480   NS_ENSURE_ARG_POINTER(aRootTreeItem);
481   *aRootTreeItem = static_cast<nsIDocShellTreeItem*>(this);
482 
483   nsCOMPtr<nsIDocShellTreeItem> parent;
484   NS_ENSURE_SUCCESS(GetSameTypeParent(getter_AddRefs(parent)),
485                     NS_ERROR_FAILURE);
486   while (parent) {
487     *aRootTreeItem = parent;
488     NS_ENSURE_SUCCESS(
489         (*aRootTreeItem)->GetSameTypeParent(getter_AddRefs(parent)),
490         NS_ERROR_FAILURE);
491   }
492   NS_ADDREF(*aRootTreeItem);
493   return NS_OK;
494 }
495 
496 NS_IMETHODIMP
FindItemWithName(const nsAString & aName,nsIDocShellTreeItem * aRequestor,nsIDocShellTreeItem * aOriginalRequestor,bool aSkipTabGroup,nsIDocShellTreeItem ** aResult)497 nsWebBrowser::FindItemWithName(const nsAString& aName,
498                                nsIDocShellTreeItem* aRequestor,
499                                nsIDocShellTreeItem* aOriginalRequestor,
500                                bool aSkipTabGroup,
501                                nsIDocShellTreeItem** aResult) {
502   NS_ENSURE_STATE(mDocShell);
503   NS_ASSERTION(mDocShellTreeOwner,
504                "This should always be set when in this situation");
505 
506   return mDocShell->FindItemWithName(aName, aRequestor, aOriginalRequestor,
507                                      aSkipTabGroup, aResult);
508 }
509 
GetDocument()510 nsIDocument* nsWebBrowser::GetDocument() {
511   return mDocShell ? mDocShell->GetDocument() : nullptr;
512 }
513 
GetWindow()514 nsPIDOMWindowOuter* nsWebBrowser::GetWindow() {
515   return mDocShell ? mDocShell->GetWindow() : nullptr;
516 }
517 
518 NS_IMETHODIMP
GetTreeOwner(nsIDocShellTreeOwner ** aTreeOwner)519 nsWebBrowser::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner) {
520   NS_ENSURE_ARG_POINTER(aTreeOwner);
521   *aTreeOwner = nullptr;
522   if (mDocShellTreeOwner) {
523     if (mDocShellTreeOwner->mTreeOwner) {
524       *aTreeOwner = mDocShellTreeOwner->mTreeOwner;
525     } else {
526       *aTreeOwner = mDocShellTreeOwner;
527     }
528   }
529   NS_IF_ADDREF(*aTreeOwner);
530   return NS_OK;
531 }
532 
533 NS_IMETHODIMP
SetTreeOwner(nsIDocShellTreeOwner * aTreeOwner)534 nsWebBrowser::SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner) {
535   NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE);
536   return mDocShellTreeOwner->SetTreeOwner(aTreeOwner);
537 }
538 
539 //*****************************************************************************
540 // nsWebBrowser::nsIDocShellTreeItem
541 //*****************************************************************************
542 
543 NS_IMETHODIMP
GetChildCount(int32_t * aChildCount)544 nsWebBrowser::GetChildCount(int32_t* aChildCount) {
545   NS_ENSURE_ARG_POINTER(aChildCount);
546   *aChildCount = 0;
547   return NS_OK;
548 }
549 
550 NS_IMETHODIMP
AddChild(nsIDocShellTreeItem * aChild)551 nsWebBrowser::AddChild(nsIDocShellTreeItem* aChild) {
552   return NS_ERROR_UNEXPECTED;
553 }
554 
555 NS_IMETHODIMP
RemoveChild(nsIDocShellTreeItem * aChild)556 nsWebBrowser::RemoveChild(nsIDocShellTreeItem* aChild) {
557   return NS_ERROR_UNEXPECTED;
558 }
559 
560 NS_IMETHODIMP
GetChildAt(int32_t aIndex,nsIDocShellTreeItem ** aChild)561 nsWebBrowser::GetChildAt(int32_t aIndex, nsIDocShellTreeItem** aChild) {
562   return NS_ERROR_UNEXPECTED;
563 }
564 
565 NS_IMETHODIMP
FindChildWithName(const nsAString & aName,bool aRecurse,bool aSameType,nsIDocShellTreeItem * aRequestor,nsIDocShellTreeItem * aOriginalRequestor,nsIDocShellTreeItem ** aResult)566 nsWebBrowser::FindChildWithName(const nsAString& aName, bool aRecurse,
567                                 bool aSameType, nsIDocShellTreeItem* aRequestor,
568                                 nsIDocShellTreeItem* aOriginalRequestor,
569                                 nsIDocShellTreeItem** aResult) {
570   NS_ENSURE_ARG_POINTER(aResult);
571 
572   *aResult = nullptr;
573   return NS_OK;
574 }
575 
576 //*****************************************************************************
577 // nsWebBrowser::nsIWebNavigation
578 //*****************************************************************************
579 
580 NS_IMETHODIMP
GetCanGoBack(bool * aCanGoBack)581 nsWebBrowser::GetCanGoBack(bool* aCanGoBack) {
582   NS_ENSURE_STATE(mDocShell);
583 
584   return mDocShellAsNav->GetCanGoBack(aCanGoBack);
585 }
586 
587 NS_IMETHODIMP
GetCanGoForward(bool * aCanGoForward)588 nsWebBrowser::GetCanGoForward(bool* aCanGoForward) {
589   NS_ENSURE_STATE(mDocShell);
590 
591   return mDocShellAsNav->GetCanGoForward(aCanGoForward);
592 }
593 
594 NS_IMETHODIMP
GoBack()595 nsWebBrowser::GoBack() {
596   NS_ENSURE_STATE(mDocShell);
597 
598   return mDocShellAsNav->GoBack();
599 }
600 
601 NS_IMETHODIMP
GoForward()602 nsWebBrowser::GoForward() {
603   NS_ENSURE_STATE(mDocShell);
604 
605   return mDocShellAsNav->GoForward();
606 }
607 
608 NS_IMETHODIMP
LoadURIWithOptions(const char16_t * aURI,uint32_t aLoadFlags,nsIURI * aReferringURI,uint32_t aReferrerPolicy,nsIInputStream * aPostDataStream,nsIInputStream * aExtraHeaderStream,nsIURI * aBaseURI,nsIPrincipal * aTriggeringPrincipal)609 nsWebBrowser::LoadURIWithOptions(const char16_t* aURI, uint32_t aLoadFlags,
610                                  nsIURI* aReferringURI,
611                                  uint32_t aReferrerPolicy,
612                                  nsIInputStream* aPostDataStream,
613                                  nsIInputStream* aExtraHeaderStream,
614                                  nsIURI* aBaseURI,
615                                  nsIPrincipal* aTriggeringPrincipal) {
616   NS_ENSURE_STATE(mDocShell);
617 
618   return mDocShellAsNav->LoadURIWithOptions(
619       aURI, aLoadFlags, aReferringURI, aReferrerPolicy, aPostDataStream,
620       aExtraHeaderStream, aBaseURI, aTriggeringPrincipal);
621 }
622 
623 NS_IMETHODIMP
SetOriginAttributesBeforeLoading(JS::Handle<JS::Value> aOriginAttributes)624 nsWebBrowser::SetOriginAttributesBeforeLoading(
625     JS::Handle<JS::Value> aOriginAttributes) {
626   return mDocShellAsNav->SetOriginAttributesBeforeLoading(aOriginAttributes);
627 }
628 
629 NS_IMETHODIMP
LoadURI(const char16_t * aURI,uint32_t aLoadFlags,nsIURI * aReferringURI,nsIInputStream * aPostDataStream,nsIInputStream * aExtraHeaderStream,nsIPrincipal * aTriggeringPrincipal)630 nsWebBrowser::LoadURI(const char16_t* aURI, uint32_t aLoadFlags,
631                       nsIURI* aReferringURI, nsIInputStream* aPostDataStream,
632                       nsIInputStream* aExtraHeaderStream,
633                       nsIPrincipal* aTriggeringPrincipal) {
634   NS_ENSURE_STATE(mDocShell);
635 
636   return mDocShellAsNav->LoadURI(aURI, aLoadFlags, aReferringURI,
637                                  aPostDataStream, aExtraHeaderStream,
638                                  aTriggeringPrincipal);
639 }
640 
641 NS_IMETHODIMP
Reload(uint32_t aReloadFlags)642 nsWebBrowser::Reload(uint32_t aReloadFlags) {
643   NS_ENSURE_STATE(mDocShell);
644 
645   return mDocShellAsNav->Reload(aReloadFlags);
646 }
647 
648 NS_IMETHODIMP
GotoIndex(int32_t aIndex)649 nsWebBrowser::GotoIndex(int32_t aIndex) {
650   NS_ENSURE_STATE(mDocShell);
651 
652   return mDocShellAsNav->GotoIndex(aIndex);
653 }
654 
655 NS_IMETHODIMP
Stop(uint32_t aStopFlags)656 nsWebBrowser::Stop(uint32_t aStopFlags) {
657   NS_ENSURE_STATE(mDocShell);
658 
659   return mDocShellAsNav->Stop(aStopFlags);
660 }
661 
662 NS_IMETHODIMP
GetCurrentURI(nsIURI ** aURI)663 nsWebBrowser::GetCurrentURI(nsIURI** aURI) {
664   NS_ENSURE_STATE(mDocShell);
665 
666   return mDocShellAsNav->GetCurrentURI(aURI);
667 }
668 
669 NS_IMETHODIMP
GetReferringURI(nsIURI ** aURI)670 nsWebBrowser::GetReferringURI(nsIURI** aURI) {
671   NS_ENSURE_STATE(mDocShell);
672 
673   return mDocShellAsNav->GetReferringURI(aURI);
674 }
675 
676 NS_IMETHODIMP
SetSessionHistory(nsISHistory * aSessionHistory)677 nsWebBrowser::SetSessionHistory(nsISHistory* aSessionHistory) {
678   if (mDocShell) {
679     return mDocShellAsNav->SetSessionHistory(aSessionHistory);
680   } else {
681     mInitInfo->sessionHistory = aSessionHistory;
682   }
683 
684   return NS_OK;
685 }
686 
687 NS_IMETHODIMP
GetSessionHistory(nsISHistory ** aSessionHistory)688 nsWebBrowser::GetSessionHistory(nsISHistory** aSessionHistory) {
689   NS_ENSURE_ARG_POINTER(aSessionHistory);
690   if (mDocShell) {
691     return mDocShellAsNav->GetSessionHistory(aSessionHistory);
692   } else {
693     *aSessionHistory = mInitInfo->sessionHistory;
694   }
695 
696   NS_IF_ADDREF(*aSessionHistory);
697 
698   return NS_OK;
699 }
700 
701 NS_IMETHODIMP
GetDocument(nsIDOMDocument ** aDocument)702 nsWebBrowser::GetDocument(nsIDOMDocument** aDocument) {
703   NS_ENSURE_STATE(mDocShell);
704 
705   return mDocShellAsNav->GetDocument(aDocument);
706 }
707 
708 //*****************************************************************************
709 // nsWebBrowser::nsIWebBrowserSetup
710 //*****************************************************************************
711 
712 NS_IMETHODIMP
SetProperty(uint32_t aId,uint32_t aValue)713 nsWebBrowser::SetProperty(uint32_t aId, uint32_t aValue) {
714   nsresult rv = NS_OK;
715 
716   switch (aId) {
717     case nsIWebBrowserSetup::SETUP_ALLOW_PLUGINS: {
718       NS_ENSURE_STATE(mDocShell);
719       NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
720                       aValue == static_cast<uint32_t>(false)),
721                      NS_ERROR_INVALID_ARG);
722       mDocShell->SetAllowPlugins(!!aValue);
723       break;
724     }
725     case nsIWebBrowserSetup::SETUP_ALLOW_JAVASCRIPT: {
726       NS_ENSURE_STATE(mDocShell);
727       NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
728                       aValue == static_cast<uint32_t>(false)),
729                      NS_ERROR_INVALID_ARG);
730       mDocShell->SetAllowJavascript(!!aValue);
731       break;
732     }
733     case nsIWebBrowserSetup::SETUP_ALLOW_META_REDIRECTS: {
734       NS_ENSURE_STATE(mDocShell);
735       NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
736                       aValue == static_cast<uint32_t>(false)),
737                      NS_ERROR_INVALID_ARG);
738       mDocShell->SetAllowMetaRedirects(!!aValue);
739       break;
740     }
741     case nsIWebBrowserSetup::SETUP_ALLOW_SUBFRAMES: {
742       NS_ENSURE_STATE(mDocShell);
743       NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
744                       aValue == static_cast<uint32_t>(false)),
745                      NS_ERROR_INVALID_ARG);
746       mDocShell->SetAllowSubframes(!!aValue);
747       break;
748     }
749     case nsIWebBrowserSetup::SETUP_ALLOW_IMAGES: {
750       NS_ENSURE_STATE(mDocShell);
751       NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
752                       aValue == static_cast<uint32_t>(false)),
753                      NS_ERROR_INVALID_ARG);
754       mDocShell->SetAllowImages(!!aValue);
755       break;
756     }
757     case nsIWebBrowserSetup::SETUP_ALLOW_DNS_PREFETCH: {
758       NS_ENSURE_STATE(mDocShell);
759       NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
760                       aValue == static_cast<uint32_t>(false)),
761                      NS_ERROR_INVALID_ARG);
762       mDocShell->SetAllowDNSPrefetch(!!aValue);
763       break;
764     }
765     case nsIWebBrowserSetup::SETUP_USE_GLOBAL_HISTORY: {
766       NS_ENSURE_STATE(mDocShell);
767       NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
768                       aValue == static_cast<uint32_t>(false)),
769                      NS_ERROR_INVALID_ARG);
770       rv = EnableGlobalHistory(!!aValue);
771       mShouldEnableHistory = aValue;
772       break;
773     }
774     case nsIWebBrowserSetup::SETUP_FOCUS_DOC_BEFORE_CONTENT: {
775       // obsolete
776       break;
777     }
778     case nsIWebBrowserSetup::SETUP_IS_CHROME_WRAPPER: {
779       NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
780                       aValue == static_cast<uint32_t>(false)),
781                      NS_ERROR_INVALID_ARG);
782       SetItemType(aValue ? static_cast<int32_t>(typeChromeWrapper)
783                          : static_cast<int32_t>(typeContentWrapper));
784       break;
785     }
786     default:
787       rv = NS_ERROR_INVALID_ARG;
788   }
789   return rv;
790 }
791 
792 //*****************************************************************************
793 // nsWebBrowser::nsIWebProgressListener
794 //*****************************************************************************
795 
796 NS_IMETHODIMP
OnStateChange(nsIWebProgress * aWebProgress,nsIRequest * aRequest,uint32_t aStateFlags,nsresult aStatus)797 nsWebBrowser::OnStateChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
798                             uint32_t aStateFlags, nsresult aStatus) {
799   if (mPersist) {
800     mPersist->GetCurrentState(&mPersistCurrentState);
801   }
802   if (aStateFlags & STATE_IS_NETWORK && aStateFlags & STATE_STOP) {
803     mPersist = nullptr;
804   }
805   if (mProgressListener) {
806     return mProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags,
807                                             aStatus);
808   }
809   return NS_OK;
810 }
811 
812 NS_IMETHODIMP
OnProgressChange(nsIWebProgress * aWebProgress,nsIRequest * aRequest,int32_t aCurSelfProgress,int32_t aMaxSelfProgress,int32_t aCurTotalProgress,int32_t aMaxTotalProgress)813 nsWebBrowser::OnProgressChange(nsIWebProgress* aWebProgress,
814                                nsIRequest* aRequest, int32_t aCurSelfProgress,
815                                int32_t aMaxSelfProgress,
816                                int32_t aCurTotalProgress,
817                                int32_t aMaxTotalProgress) {
818   if (mPersist) {
819     mPersist->GetCurrentState(&mPersistCurrentState);
820   }
821   if (mProgressListener) {
822     return mProgressListener->OnProgressChange(
823         aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress,
824         aCurTotalProgress, aMaxTotalProgress);
825   }
826   return NS_OK;
827 }
828 
829 NS_IMETHODIMP
OnLocationChange(nsIWebProgress * aWebProgress,nsIRequest * aRequest,nsIURI * aLocation,uint32_t aFlags)830 nsWebBrowser::OnLocationChange(nsIWebProgress* aWebProgress,
831                                nsIRequest* aRequest, nsIURI* aLocation,
832                                uint32_t aFlags) {
833   if (mProgressListener) {
834     return mProgressListener->OnLocationChange(aWebProgress, aRequest,
835                                                aLocation, aFlags);
836   }
837   return NS_OK;
838 }
839 
840 NS_IMETHODIMP
OnStatusChange(nsIWebProgress * aWebProgress,nsIRequest * aRequest,nsresult aStatus,const char16_t * aMessage)841 nsWebBrowser::OnStatusChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
842                              nsresult aStatus, const char16_t* aMessage) {
843   if (mProgressListener) {
844     return mProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus,
845                                              aMessage);
846   }
847   return NS_OK;
848 }
849 
850 NS_IMETHODIMP
OnSecurityChange(nsIWebProgress * aWebProgress,nsIRequest * aRequest,uint32_t aState)851 nsWebBrowser::OnSecurityChange(nsIWebProgress* aWebProgress,
852                                nsIRequest* aRequest, uint32_t aState) {
853   if (mProgressListener) {
854     return mProgressListener->OnSecurityChange(aWebProgress, aRequest, aState);
855   }
856   return NS_OK;
857 }
858 
859 //*****************************************************************************
860 // nsWebBrowser::nsIWebBrowserPersist
861 //*****************************************************************************
862 
863 NS_IMETHODIMP
GetPersistFlags(uint32_t * aPersistFlags)864 nsWebBrowser::GetPersistFlags(uint32_t* aPersistFlags) {
865   NS_ENSURE_ARG_POINTER(aPersistFlags);
866   nsresult rv = NS_OK;
867   if (mPersist) {
868     rv = mPersist->GetPersistFlags(&mPersistFlags);
869   }
870   *aPersistFlags = mPersistFlags;
871   return rv;
872 }
873 
874 NS_IMETHODIMP
SetPersistFlags(uint32_t aPersistFlags)875 nsWebBrowser::SetPersistFlags(uint32_t aPersistFlags) {
876   nsresult rv = NS_OK;
877   mPersistFlags = aPersistFlags;
878   if (mPersist) {
879     rv = mPersist->SetPersistFlags(mPersistFlags);
880     mPersist->GetPersistFlags(&mPersistFlags);
881   }
882   return rv;
883 }
884 
885 NS_IMETHODIMP
GetCurrentState(uint32_t * aCurrentState)886 nsWebBrowser::GetCurrentState(uint32_t* aCurrentState) {
887   NS_ENSURE_ARG_POINTER(aCurrentState);
888   if (mPersist) {
889     mPersist->GetCurrentState(&mPersistCurrentState);
890   }
891   *aCurrentState = mPersistCurrentState;
892   return NS_OK;
893 }
894 
895 NS_IMETHODIMP
GetResult(nsresult * aResult)896 nsWebBrowser::GetResult(nsresult* aResult) {
897   NS_ENSURE_ARG_POINTER(aResult);
898   if (mPersist) {
899     mPersist->GetResult(&mPersistResult);
900   }
901   *aResult = mPersistResult;
902   return NS_OK;
903 }
904 
905 NS_IMETHODIMP
GetProgressListener(nsIWebProgressListener ** aProgressListener)906 nsWebBrowser::GetProgressListener(nsIWebProgressListener** aProgressListener) {
907   NS_ENSURE_ARG_POINTER(aProgressListener);
908   *aProgressListener = mProgressListener;
909   NS_IF_ADDREF(*aProgressListener);
910   return NS_OK;
911 }
912 
913 NS_IMETHODIMP
SetProgressListener(nsIWebProgressListener * aProgressListener)914 nsWebBrowser::SetProgressListener(nsIWebProgressListener* aProgressListener) {
915   mProgressListener = aProgressListener;
916   return NS_OK;
917 }
918 
919 NS_IMETHODIMP
SaveURI(nsIURI * aURI,nsISupports * aCacheKey,nsIURI * aReferrer,uint32_t aReferrerPolicy,nsIInputStream * aPostData,const char * aExtraHeaders,nsISupports * aFile,nsILoadContext * aPrivacyContext)920 nsWebBrowser::SaveURI(nsIURI* aURI, nsISupports* aCacheKey, nsIURI* aReferrer,
921                       uint32_t aReferrerPolicy, nsIInputStream* aPostData,
922                       const char* aExtraHeaders, nsISupports* aFile,
923                       nsILoadContext* aPrivacyContext) {
924   return SavePrivacyAwareURI(
925       aURI, aCacheKey, aReferrer, aReferrerPolicy, aPostData, aExtraHeaders,
926       aFile, aPrivacyContext && aPrivacyContext->UsePrivateBrowsing());
927 }
928 
929 NS_IMETHODIMP
SavePrivacyAwareURI(nsIURI * aURI,nsISupports * aCacheKey,nsIURI * aReferrer,uint32_t aReferrerPolicy,nsIInputStream * aPostData,const char * aExtraHeaders,nsISupports * aFile,bool aIsPrivate)930 nsWebBrowser::SavePrivacyAwareURI(nsIURI* aURI, nsISupports* aCacheKey,
931                                   nsIURI* aReferrer, uint32_t aReferrerPolicy,
932                                   nsIInputStream* aPostData,
933                                   const char* aExtraHeaders, nsISupports* aFile,
934                                   bool aIsPrivate) {
935   if (mPersist) {
936     uint32_t currentState;
937     mPersist->GetCurrentState(&currentState);
938     if (currentState == PERSIST_STATE_FINISHED) {
939       mPersist = nullptr;
940     } else {
941       // You can't save again until the last save has completed
942       return NS_ERROR_FAILURE;
943     }
944   }
945 
946   nsCOMPtr<nsIURI> uri;
947   if (aURI) {
948     uri = aURI;
949   } else {
950     nsresult rv = GetCurrentURI(getter_AddRefs(uri));
951     if (NS_FAILED(rv)) {
952       return NS_ERROR_FAILURE;
953     }
954   }
955 
956   // Create a throwaway persistence object to do the work
957   nsresult rv;
958   mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
959   NS_ENSURE_SUCCESS(rv, rv);
960   mPersist->SetProgressListener(this);
961   mPersist->SetPersistFlags(mPersistFlags);
962   mPersist->GetCurrentState(&mPersistCurrentState);
963 
964   rv = mPersist->SavePrivacyAwareURI(uri, aCacheKey, aReferrer, aReferrerPolicy,
965                                      aPostData, aExtraHeaders, aFile,
966                                      aIsPrivate);
967   if (NS_FAILED(rv)) {
968     mPersist = nullptr;
969   }
970   return rv;
971 }
972 
973 NS_IMETHODIMP
SaveChannel(nsIChannel * aChannel,nsISupports * aFile)974 nsWebBrowser::SaveChannel(nsIChannel* aChannel, nsISupports* aFile) {
975   if (mPersist) {
976     uint32_t currentState;
977     mPersist->GetCurrentState(&currentState);
978     if (currentState == PERSIST_STATE_FINISHED) {
979       mPersist = nullptr;
980     } else {
981       // You can't save again until the last save has completed
982       return NS_ERROR_FAILURE;
983     }
984   }
985 
986   // Create a throwaway persistence object to do the work
987   nsresult rv;
988   mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
989   NS_ENSURE_SUCCESS(rv, rv);
990   mPersist->SetProgressListener(this);
991   mPersist->SetPersistFlags(mPersistFlags);
992   mPersist->GetCurrentState(&mPersistCurrentState);
993   rv = mPersist->SaveChannel(aChannel, aFile);
994   if (NS_FAILED(rv)) {
995     mPersist = nullptr;
996   }
997   return rv;
998 }
999 
1000 NS_IMETHODIMP
SaveDocument(nsISupports * aDocumentish,nsISupports * aFile,nsISupports * aDataPath,const char * aOutputContentType,uint32_t aEncodingFlags,uint32_t aWrapColumn)1001 nsWebBrowser::SaveDocument(nsISupports* aDocumentish, nsISupports* aFile,
1002                            nsISupports* aDataPath,
1003                            const char* aOutputContentType,
1004                            uint32_t aEncodingFlags, uint32_t aWrapColumn) {
1005   if (mPersist) {
1006     uint32_t currentState;
1007     mPersist->GetCurrentState(&currentState);
1008     if (currentState == PERSIST_STATE_FINISHED) {
1009       mPersist = nullptr;
1010     } else {
1011       // You can't save again until the last save has completed
1012       return NS_ERROR_FAILURE;
1013     }
1014   }
1015 
1016   // Use the specified DOM document, or if none is specified, the one
1017   // attached to the web browser.
1018 
1019   nsCOMPtr<nsISupports> doc;
1020   if (aDocumentish) {
1021     doc = aDocumentish;
1022   } else {
1023     nsCOMPtr<nsIDOMDocument> domDoc;
1024     GetDocument(getter_AddRefs(domDoc));
1025     doc = domDoc.forget();
1026   }
1027   if (!doc) {
1028     return NS_ERROR_FAILURE;
1029   }
1030 
1031   // Create a throwaway persistence object to do the work
1032   nsresult rv;
1033   mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
1034   NS_ENSURE_SUCCESS(rv, rv);
1035   mPersist->SetProgressListener(this);
1036   mPersist->SetPersistFlags(mPersistFlags);
1037   mPersist->GetCurrentState(&mPersistCurrentState);
1038   rv = mPersist->SaveDocument(doc, aFile, aDataPath, aOutputContentType,
1039                               aEncodingFlags, aWrapColumn);
1040   if (NS_FAILED(rv)) {
1041     mPersist = nullptr;
1042   }
1043   return rv;
1044 }
1045 
1046 NS_IMETHODIMP
CancelSave()1047 nsWebBrowser::CancelSave() {
1048   if (mPersist) {
1049     return mPersist->CancelSave();
1050   }
1051   return NS_OK;
1052 }
1053 
1054 NS_IMETHODIMP
Cancel(nsresult aReason)1055 nsWebBrowser::Cancel(nsresult aReason) {
1056   if (mPersist) {
1057     return mPersist->Cancel(aReason);
1058   }
1059   return NS_OK;
1060 }
1061 
1062 //*****************************************************************************
1063 // nsWebBrowser::nsIBaseWindow
1064 //*****************************************************************************
1065 
1066 NS_IMETHODIMP
InitWindow(nativeWindow aParentNativeWindow,nsIWidget * aParentWidget,int32_t aX,int32_t aY,int32_t aCX,int32_t aCY)1067 nsWebBrowser::InitWindow(nativeWindow aParentNativeWindow,
1068                          nsIWidget* aParentWidget, int32_t aX, int32_t aY,
1069                          int32_t aCX, int32_t aCY) {
1070   NS_ENSURE_ARG(aParentNativeWindow || aParentWidget);
1071   NS_ENSURE_STATE(!mDocShell || mInitInfo);
1072 
1073   if (aParentWidget) {
1074     NS_ENSURE_SUCCESS(SetParentWidget(aParentWidget), NS_ERROR_FAILURE);
1075   } else
1076     NS_ENSURE_SUCCESS(SetParentNativeWindow(aParentNativeWindow),
1077                       NS_ERROR_FAILURE);
1078 
1079   NS_ENSURE_SUCCESS(SetPositionAndSize(aX, aY, aCX, aCY, 0), NS_ERROR_FAILURE);
1080 
1081   return NS_OK;
1082 }
1083 
1084 NS_IMETHODIMP
Create()1085 nsWebBrowser::Create() {
1086   NS_ENSURE_STATE(!mDocShell && (mParentNativeWindow || mParentWidget));
1087 
1088   nsresult rv = EnsureDocShellTreeOwner();
1089   NS_ENSURE_SUCCESS(rv, rv);
1090 
1091   nsCOMPtr<nsIWidget> docShellParentWidget(mParentWidget);
1092   if (!mParentWidget) {
1093     // Create the widget
1094     mInternalWidget = do_CreateInstance(kChildCID, &rv);
1095     NS_ENSURE_SUCCESS(rv, rv);
1096 
1097     docShellParentWidget = mInternalWidget;
1098     nsWidgetInitData widgetInit;
1099 
1100     widgetInit.clipChildren = true;
1101 
1102     widgetInit.mWindowType = eWindowType_child;
1103     LayoutDeviceIntRect bounds(mInitInfo->x, mInitInfo->y, mInitInfo->cx,
1104                                mInitInfo->cy);
1105 
1106     mInternalWidget->SetWidgetListener(&mWidgetListenerDelegate);
1107     rv = mInternalWidget->Create(nullptr, mParentNativeWindow, bounds,
1108                                  &widgetInit);
1109     NS_ENSURE_SUCCESS(rv, rv);
1110   }
1111 
1112   nsCOMPtr<nsIDocShell> docShell(
1113       do_CreateInstance("@mozilla.org/docshell;1", &rv));
1114   NS_ENSURE_SUCCESS(rv, rv);
1115   nsDocShell::Cast(docShell)->SetOriginAttributes(mOriginAttributes);
1116   rv = SetDocShell(docShell);
1117   NS_ENSURE_SUCCESS(rv, rv);
1118 
1119   // get the system default window background colour
1120   LookAndFeel::GetColor(LookAndFeel::eColorID_WindowBackground,
1121                         &mBackgroundColor);
1122 
1123   // the docshell has been set so we now have our listener registrars.
1124   if (mListenerArray) {
1125     // we had queued up some listeners, let's register them now.
1126     uint32_t count = mListenerArray->Length();
1127     uint32_t i = 0;
1128     NS_ASSERTION(count > 0, "array construction problem");
1129     while (i < count) {
1130       nsWebBrowserListenerState& state = mListenerArray->ElementAt(i);
1131       nsCOMPtr<nsISupports> listener = do_QueryReferent(state.mWeakPtr);
1132       NS_ASSERTION(listener, "bad listener");
1133       (void)BindListener(listener, state.mID);
1134       i++;
1135     }
1136     mListenerArray = nullptr;
1137   }
1138 
1139   // HACK ALERT - this registration registers the nsDocShellTreeOwner as a
1140   // nsIWebBrowserListener so it can setup its MouseListener in one of the
1141   // progress callbacks. If we can register the MouseListener another way, this
1142   // registration can go away, and nsDocShellTreeOwner can stop implementing
1143   // nsIWebProgressListener.
1144   nsCOMPtr<nsISupports> supports = nullptr;
1145   (void)mDocShellTreeOwner->QueryInterface(
1146       NS_GET_IID(nsIWebProgressListener),
1147       static_cast<void**>(getter_AddRefs(supports)));
1148   (void)BindListener(supports, NS_GET_IID(nsIWebProgressListener));
1149 
1150   NS_ENSURE_SUCCESS(
1151       mDocShellAsWin->InitWindow(nullptr, docShellParentWidget, mInitInfo->x,
1152                                  mInitInfo->y, mInitInfo->cx, mInitInfo->cy),
1153       NS_ERROR_FAILURE);
1154 
1155   mDocShell->SetName(mInitInfo->name);
1156   if (mContentType == typeChromeWrapper) {
1157     mDocShell->SetItemType(nsIDocShellTreeItem::typeChrome);
1158   } else {
1159     mDocShell->SetItemType(nsIDocShellTreeItem::typeContent);
1160   }
1161   mDocShell->SetTreeOwner(mDocShellTreeOwner);
1162 
1163   // If the webbrowser is a content docshell item then we won't hear any
1164   // events from subframes. To solve that we install our own chrome event
1165   // handler that always gets called (even for subframes) for any bubbling
1166   // event.
1167 
1168   if (!mInitInfo->sessionHistory) {
1169     mInitInfo->sessionHistory = do_CreateInstance(NS_SHISTORY_CONTRACTID, &rv);
1170     NS_ENSURE_SUCCESS(rv, rv);
1171   }
1172   mDocShellAsNav->SetSessionHistory(mInitInfo->sessionHistory);
1173 
1174   if (XRE_IsParentProcess()) {
1175     // Hook up global history. Do not fail if we can't - just warn.
1176     rv = EnableGlobalHistory(mShouldEnableHistory);
1177     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "EnableGlobalHistory() failed");
1178   }
1179 
1180   NS_ENSURE_SUCCESS(mDocShellAsWin->Create(), NS_ERROR_FAILURE);
1181 
1182   // Hook into the OnSecurityChange() notification for lock/unlock icon
1183   // updates
1184   nsCOMPtr<mozIDOMWindowProxy> domWindow;
1185   rv = GetContentDOMWindow(getter_AddRefs(domWindow));
1186   if (NS_SUCCEEDED(rv)) {
1187     // this works because the implementation of nsISecureBrowserUI
1188     // (nsSecureBrowserUIImpl) gets a docShell from the domWindow,
1189     // and calls docShell->SetSecurityUI(this);
1190     nsCOMPtr<nsISecureBrowserUI> securityUI =
1191         do_CreateInstance(NS_SECURE_BROWSER_UI_CONTRACTID, &rv);
1192     if (NS_SUCCEEDED(rv)) {
1193       securityUI->Init(domWindow);
1194     }
1195   }
1196 
1197   mDocShellTreeOwner->AddToWatcher();  // evil twin of Remove in SetDocShell(0)
1198   mDocShellTreeOwner->AddChromeListeners();
1199 
1200   mInitInfo = nullptr;
1201 
1202   return NS_OK;
1203 }
1204 
1205 NS_IMETHODIMP
Destroy()1206 nsWebBrowser::Destroy() {
1207   InternalDestroy();
1208 
1209   if (!mInitInfo) {
1210     mInitInfo = new nsWebBrowserInitInfo();
1211   }
1212 
1213   return NS_OK;
1214 }
1215 
1216 NS_IMETHODIMP
GetUnscaledDevicePixelsPerCSSPixel(double * aScale)1217 nsWebBrowser::GetUnscaledDevicePixelsPerCSSPixel(double* aScale) {
1218   *aScale = mParentWidget ? mParentWidget->GetDefaultScale().scale : 1.0;
1219   return NS_OK;
1220 }
1221 
1222 NS_IMETHODIMP
GetDevicePixelsPerDesktopPixel(double * aScale)1223 nsWebBrowser::GetDevicePixelsPerDesktopPixel(double* aScale) {
1224   *aScale =
1225       mParentWidget ? mParentWidget->GetDesktopToDeviceScale().scale : 1.0;
1226   return NS_OK;
1227 }
1228 
1229 NS_IMETHODIMP
SetPositionDesktopPix(int32_t aX,int32_t aY)1230 nsWebBrowser::SetPositionDesktopPix(int32_t aX, int32_t aY) {
1231   // XXX jfkthame
1232   // It's not clear to me whether this will be fully correct across
1233   // potential multi-screen, mixed-DPI configurations for all platforms;
1234   // we might need to add code paths that make it possible to pass the
1235   // desktop-pix parameters all the way through to the native widget,
1236   // to avoid the risk of device-pixel coords mapping to the wrong
1237   // display on OS X with mixed retina/non-retina screens.
1238   double scale = 1.0;
1239   GetDevicePixelsPerDesktopPixel(&scale);
1240   return SetPosition(NSToIntRound(aX * scale), NSToIntRound(aY * scale));
1241 }
1242 
1243 NS_IMETHODIMP
SetPosition(int32_t aX,int32_t aY)1244 nsWebBrowser::SetPosition(int32_t aX, int32_t aY) {
1245   int32_t cx = 0;
1246   int32_t cy = 0;
1247 
1248   GetSize(&cx, &cy);
1249 
1250   return SetPositionAndSize(aX, aY, cx, cy, 0);
1251 }
1252 
1253 NS_IMETHODIMP
GetPosition(int32_t * aX,int32_t * aY)1254 nsWebBrowser::GetPosition(int32_t* aX, int32_t* aY) {
1255   return GetPositionAndSize(aX, aY, nullptr, nullptr);
1256 }
1257 
1258 NS_IMETHODIMP
SetSize(int32_t aCX,int32_t aCY,bool aRepaint)1259 nsWebBrowser::SetSize(int32_t aCX, int32_t aCY, bool aRepaint) {
1260   int32_t x = 0;
1261   int32_t y = 0;
1262 
1263   GetPosition(&x, &y);
1264 
1265   return SetPositionAndSize(x, y, aCX, aCY,
1266                             aRepaint ? nsIBaseWindow::eRepaint : 0);
1267 }
1268 
1269 NS_IMETHODIMP
GetSize(int32_t * aCX,int32_t * aCY)1270 nsWebBrowser::GetSize(int32_t* aCX, int32_t* aCY) {
1271   return GetPositionAndSize(nullptr, nullptr, aCX, aCY);
1272 }
1273 
1274 NS_IMETHODIMP
SetPositionAndSize(int32_t aX,int32_t aY,int32_t aCX,int32_t aCY,uint32_t aFlags)1275 nsWebBrowser::SetPositionAndSize(int32_t aX, int32_t aY, int32_t aCX,
1276                                  int32_t aCY, uint32_t aFlags) {
1277   if (!mDocShell) {
1278     mInitInfo->x = aX;
1279     mInitInfo->y = aY;
1280     mInitInfo->cx = aCX;
1281     mInitInfo->cy = aCY;
1282   } else {
1283     int32_t doc_x = aX;
1284     int32_t doc_y = aY;
1285 
1286     // If there is an internal widget we need to make the docShell coordinates
1287     // relative to the internal widget rather than the calling app's parent.
1288     // We also need to resize our widget then.
1289     if (mInternalWidget) {
1290       doc_x = doc_y = 0;
1291       mInternalWidget->Resize(aX, aY, aCX, aCY,
1292                               !!(aFlags & nsIBaseWindow::eRepaint));
1293     }
1294     // Now reposition/ resize the doc
1295     NS_ENSURE_SUCCESS(
1296         mDocShellAsWin->SetPositionAndSize(doc_x, doc_y, aCX, aCY, aFlags),
1297         NS_ERROR_FAILURE);
1298   }
1299 
1300   return NS_OK;
1301 }
1302 
1303 NS_IMETHODIMP
GetPositionAndSize(int32_t * aX,int32_t * aY,int32_t * aCX,int32_t * aCY)1304 nsWebBrowser::GetPositionAndSize(int32_t* aX, int32_t* aY, int32_t* aCX,
1305                                  int32_t* aCY) {
1306   if (!mDocShell) {
1307     if (aX) {
1308       *aX = mInitInfo->x;
1309     }
1310     if (aY) {
1311       *aY = mInitInfo->y;
1312     }
1313     if (aCX) {
1314       *aCX = mInitInfo->cx;
1315     }
1316     if (aCY) {
1317       *aCY = mInitInfo->cy;
1318     }
1319   } else if (mInternalWidget) {
1320     LayoutDeviceIntRect bounds = mInternalWidget->GetBounds();
1321 
1322     if (aX) {
1323       *aX = bounds.X();
1324     }
1325     if (aY) {
1326       *aY = bounds.Y();
1327     }
1328     if (aCX) {
1329       *aCX = bounds.Width();
1330     }
1331     if (aCY) {
1332       *aCY = bounds.Height();
1333     }
1334     return NS_OK;
1335   } else {
1336     // Can directly return this as it is the
1337     // same interface, thus same returns.
1338     return mDocShellAsWin->GetPositionAndSize(aX, aY, aCX, aCY);
1339   }
1340   return NS_OK;
1341 }
1342 
1343 NS_IMETHODIMP
Repaint(bool aForce)1344 nsWebBrowser::Repaint(bool aForce) {
1345   NS_ENSURE_STATE(mDocShell);
1346   // Can directly return this as it is the
1347   // same interface, thus same returns.
1348   return mDocShellAsWin->Repaint(aForce);
1349 }
1350 
1351 NS_IMETHODIMP
GetParentWidget(nsIWidget ** aParentWidget)1352 nsWebBrowser::GetParentWidget(nsIWidget** aParentWidget) {
1353   NS_ENSURE_ARG_POINTER(aParentWidget);
1354 
1355   *aParentWidget = mParentWidget;
1356 
1357   NS_IF_ADDREF(*aParentWidget);
1358 
1359   return NS_OK;
1360 }
1361 
1362 NS_IMETHODIMP
SetParentWidget(nsIWidget * aParentWidget)1363 nsWebBrowser::SetParentWidget(nsIWidget* aParentWidget) {
1364   NS_ENSURE_STATE(!mDocShell);
1365 
1366   mParentWidget = aParentWidget;
1367   if (mParentWidget) {
1368     mParentNativeWindow = mParentWidget->GetNativeData(NS_NATIVE_WIDGET);
1369   } else {
1370     mParentNativeWindow = nullptr;
1371   }
1372 
1373   return NS_OK;
1374 }
1375 
1376 NS_IMETHODIMP
GetParentNativeWindow(nativeWindow * aParentNativeWindow)1377 nsWebBrowser::GetParentNativeWindow(nativeWindow* aParentNativeWindow) {
1378   NS_ENSURE_ARG_POINTER(aParentNativeWindow);
1379 
1380   *aParentNativeWindow = mParentNativeWindow;
1381 
1382   return NS_OK;
1383 }
1384 
1385 NS_IMETHODIMP
SetParentNativeWindow(nativeWindow aParentNativeWindow)1386 nsWebBrowser::SetParentNativeWindow(nativeWindow aParentNativeWindow) {
1387   NS_ENSURE_STATE(!mDocShell);
1388 
1389   mParentNativeWindow = aParentNativeWindow;
1390 
1391   return NS_OK;
1392 }
1393 
1394 NS_IMETHODIMP
GetNativeHandle(nsAString & aNativeHandle)1395 nsWebBrowser::GetNativeHandle(nsAString& aNativeHandle) {
1396   // the nativeHandle should be accessed from nsIXULWindow
1397   return NS_ERROR_NOT_IMPLEMENTED;
1398 }
1399 
1400 NS_IMETHODIMP
GetVisibility(bool * aVisibility)1401 nsWebBrowser::GetVisibility(bool* aVisibility) {
1402   NS_ENSURE_ARG_POINTER(aVisibility);
1403 
1404   if (!mDocShell) {
1405     *aVisibility = mInitInfo->visible;
1406   } else {
1407     NS_ENSURE_SUCCESS(mDocShellAsWin->GetVisibility(aVisibility),
1408                       NS_ERROR_FAILURE);
1409   }
1410 
1411   return NS_OK;
1412 }
1413 
1414 NS_IMETHODIMP
SetVisibility(bool aVisibility)1415 nsWebBrowser::SetVisibility(bool aVisibility) {
1416   if (!mDocShell) {
1417     mInitInfo->visible = aVisibility;
1418   } else {
1419     NS_ENSURE_SUCCESS(mDocShellAsWin->SetVisibility(aVisibility),
1420                       NS_ERROR_FAILURE);
1421     if (mInternalWidget) {
1422       mInternalWidget->Show(aVisibility);
1423     }
1424   }
1425 
1426   return NS_OK;
1427 }
1428 
1429 NS_IMETHODIMP
GetEnabled(bool * aEnabled)1430 nsWebBrowser::GetEnabled(bool* aEnabled) {
1431   if (mInternalWidget) {
1432     *aEnabled = mInternalWidget->IsEnabled();
1433     return NS_OK;
1434   }
1435 
1436   return NS_ERROR_FAILURE;
1437 }
1438 
1439 NS_IMETHODIMP
SetEnabled(bool aEnabled)1440 nsWebBrowser::SetEnabled(bool aEnabled) {
1441   if (mInternalWidget) {
1442     mInternalWidget->Enable(aEnabled);
1443     return NS_OK;
1444   }
1445   return NS_ERROR_FAILURE;
1446 }
1447 
1448 NS_IMETHODIMP
GetMainWidget(nsIWidget ** aMainWidget)1449 nsWebBrowser::GetMainWidget(nsIWidget** aMainWidget) {
1450   NS_ENSURE_ARG_POINTER(aMainWidget);
1451 
1452   if (mInternalWidget) {
1453     *aMainWidget = mInternalWidget;
1454   } else {
1455     *aMainWidget = mParentWidget;
1456   }
1457 
1458   NS_IF_ADDREF(*aMainWidget);
1459 
1460   return NS_OK;
1461 }
1462 
1463 NS_IMETHODIMP
SetFocus()1464 nsWebBrowser::SetFocus() {
1465   nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
1466   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
1467 
1468   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1469   return fm ? fm->SetFocusedWindow(window) : NS_OK;
1470 }
1471 
1472 NS_IMETHODIMP
GetTitle(nsAString & aTitle)1473 nsWebBrowser::GetTitle(nsAString& aTitle) {
1474   NS_ENSURE_STATE(mDocShell);
1475 
1476   NS_ENSURE_SUCCESS(mDocShellAsWin->GetTitle(aTitle), NS_ERROR_FAILURE);
1477 
1478   return NS_OK;
1479 }
1480 
1481 NS_IMETHODIMP
SetTitle(const nsAString & aTitle)1482 nsWebBrowser::SetTitle(const nsAString& aTitle) {
1483   NS_ENSURE_STATE(mDocShell);
1484 
1485   NS_ENSURE_SUCCESS(mDocShellAsWin->SetTitle(aTitle), NS_ERROR_FAILURE);
1486 
1487   return NS_OK;
1488 }
1489 
1490 //*****************************************************************************
1491 // nsWebBrowser::nsIScrollable
1492 //*****************************************************************************
1493 
1494 NS_IMETHODIMP
GetDefaultScrollbarPreferences(int32_t aScrollOrientation,int32_t * aScrollbarPref)1495 nsWebBrowser::GetDefaultScrollbarPreferences(int32_t aScrollOrientation,
1496                                              int32_t* aScrollbarPref) {
1497   NS_ENSURE_STATE(mDocShell);
1498 
1499   return mDocShellAsScrollable->GetDefaultScrollbarPreferences(
1500       aScrollOrientation, aScrollbarPref);
1501 }
1502 
1503 NS_IMETHODIMP
SetDefaultScrollbarPreferences(int32_t aScrollOrientation,int32_t aScrollbarPref)1504 nsWebBrowser::SetDefaultScrollbarPreferences(int32_t aScrollOrientation,
1505                                              int32_t aScrollbarPref) {
1506   NS_ENSURE_STATE(mDocShell);
1507 
1508   return mDocShellAsScrollable->SetDefaultScrollbarPreferences(
1509       aScrollOrientation, aScrollbarPref);
1510 }
1511 
1512 NS_IMETHODIMP
GetScrollbarVisibility(bool * aVerticalVisible,bool * aHorizontalVisible)1513 nsWebBrowser::GetScrollbarVisibility(bool* aVerticalVisible,
1514                                      bool* aHorizontalVisible) {
1515   NS_ENSURE_STATE(mDocShell);
1516 
1517   return mDocShellAsScrollable->GetScrollbarVisibility(aVerticalVisible,
1518                                                        aHorizontalVisible);
1519 }
1520 
1521 //*****************************************************************************
1522 // nsWebBrowser::nsITextScroll
1523 //*****************************************************************************
1524 
1525 NS_IMETHODIMP
ScrollByLines(int32_t aNumLines)1526 nsWebBrowser::ScrollByLines(int32_t aNumLines) {
1527   NS_ENSURE_STATE(mDocShell);
1528 
1529   return mDocShellAsTextScroll->ScrollByLines(aNumLines);
1530 }
1531 
1532 NS_IMETHODIMP
ScrollByPages(int32_t aNumPages)1533 nsWebBrowser::ScrollByPages(int32_t aNumPages) {
1534   NS_ENSURE_STATE(mDocShell);
1535 
1536   return mDocShellAsTextScroll->ScrollByPages(aNumPages);
1537 }
1538 
1539 //*****************************************************************************
1540 // nsWebBrowser: Listener Helpers
1541 //*****************************************************************************
1542 
1543 NS_IMETHODIMP
SetDocShell(nsIDocShell * aDocShell)1544 nsWebBrowser::SetDocShell(nsIDocShell* aDocShell) {
1545   // We need to keep the docshell alive while we perform the changes, but we
1546   // don't need to call any methods on it.
1547   nsCOMPtr<nsIDocShell> kungFuDeathGrip(mDocShell);
1548   mozilla::Unused << kungFuDeathGrip;
1549 
1550   if (aDocShell) {
1551     NS_ENSURE_TRUE(!mDocShell, NS_ERROR_FAILURE);
1552 
1553     nsCOMPtr<nsIInterfaceRequestor> req(do_QueryInterface(aDocShell));
1554     nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(aDocShell));
1555     nsCOMPtr<nsIWebNavigation> nav(do_QueryInterface(aDocShell));
1556     nsCOMPtr<nsIScrollable> scrollable(do_QueryInterface(aDocShell));
1557     nsCOMPtr<nsITextScroll> textScroll(do_QueryInterface(aDocShell));
1558     nsCOMPtr<nsIWebProgress> progress(do_GetInterface(aDocShell));
1559     NS_ENSURE_TRUE(
1560         req && baseWin && nav && scrollable && textScroll && progress,
1561         NS_ERROR_FAILURE);
1562 
1563     mDocShell = aDocShell;
1564     mDocShellAsReq = req;
1565     mDocShellAsWin = baseWin;
1566     mDocShellAsNav = nav;
1567     mDocShellAsScrollable = scrollable;
1568     mDocShellAsTextScroll = textScroll;
1569     mWebProgress = progress;
1570 
1571     // By default, do not allow DNS prefetch, so we don't break our frozen
1572     // API.  Embeddors who decide to enable it should do so manually.
1573     mDocShell->SetAllowDNSPrefetch(false);
1574 
1575     // It's possible to call setIsActive() on us before we have a docshell.
1576     // If we're getting a docshell now, pass along our desired value. The
1577     // default here (true) matches the default of the docshell, so this is
1578     // a no-op unless setIsActive(false) has been called on us.
1579     mDocShell->SetIsActive(mIsActive);
1580   } else {
1581     if (mDocShellTreeOwner) {
1582       mDocShellTreeOwner->RemoveFromWatcher();  // evil twin of Add in Create()
1583     }
1584     if (mDocShellAsWin) {
1585       mDocShellAsWin->Destroy();
1586     }
1587 
1588     mDocShell = nullptr;
1589     mDocShellAsReq = nullptr;
1590     mDocShellAsWin = nullptr;
1591     mDocShellAsNav = nullptr;
1592     mDocShellAsScrollable = nullptr;
1593     mDocShellAsTextScroll = nullptr;
1594     mWebProgress = nullptr;
1595   }
1596 
1597   return NS_OK;
1598 }
1599 
1600 NS_IMETHODIMP
EnsureDocShellTreeOwner()1601 nsWebBrowser::EnsureDocShellTreeOwner() {
1602   if (mDocShellTreeOwner) {
1603     return NS_OK;
1604   }
1605 
1606   mDocShellTreeOwner = new nsDocShellTreeOwner();
1607   mDocShellTreeOwner->WebBrowser(this);
1608 
1609   return NS_OK;
1610 }
1611 
DrawPaintedLayer(PaintedLayer * aLayer,gfxContext * aContext,const nsIntRegion & aRegionToDraw,const nsIntRegion & aDirtyRegion,DrawRegionClip aClip,const nsIntRegion & aRegionToInvalidate,void * aCallbackData)1612 static void DrawPaintedLayer(PaintedLayer* aLayer, gfxContext* aContext,
1613                              const nsIntRegion& aRegionToDraw,
1614                              const nsIntRegion& aDirtyRegion,
1615                              DrawRegionClip aClip,
1616                              const nsIntRegion& aRegionToInvalidate,
1617                              void* aCallbackData) {
1618   DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
1619 
1620   ColorPattern color(ToDeviceColor(*static_cast<nscolor*>(aCallbackData)));
1621   nsIntRect dirtyRect = aRegionToDraw.GetBounds();
1622   aDrawTarget.FillRect(
1623       Rect(dirtyRect.X(), dirtyRect.Y(), dirtyRect.Width(), dirtyRect.Height()),
1624       color);
1625 }
1626 
WindowActivated()1627 void nsWebBrowser::WindowActivated() {
1628 #if defined(DEBUG_smaug)
1629   nsCOMPtr<nsIDocument> document = mDocShell->GetDocument();
1630   nsAutoString documentURI;
1631   document->GetDocumentURI(documentURI);
1632   printf("nsWebBrowser::NS_ACTIVATE %p %s\n", (void*)this,
1633          NS_ConvertUTF16toUTF8(documentURI).get());
1634 #endif
1635   Activate();
1636 }
1637 
WindowDeactivated()1638 void nsWebBrowser::WindowDeactivated() {
1639 #if defined(DEBUG_smaug)
1640   nsCOMPtr<nsIDocument> document = mDocShell->GetDocument();
1641   nsAutoString documentURI;
1642   document->GetDocumentURI(documentURI);
1643   printf("nsWebBrowser::NS_DEACTIVATE %p %s\n", (void*)this,
1644          NS_ConvertUTF16toUTF8(documentURI).get());
1645 #endif
1646   Deactivate();
1647 }
1648 
PaintWindow(nsIWidget * aWidget,LayoutDeviceIntRegion aRegion)1649 bool nsWebBrowser::PaintWindow(nsIWidget* aWidget,
1650                                LayoutDeviceIntRegion aRegion) {
1651   LayerManager* layerManager = aWidget->GetLayerManager();
1652   NS_ASSERTION(layerManager, "Must be in paint event");
1653 
1654   layerManager->BeginTransaction();
1655   RefPtr<PaintedLayer> root = layerManager->CreatePaintedLayer();
1656   if (root) {
1657     nsIntRect dirtyRect = aRegion.GetBounds().ToUnknownRect();
1658     root->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(dirtyRect));
1659     layerManager->SetRoot(root);
1660   }
1661 
1662   layerManager->EndTransaction(DrawPaintedLayer, &mBackgroundColor);
1663   return true;
1664 }
1665 /*
1666 NS_IMETHODIMP
1667 nsWebBrowser::GetPrimaryContentWindow(mozIDOMWindowProxy** aDOMWindow)
1668 {
1669   *aDOMWindow = nullptr;
1670 
1671   nsCOMPtr<nsIDocShellTreeItem> item;
1672   NS_ENSURE_TRUE(mDocShellTreeOwner, NS_ERROR_FAILURE);
1673   mDocShellTreeOwner->GetPrimaryContentShell(getter_AddRefs(item));
1674   NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
1675 
1676   nsCOMPtr<nsIDocShell> docShell;
1677   docShell = do_QueryInterface(item);
1678   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
1679 
1680   nsCOMPtr<nsPIDOMWindowOuter> domWindow = docShell->GetWindow();
1681   NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
1682 
1683   *aDOMWindow = domWindow;
1684   NS_ADDREF(*aDOMWindow);
1685   return NS_OK;
1686 }
1687 */
1688 //*****************************************************************************
1689 // nsWebBrowser::nsIWebBrowserFocus
1690 //*****************************************************************************
1691 
1692 NS_IMETHODIMP
Activate(void)1693 nsWebBrowser::Activate(void) {
1694   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1695   nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
1696   if (fm && window) {
1697     return fm->WindowRaised(window);
1698   }
1699   return NS_OK;
1700 }
1701 
1702 NS_IMETHODIMP
Deactivate(void)1703 nsWebBrowser::Deactivate(void) {
1704   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1705   nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
1706   if (fm && window) {
1707     return fm->WindowLowered(window);
1708   }
1709   return NS_OK;
1710 }
1711 
1712 NS_IMETHODIMP
SetFocusAtFirstElement(void)1713 nsWebBrowser::SetFocusAtFirstElement(void) { return NS_OK; }
1714 
1715 NS_IMETHODIMP
SetFocusAtLastElement(void)1716 nsWebBrowser::SetFocusAtLastElement(void) { return NS_OK; }
1717 
1718 NS_IMETHODIMP
GetFocusedWindow(mozIDOMWindowProxy ** aFocusedWindow)1719 nsWebBrowser::GetFocusedWindow(mozIDOMWindowProxy** aFocusedWindow) {
1720   NS_ENSURE_ARG_POINTER(aFocusedWindow);
1721   *aFocusedWindow = nullptr;
1722 
1723   NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
1724 
1725   nsCOMPtr<nsPIDOMWindowOuter> window = mDocShell->GetWindow();
1726   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
1727 
1728   nsCOMPtr<nsIDOMElement> focusedElement;
1729   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1730   return fm ? fm->GetFocusedElementForWindow(window, true, aFocusedWindow,
1731                                              getter_AddRefs(focusedElement))
1732             : NS_OK;
1733 }
1734 
1735 NS_IMETHODIMP
SetFocusedWindow(mozIDOMWindowProxy * aFocusedWindow)1736 nsWebBrowser::SetFocusedWindow(mozIDOMWindowProxy* aFocusedWindow) {
1737   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1738   return fm ? fm->SetFocusedWindow(aFocusedWindow) : NS_OK;
1739 }
1740 
1741 NS_IMETHODIMP
GetFocusedElement(nsIDOMElement ** aFocusedElement)1742 nsWebBrowser::GetFocusedElement(nsIDOMElement** aFocusedElement) {
1743   NS_ENSURE_ARG_POINTER(aFocusedElement);
1744   NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
1745 
1746   nsCOMPtr<nsPIDOMWindowOuter> window = mDocShell->GetWindow();
1747   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
1748 
1749   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1750   return fm ? fm->GetFocusedElementForWindow(window, true, nullptr,
1751                                              aFocusedElement)
1752             : NS_OK;
1753 }
1754 
1755 NS_IMETHODIMP
SetFocusedElement(nsIDOMElement * aFocusedElement)1756 nsWebBrowser::SetFocusedElement(nsIDOMElement* aFocusedElement) {
1757   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1758   return fm ? fm->SetFocus(aFocusedElement, 0) : NS_OK;
1759 }
1760 
WindowActivated()1761 void nsWebBrowser::WidgetListenerDelegate::WindowActivated() {
1762   RefPtr<nsWebBrowser> holder = mWebBrowser;
1763   holder->WindowActivated();
1764 }
1765 
WindowDeactivated()1766 void nsWebBrowser::WidgetListenerDelegate::WindowDeactivated() {
1767   RefPtr<nsWebBrowser> holder = mWebBrowser;
1768   holder->WindowDeactivated();
1769 }
1770 
PaintWindow(nsIWidget * aWidget,mozilla::LayoutDeviceIntRegion aRegion)1771 bool nsWebBrowser::WidgetListenerDelegate::PaintWindow(
1772     nsIWidget* aWidget, mozilla::LayoutDeviceIntRegion aRegion) {
1773   RefPtr<nsWebBrowser> holder = mWebBrowser;
1774   return holder->PaintWindow(aWidget, aRegion);
1775 }
1776