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