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/. */
8 #include "nsWebBrowser.h"
11 #include "nsGfxCIID.h"
12 #include "nsWidgetsCID.h"
15 #include "mozilla/gfx/2D.h"
18 #include "gfxContext.h"
19 #include "nsReadableUtils.h"
20 #include "nsIInterfaceRequestor.h"
21 #include "nsIInterfaceRequestorUtils.h"
22 #include "nsIWebBrowserChrome.h"
23 #include "nsPIDOMWindow.h"
24 #include "nsIWebProgress.h"
25 #include "nsIWebProgressListener.h"
27 #include "nsIWebBrowserPersist.h"
28 #include "nsFocusManager.h"
29 #include "nsILoadContext.h"
30 #include "nsComponentManagerUtils.h"
31 #include "nsDocShell.h"
32 #include "nsServiceManagerUtils.h"
33 #include "WindowRenderer.h"
35 #include "mozilla/dom/Element.h"
36 #include "mozilla/dom/BrowsingContext.h"
37 #include "mozilla/dom/LoadURIOptionsBinding.h"
38 #include "mozilla/dom/WindowGlobalChild.h"
40 // for painting the background window
41 #include "mozilla/LookAndFeel.h"
42 #include "mozilla/ServoStyleConsts.h"
46 # include "nsIWebBrowserPrint.h"
47 # include "nsIDocumentViewer.h"
51 #include "nsISecureBrowserUI.h"
52 #include "nsXULAppAPI.h"
54 using namespace mozilla
;
55 using namespace mozilla::gfx
;
56 using namespace mozilla::layers
;
58 nsWebBrowser::nsWebBrowser(int aItemType
)
59 : mContentType(aItemType
),
60 mShouldEnableHistory(true),
61 mWillChangeProcess(false),
62 mParentNativeWindow(nullptr),
63 mProgressListener(nullptr),
64 mWidgetListenerDelegate(this),
66 mPersistCurrentState(nsIWebBrowserPersist::PERSIST_STATE_READY
),
67 mPersistResult(NS_OK
),
68 mPersistFlags(nsIWebBrowserPersist::PERSIST_FLAGS_NONE
),
69 mParentWidget(nullptr) {
70 mWWatch
= do_GetService(NS_WINDOWWATCHER_CONTRACTID
);
71 NS_ASSERTION(mWWatch
, "failed to get WindowWatcher");
74 nsWebBrowser::~nsWebBrowser() { InternalDestroy(); }
76 nsIWidget
* nsWebBrowser::EnsureWidget() {
81 mInternalWidget
= nsIWidget::CreateChildWindow();
82 if (NS_WARN_IF(!mInternalWidget
)) {
86 widget::InitData widgetInit
;
87 widgetInit
.mClipChildren
= true;
88 widgetInit
.mWindowType
= widget::WindowType::Child
;
89 LayoutDeviceIntRect
bounds(0, 0, 0, 0);
91 mInternalWidget
->SetWidgetListener(&mWidgetListenerDelegate
);
92 NS_ENSURE_SUCCESS(mInternalWidget
->Create(nullptr, mParentNativeWindow
,
96 return mInternalWidget
;
100 already_AddRefed
<nsWebBrowser
> nsWebBrowser::Create(
101 nsIWebBrowserChrome
* aContainerWindow
, nsIWidget
* aParentWidget
,
102 dom::BrowsingContext
* aBrowsingContext
,
103 dom::WindowGlobalChild
* aInitialWindowChild
) {
104 MOZ_ASSERT_IF(aInitialWindowChild
,
105 aInitialWindowChild
->BrowsingContext() == aBrowsingContext
);
107 RefPtr
<nsWebBrowser
> browser
= new nsWebBrowser(
108 aBrowsingContext
->IsContent() ? typeContentWrapper
: typeChromeWrapper
);
110 // nsWebBrowser::SetContainer also calls nsWebBrowser::EnsureDocShellTreeOwner
111 NS_ENSURE_SUCCESS(browser
->SetContainerWindow(aContainerWindow
), nullptr);
112 NS_ENSURE_SUCCESS(browser
->SetParentWidget(aParentWidget
), nullptr);
114 nsCOMPtr
<nsIWidget
> docShellParentWidget
= browser
->EnsureWidget();
115 if (NS_WARN_IF(!docShellParentWidget
)) {
119 uint64_t outerWindowId
=
120 aInitialWindowChild
? aInitialWindowChild
->OuterWindowId() : 0;
122 RefPtr
<nsDocShell
> docShell
=
123 nsDocShell::Create(aBrowsingContext
, outerWindowId
);
124 if (NS_WARN_IF(!docShell
)) {
127 browser
->SetDocShell(docShell
);
128 MOZ_ASSERT(browser
->mDocShell
== docShell
);
130 // get the system default window background colour
132 // TODO(emilio): Can we get the color-scheme from somewhere here?
133 browser
->mBackgroundColor
=
134 LookAndFeel::Color(LookAndFeel::ColorID::Window
, ColorScheme::Light
,
135 LookAndFeel::UseStandins::No
);
137 // HACK ALERT - this registration registers the nsDocShellTreeOwner as a
138 // nsIWebBrowserListener so it can setup its MouseListener in one of the
139 // progress callbacks. If we can register the MouseListener another way, this
140 // registration can go away, and nsDocShellTreeOwner can stop implementing
141 // nsIWebProgressListener.
142 RefPtr
<nsDocShellTreeOwner
> docShellTreeOwner
= browser
->mDocShellTreeOwner
;
143 Unused
<< docShell
->AddProgressListener(docShellTreeOwner
,
144 nsIWebProgress::NOTIFY_ALL
);
146 docShell
->SetTreeOwner(docShellTreeOwner
);
148 // If the webbrowser is a content docshell item then we won't hear any
149 // events from subframes. To solve that we install our own chrome event
150 // handler that always gets called (even for subframes) for any bubbling
153 nsresult rv
= docShell
->InitWindow(nullptr, docShellParentWidget
, 0, 0, 0, 0);
154 if (NS_WARN_IF(NS_FAILED(rv
))) {
158 docShellTreeOwner
->AddToWatcher(); // evil twin of Remove in SetDocShell(0)
159 docShellTreeOwner
->AddChromeListeners();
161 if (aInitialWindowChild
) {
162 docShell
->CreateDocumentViewerForActor(aInitialWindowChild
);
165 return browser
.forget();
168 void nsWebBrowser::InternalDestroy() {
169 if (mInternalWidget
) {
170 mInternalWidget
->SetWidgetListener(nullptr);
171 mInternalWidget
->Destroy();
172 mInternalWidget
= nullptr; // Force release here.
175 SetDocShell(nullptr);
177 if (mDocShellTreeOwner
) {
178 mDocShellTreeOwner
->WebBrowser(nullptr);
179 mDocShellTreeOwner
= nullptr;
183 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWebBrowser
)
184 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWebBrowser
)
186 NS_IMPL_CYCLE_COLLECTION_WEAK(nsWebBrowser
, mDocShell
)
188 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWebBrowser
)
189 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIWebBrowser
)
190 NS_INTERFACE_MAP_ENTRY(nsIWebBrowser
)
191 NS_INTERFACE_MAP_ENTRY(nsIWebNavigation
)
192 NS_INTERFACE_MAP_ENTRY(nsIBaseWindow
)
193 NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem
)
194 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor
)
195 NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPersist
)
196 NS_INTERFACE_MAP_ENTRY(nsICancelable
)
197 NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener
)
198 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference
)
201 ///*****************************************************************************
202 // nsWebBrowser::nsIInterfaceRequestor
203 //*****************************************************************************
206 nsWebBrowser::GetInterface(const nsIID
& aIID
, void** aSink
) {
207 NS_ENSURE_ARG_POINTER(aSink
);
209 if (NS_SUCCEEDED(QueryInterface(aIID
, aSink
))) {
215 if (aIID
.Equals(NS_GET_IID(nsIWebBrowserPrint
))) {
216 nsCOMPtr
<nsIDocumentViewer
> viewer
;
217 mDocShell
->GetDocViewer(getter_AddRefs(viewer
));
219 return NS_NOINTERFACE
;
222 nsCOMPtr
<nsIWebBrowserPrint
> webBrowserPrint(do_QueryInterface(viewer
));
223 nsIWebBrowserPrint
* print
= (nsIWebBrowserPrint
*)webBrowserPrint
.get();
224 NS_ASSERTION(print
, "This MUST support this interface!");
230 return mDocShell
->GetInterface(aIID
, aSink
);
233 return NS_NOINTERFACE
;
236 //*****************************************************************************
237 // nsWebBrowser::nsIWebBrowser
238 //*****************************************************************************
241 nsWebBrowser::GetContainerWindow(nsIWebBrowserChrome
** aTopWindow
) {
242 NS_ENSURE_ARG_POINTER(aTopWindow
);
244 nsCOMPtr
<nsIWebBrowserChrome
> top
;
245 if (mDocShellTreeOwner
) {
246 top
= mDocShellTreeOwner
->GetWebBrowserChrome();
249 top
.forget(aTopWindow
);
255 nsWebBrowser::SetContainerWindow(nsIWebBrowserChrome
* aTopWindow
) {
256 EnsureDocShellTreeOwner();
257 return mDocShellTreeOwner
->SetWebBrowserChrome(aTopWindow
);
261 nsWebBrowser::GetContentDOMWindow(mozIDOMWindowProxy
** aResult
) {
263 return NS_ERROR_UNEXPECTED
;
266 nsCOMPtr
<nsPIDOMWindowOuter
> retval
= mDocShell
->GetWindow();
267 retval
.forget(aResult
);
268 return *aResult
? NS_OK
: NS_ERROR_FAILURE
;
271 void nsWebBrowser::SetOriginAttributes(const OriginAttributes
& aAttrs
) {
272 mOriginAttributes
= aAttrs
;
275 //*****************************************************************************
276 // nsWebBrowser::nsIDocShellTreeItem
277 //*****************************************************************************
280 nsWebBrowser::GetName(nsAString
& aName
) {
282 mDocShell
->GetName(aName
);
289 nsWebBrowser::SetName(const nsAString
& aName
) {
291 return mDocShell
->SetName(aName
);
298 nsWebBrowser::NameEquals(const nsAString
& aName
, bool* aResult
) {
299 NS_ENSURE_ARG_POINTER(aResult
);
301 return mDocShell
->NameEquals(aName
, aResult
);
308 int32_t nsWebBrowser::ItemType() { return mContentType
; }
311 nsWebBrowser::GetItemType(int32_t* aItemType
) {
312 NS_ENSURE_ARG_POINTER(aItemType
);
314 *aItemType
= ItemType();
319 nsWebBrowser::GetInProcessParent(nsIDocShellTreeItem
** aParent
) {
325 nsWebBrowser::GetInProcessSameTypeParent(nsIDocShellTreeItem
** aParent
) {
332 nsWebBrowser::GetInProcessRootTreeItem(nsIDocShellTreeItem
** aRootTreeItem
) {
333 NS_ENSURE_ARG_POINTER(aRootTreeItem
);
334 *aRootTreeItem
= static_cast<nsIDocShellTreeItem
*>(this);
336 nsCOMPtr
<nsIDocShellTreeItem
> parent
;
337 NS_ENSURE_SUCCESS(GetInProcessParent(getter_AddRefs(parent
)),
340 *aRootTreeItem
= parent
;
342 (*aRootTreeItem
)->GetInProcessParent(getter_AddRefs(parent
)),
345 NS_ADDREF(*aRootTreeItem
);
350 nsWebBrowser::GetInProcessSameTypeRootTreeItem(
351 nsIDocShellTreeItem
** aRootTreeItem
) {
352 NS_ENSURE_ARG_POINTER(aRootTreeItem
);
353 *aRootTreeItem
= static_cast<nsIDocShellTreeItem
*>(this);
355 nsCOMPtr
<nsIDocShellTreeItem
> parent
;
356 NS_ENSURE_SUCCESS(GetInProcessSameTypeParent(getter_AddRefs(parent
)),
359 *aRootTreeItem
= parent
;
361 (*aRootTreeItem
)->GetInProcessSameTypeParent(getter_AddRefs(parent
)),
364 NS_ADDREF(*aRootTreeItem
);
368 dom::Document
* nsWebBrowser::GetDocument() {
369 return mDocShell
? mDocShell
->GetDocument() : nullptr;
372 nsPIDOMWindowOuter
* nsWebBrowser::GetWindow() {
373 return mDocShell
? mDocShell
->GetWindow() : nullptr;
377 nsWebBrowser::GetBrowsingContextXPCOM(dom::BrowsingContext
** aBrowsingContext
) {
378 NS_ENSURE_STATE(mDocShell
);
379 return mDocShell
->GetBrowsingContextXPCOM(aBrowsingContext
);
382 dom::BrowsingContext
* nsWebBrowser::GetBrowsingContext() {
383 return mDocShell
->GetBrowsingContext();
387 nsWebBrowser::GetDomWindow(mozIDOMWindowProxy
** aWindow
) {
388 if (!mDocShell
) return NS_ERROR_NOT_INITIALIZED
;
389 return mDocShell
->GetDomWindow(aWindow
);
393 nsWebBrowser::GetTreeOwner(nsIDocShellTreeOwner
** aTreeOwner
) {
394 NS_ENSURE_ARG_POINTER(aTreeOwner
);
395 *aTreeOwner
= nullptr;
396 if (mDocShellTreeOwner
) {
397 if (mDocShellTreeOwner
->mTreeOwner
) {
398 *aTreeOwner
= mDocShellTreeOwner
->mTreeOwner
;
400 *aTreeOwner
= mDocShellTreeOwner
;
403 NS_IF_ADDREF(*aTreeOwner
);
408 nsWebBrowser::SetTreeOwner(nsIDocShellTreeOwner
* aTreeOwner
) {
409 EnsureDocShellTreeOwner();
410 return mDocShellTreeOwner
->SetTreeOwner(aTreeOwner
);
413 //*****************************************************************************
414 // nsWebBrowser::nsIDocShellTreeItem
415 //*****************************************************************************
418 nsWebBrowser::GetInProcessChildCount(int32_t* aChildCount
) {
419 NS_ENSURE_ARG_POINTER(aChildCount
);
425 nsWebBrowser::AddChild(nsIDocShellTreeItem
* aChild
) {
426 return NS_ERROR_UNEXPECTED
;
430 nsWebBrowser::RemoveChild(nsIDocShellTreeItem
* aChild
) {
431 return NS_ERROR_UNEXPECTED
;
435 nsWebBrowser::GetInProcessChildAt(int32_t aIndex
,
436 nsIDocShellTreeItem
** aChild
) {
437 return NS_ERROR_UNEXPECTED
;
440 //*****************************************************************************
441 // nsWebBrowser::nsIWebNavigation
442 //*****************************************************************************
445 nsWebBrowser::GetCanGoBack(bool* aCanGoBack
) {
446 NS_ENSURE_STATE(mDocShell
);
448 return mDocShell
->GetCanGoBack(aCanGoBack
);
452 nsWebBrowser::GetCanGoForward(bool* aCanGoForward
) {
453 NS_ENSURE_STATE(mDocShell
);
455 return mDocShell
->GetCanGoForward(aCanGoForward
);
459 nsWebBrowser::GoBack(bool aRequireUserInteraction
, bool aUserActivation
) {
460 NS_ENSURE_STATE(mDocShell
);
462 RefPtr
<nsDocShell
> docShell
= mDocShell
;
463 return docShell
->GoBack(aRequireUserInteraction
, aUserActivation
);
467 nsWebBrowser::GoForward(bool aRequireUserInteraction
, bool aUserActivation
) {
468 NS_ENSURE_STATE(mDocShell
);
470 RefPtr
<nsDocShell
> docShell
= mDocShell
;
471 return docShell
->GoForward(aRequireUserInteraction
, aUserActivation
);
474 nsresult
nsWebBrowser::LoadURI(nsIURI
* aURI
,
475 const dom::LoadURIOptions
& aLoadURIOptions
) {
477 MOZ_ASSERT(aLoadURIOptions
.mTriggeringPrincipal
,
478 "nsWebBrowser::LoadURI - Need a valid triggeringPrincipal");
480 NS_ENSURE_STATE(mDocShell
);
482 RefPtr
<nsDocShell
> docShell
= mDocShell
;
483 return docShell
->LoadURI(aURI
, aLoadURIOptions
);
487 nsWebBrowser::LoadURIFromScript(nsIURI
* aURI
,
488 JS::Handle
<JS::Value
> aLoadURIOptions
,
490 // generate dictionary for loadURIOptions and forward call
491 dom::LoadURIOptions loadURIOptions
;
492 if (!loadURIOptions
.Init(aCx
, aLoadURIOptions
)) {
493 return NS_ERROR_INVALID_ARG
;
495 return LoadURI(aURI
, loadURIOptions
);
498 nsresult
nsWebBrowser::FixupAndLoadURIString(
499 const nsAString
& aURI
, const dom::LoadURIOptions
& aLoadURIOptions
) {
502 aLoadURIOptions
.mTriggeringPrincipal
,
503 "nsWebBrowser::FixupAndLoadURIString - Need a valid triggeringPrincipal");
505 NS_ENSURE_STATE(mDocShell
);
507 RefPtr
<nsDocShell
> docShell
= mDocShell
;
508 return docShell
->FixupAndLoadURIString(aURI
, aLoadURIOptions
);
512 nsWebBrowser::FixupAndLoadURIStringFromScript(
513 const nsAString
& aURI
, JS::Handle
<JS::Value
> aLoadURIOptions
,
515 // generate dictionary for loadURIOptions and forward call
516 dom::LoadURIOptions loadURIOptions
;
517 if (!loadURIOptions
.Init(aCx
, aLoadURIOptions
)) {
518 return NS_ERROR_INVALID_ARG
;
520 return FixupAndLoadURIString(aURI
, loadURIOptions
);
524 nsWebBrowser::ResumeRedirectedLoad(uint64_t aIdentifier
,
525 int32_t aHistoryIndex
) {
526 NS_ENSURE_STATE(mDocShell
);
528 return mDocShell
->ResumeRedirectedLoad(aIdentifier
, aHistoryIndex
);
532 nsWebBrowser::Reload(uint32_t aReloadFlags
) {
533 NS_ENSURE_STATE(mDocShell
);
535 RefPtr
<nsDocShell
> docShell
= mDocShell
;
536 return docShell
->Reload(aReloadFlags
);
540 nsWebBrowser::GotoIndex(int32_t aIndex
, bool aUserActivation
) {
541 NS_ENSURE_STATE(mDocShell
);
543 RefPtr
<nsDocShell
> docShell
= mDocShell
;
544 return docShell
->GotoIndex(aIndex
, aUserActivation
);
548 nsWebBrowser::Stop(uint32_t aStopFlags
) {
549 NS_ENSURE_STATE(mDocShell
);
551 return mDocShell
->Stop(aStopFlags
);
555 nsWebBrowser::GetCurrentURI(nsIURI
** aURI
) {
556 NS_ENSURE_STATE(mDocShell
);
558 return mDocShell
->GetCurrentURI(aURI
);
561 // XXX(nika): Consider making the mozilla::dom::ChildSHistory version the
564 nsWebBrowser::GetSessionHistoryXPCOM(nsISupports
** aSessionHistory
) {
565 NS_ENSURE_ARG_POINTER(aSessionHistory
);
566 *aSessionHistory
= nullptr;
568 return mDocShell
->GetSessionHistoryXPCOM(aSessionHistory
);
574 nsWebBrowser::GetDocument(dom::Document
** aDocument
) {
575 NS_ENSURE_STATE(mDocShell
);
577 return mDocShell
->GetDocument(aDocument
);
580 void nsWebBrowser::SetAllowDNSPrefetch(bool aAllowPrefetch
) {
581 MOZ_ASSERT(mDocShell
);
582 mDocShell
->SetAllowDNSPrefetch(aAllowPrefetch
);
585 //*****************************************************************************
586 // nsWebBrowser::nsIWebProgressListener
587 //*****************************************************************************
590 nsWebBrowser::OnStateChange(nsIWebProgress
* aWebProgress
, nsIRequest
* aRequest
,
591 uint32_t aStateFlags
, nsresult aStatus
) {
593 mPersist
->GetCurrentState(&mPersistCurrentState
);
595 if (aStateFlags
& STATE_IS_NETWORK
&& aStateFlags
& STATE_STOP
) {
598 if (mProgressListener
) {
599 return mProgressListener
->OnStateChange(aWebProgress
, aRequest
, aStateFlags
,
606 nsWebBrowser::OnProgressChange(nsIWebProgress
* aWebProgress
,
607 nsIRequest
* aRequest
, int32_t aCurSelfProgress
,
608 int32_t aMaxSelfProgress
,
609 int32_t aCurTotalProgress
,
610 int32_t aMaxTotalProgress
) {
612 mPersist
->GetCurrentState(&mPersistCurrentState
);
614 if (mProgressListener
) {
615 return mProgressListener
->OnProgressChange(
616 aWebProgress
, aRequest
, aCurSelfProgress
, aMaxSelfProgress
,
617 aCurTotalProgress
, aMaxTotalProgress
);
623 nsWebBrowser::OnLocationChange(nsIWebProgress
* aWebProgress
,
624 nsIRequest
* aRequest
, nsIURI
* aLocation
,
626 if (mProgressListener
) {
627 return mProgressListener
->OnLocationChange(aWebProgress
, aRequest
,
634 nsWebBrowser::OnStatusChange(nsIWebProgress
* aWebProgress
, nsIRequest
* aRequest
,
635 nsresult aStatus
, const char16_t
* aMessage
) {
636 if (mProgressListener
) {
637 return mProgressListener
->OnStatusChange(aWebProgress
, aRequest
, aStatus
,
644 nsWebBrowser::OnSecurityChange(nsIWebProgress
* aWebProgress
,
645 nsIRequest
* aRequest
, uint32_t aState
) {
646 if (mProgressListener
) {
647 return mProgressListener
->OnSecurityChange(aWebProgress
, aRequest
, aState
);
653 nsWebBrowser::OnContentBlockingEvent(nsIWebProgress
* aWebProgress
,
654 nsIRequest
* aRequest
, uint32_t aEvent
) {
655 if (mProgressListener
) {
656 return mProgressListener
->OnContentBlockingEvent(aWebProgress
, aRequest
,
662 //*****************************************************************************
663 // nsWebBrowser::nsIWebBrowserPersist
664 //*****************************************************************************
667 nsWebBrowser::GetPersistFlags(uint32_t* aPersistFlags
) {
668 NS_ENSURE_ARG_POINTER(aPersistFlags
);
671 rv
= mPersist
->GetPersistFlags(&mPersistFlags
);
673 *aPersistFlags
= mPersistFlags
;
678 nsWebBrowser::SetPersistFlags(uint32_t aPersistFlags
) {
680 mPersistFlags
= aPersistFlags
;
682 rv
= mPersist
->SetPersistFlags(mPersistFlags
);
683 mPersist
->GetPersistFlags(&mPersistFlags
);
689 nsWebBrowser::GetCurrentState(uint32_t* aCurrentState
) {
690 NS_ENSURE_ARG_POINTER(aCurrentState
);
692 mPersist
->GetCurrentState(&mPersistCurrentState
);
694 *aCurrentState
= mPersistCurrentState
;
699 nsWebBrowser::GetResult(nsresult
* aResult
) {
700 NS_ENSURE_ARG_POINTER(aResult
);
702 mPersist
->GetResult(&mPersistResult
);
704 *aResult
= mPersistResult
;
709 nsWebBrowser::GetProgressListener(nsIWebProgressListener
** aProgressListener
) {
710 NS_ENSURE_ARG_POINTER(aProgressListener
);
711 *aProgressListener
= mProgressListener
;
712 NS_IF_ADDREF(*aProgressListener
);
717 nsWebBrowser::SetProgressListener(nsIWebProgressListener
* aProgressListener
) {
718 mProgressListener
= aProgressListener
;
723 nsWebBrowser::SaveURI(nsIURI
* aURI
, nsIPrincipal
* aPrincipal
,
724 uint32_t aCacheKey
, nsIReferrerInfo
* aReferrerInfo
,
725 nsICookieJarSettings
* aCookieJarSettings
,
726 nsIInputStream
* aPostData
, const char* aExtraHeaders
,
728 nsContentPolicyType aContentPolicyType
, bool aIsPrivate
) {
730 uint32_t currentState
;
731 mPersist
->GetCurrentState(¤tState
);
732 if (currentState
== PERSIST_STATE_FINISHED
) {
735 // You can't save again until the last save has completed
736 return NS_ERROR_FAILURE
;
740 nsCOMPtr
<nsIURI
> uri
;
744 nsresult rv
= GetCurrentURI(getter_AddRefs(uri
));
746 return NS_ERROR_FAILURE
;
750 // Create a throwaway persistence object to do the work
752 mPersist
= do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID
, &rv
);
753 NS_ENSURE_SUCCESS(rv
, rv
);
754 mPersist
->SetProgressListener(this);
755 mPersist
->SetPersistFlags(mPersistFlags
);
756 mPersist
->GetCurrentState(&mPersistCurrentState
);
758 rv
= mPersist
->SaveURI(uri
, aPrincipal
, aCacheKey
, aReferrerInfo
,
759 aCookieJarSettings
, aPostData
, aExtraHeaders
, aFile
,
760 aContentPolicyType
, aIsPrivate
);
768 nsWebBrowser::SaveChannel(nsIChannel
* aChannel
, nsISupports
* aFile
) {
770 uint32_t currentState
;
771 mPersist
->GetCurrentState(¤tState
);
772 if (currentState
== PERSIST_STATE_FINISHED
) {
775 // You can't save again until the last save has completed
776 return NS_ERROR_FAILURE
;
780 // Create a throwaway persistence object to do the work
782 mPersist
= do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID
, &rv
);
783 NS_ENSURE_SUCCESS(rv
, rv
);
784 mPersist
->SetProgressListener(this);
785 mPersist
->SetPersistFlags(mPersistFlags
);
786 mPersist
->GetCurrentState(&mPersistCurrentState
);
787 rv
= mPersist
->SaveChannel(aChannel
, aFile
);
795 nsWebBrowser::SaveDocument(nsISupports
* aDocumentish
, nsISupports
* aFile
,
796 nsISupports
* aDataPath
,
797 const char* aOutputContentType
,
798 uint32_t aEncodingFlags
, uint32_t aWrapColumn
) {
800 uint32_t currentState
;
801 mPersist
->GetCurrentState(¤tState
);
802 if (currentState
== PERSIST_STATE_FINISHED
) {
805 // You can't save again until the last save has completed
806 return NS_ERROR_FAILURE
;
810 // Use the specified DOM document, or if none is specified, the one
811 // attached to the web browser.
813 nsCOMPtr
<nsISupports
> doc
;
817 RefPtr
<dom::Document
> domDoc
;
818 GetDocument(getter_AddRefs(domDoc
));
819 doc
= already_AddRefed
<nsISupports
>(ToSupports(domDoc
.forget().take()));
822 return NS_ERROR_FAILURE
;
825 // Create a throwaway persistence object to do the work
827 mPersist
= do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID
, &rv
);
828 NS_ENSURE_SUCCESS(rv
, rv
);
829 RefPtr
<nsIWebBrowserPersist
> localPersist(mPersist
);
830 Unused
<< localPersist
;
831 mPersist
->SetProgressListener(this);
832 mPersist
->SetPersistFlags(mPersistFlags
);
833 mPersist
->GetCurrentState(&mPersistCurrentState
);
834 rv
= mPersist
->SaveDocument(doc
, aFile
, aDataPath
, aOutputContentType
,
835 aEncodingFlags
, aWrapColumn
);
843 nsWebBrowser::CancelSave() {
845 return mPersist
->CancelSave();
851 nsWebBrowser::Cancel(nsresult aReason
) {
853 return mPersist
->Cancel(aReason
);
858 //*****************************************************************************
859 // nsWebBrowser::nsIBaseWindow
860 //*****************************************************************************
863 nsWebBrowser::InitWindow(nativeWindow aParentNativeWindow
,
864 nsIWidget
* aParentWidget
, int32_t aX
, int32_t aY
,
865 int32_t aCX
, int32_t aCY
) {
866 // nsIBaseWindow::InitWindow and nsIBaseWindow::Create
867 // implementations have been merged into nsWebBrowser::Create
868 MOZ_DIAGNOSTIC_ASSERT(false);
869 return NS_ERROR_NULL_POINTER
;
873 nsWebBrowser::Destroy() {
879 double nsWebBrowser::GetWidgetCSSToDeviceScale() {
880 return mParentWidget
? mParentWidget
->GetDefaultScale().scale
: 1.0;
884 nsWebBrowser::GetDevicePixelsPerDesktopPixel(double* aScale
) {
886 mParentWidget
? mParentWidget
->GetDesktopToDeviceScale().scale
: 1.0;
891 nsWebBrowser::SetPositionDesktopPix(int32_t aX
, int32_t aY
) {
893 // It's not clear to me whether this will be fully correct across
894 // potential multi-screen, mixed-DPI configurations for all platforms;
895 // we might need to add code paths that make it possible to pass the
896 // desktop-pix parameters all the way through to the native widget,
897 // to avoid the risk of device-pixel coords mapping to the wrong
898 // display on OS X with mixed retina/non-retina screens.
900 GetDevicePixelsPerDesktopPixel(&scale
);
901 return SetPosition(NSToIntRound(aX
* scale
), NSToIntRound(aY
* scale
));
905 nsWebBrowser::SetPosition(int32_t aX
, int32_t aY
) {
911 return SetPositionAndSize(aX
, aY
, cx
, cy
, 0);
915 nsWebBrowser::GetPosition(int32_t* aX
, int32_t* aY
) {
916 return GetPositionAndSize(aX
, aY
, nullptr, nullptr);
920 nsWebBrowser::SetSize(int32_t aCX
, int32_t aCY
, bool aRepaint
) {
926 return SetPositionAndSize(x
, y
, aCX
, aCY
,
927 aRepaint
? nsIBaseWindow::eRepaint
: 0);
931 nsWebBrowser::GetSize(int32_t* aCX
, int32_t* aCY
) {
932 return GetPositionAndSize(nullptr, nullptr, aCX
, aCY
);
936 nsWebBrowser::SetPositionAndSize(int32_t aX
, int32_t aY
, int32_t aCX
,
937 int32_t aCY
, uint32_t aFlags
) {
941 // If there is an internal widget we need to make the docShell coordinates
942 // relative to the internal widget rather than the calling app's parent.
943 // We also need to resize our widget then.
944 if (mInternalWidget
) {
946 mInternalWidget
->Resize(aX
, aY
, aCX
, aCY
,
947 !!(aFlags
& nsIBaseWindow::eRepaint
));
949 // Now reposition/ resize the doc
951 mDocShell
->SetPositionAndSize(doc_x
, doc_y
, aCX
, aCY
, aFlags
),
958 nsWebBrowser::GetPositionAndSize(int32_t* aX
, int32_t* aY
, int32_t* aCX
,
960 if (mInternalWidget
) {
961 LayoutDeviceIntRect bounds
= mInternalWidget
->GetBounds();
970 *aCX
= bounds
.Width();
973 *aCY
= bounds
.Height();
978 // Can directly return this as it is the
979 // same interface, thus same returns.
980 return mDocShell
->GetPositionAndSize(aX
, aY
, aCX
, aCY
);
984 nsWebBrowser::SetDimensions(DimensionRequest
&& aRequest
) {
985 return NS_ERROR_NOT_IMPLEMENTED
;
989 nsWebBrowser::GetDimensions(DimensionKind aDimensionKind
, int32_t* aX
,
990 int32_t* aY
, int32_t* aCX
, int32_t* aCY
) {
991 return NS_ERROR_NOT_IMPLEMENTED
;
995 nsWebBrowser::Repaint(bool aForce
) {
996 NS_ENSURE_STATE(mDocShell
);
997 // Can directly return this as it is the
998 // same interface, thus same returns.
999 return mDocShell
->Repaint(aForce
);
1003 nsWebBrowser::GetParentWidget(nsIWidget
** aParentWidget
) {
1004 NS_ENSURE_ARG_POINTER(aParentWidget
);
1006 *aParentWidget
= mParentWidget
;
1008 NS_IF_ADDREF(*aParentWidget
);
1014 nsWebBrowser::SetParentWidget(nsIWidget
* aParentWidget
) {
1015 NS_ENSURE_STATE(!mDocShell
);
1017 mParentWidget
= aParentWidget
;
1018 if (mParentWidget
) {
1019 mParentNativeWindow
= mParentWidget
->GetNativeData(NS_NATIVE_WIDGET
);
1021 mParentNativeWindow
= nullptr;
1028 nsWebBrowser::GetParentNativeWindow(nativeWindow
* aParentNativeWindow
) {
1029 NS_ENSURE_ARG_POINTER(aParentNativeWindow
);
1031 *aParentNativeWindow
= mParentNativeWindow
;
1037 nsWebBrowser::SetParentNativeWindow(nativeWindow aParentNativeWindow
) {
1038 NS_ENSURE_STATE(!mDocShell
);
1040 mParentNativeWindow
= aParentNativeWindow
;
1046 nsWebBrowser::GetNativeHandle(nsAString
& aNativeHandle
) {
1047 // the nativeHandle should be accessed from nsIAppWindow
1048 return NS_ERROR_NOT_IMPLEMENTED
;
1052 nsWebBrowser::GetVisibility(bool* aVisibility
) {
1053 NS_ENSURE_ARG_POINTER(aVisibility
);
1056 NS_ENSURE_SUCCESS(mDocShell
->GetVisibility(aVisibility
), NS_ERROR_FAILURE
);
1063 nsWebBrowser::SetVisibility(bool aVisibility
) {
1065 NS_ENSURE_SUCCESS(mDocShell
->SetVisibility(aVisibility
), NS_ERROR_FAILURE
);
1066 if (mInternalWidget
) {
1067 mInternalWidget
->Show(aVisibility
);
1075 nsWebBrowser::GetEnabled(bool* aEnabled
) {
1076 if (mInternalWidget
) {
1077 *aEnabled
= mInternalWidget
->IsEnabled();
1081 return NS_ERROR_FAILURE
;
1085 nsWebBrowser::SetEnabled(bool aEnabled
) {
1086 if (mInternalWidget
) {
1087 mInternalWidget
->Enable(aEnabled
);
1090 return NS_ERROR_FAILURE
;
1094 nsWebBrowser::GetMainWidget(nsIWidget
** aMainWidget
) {
1095 NS_ENSURE_ARG_POINTER(aMainWidget
);
1097 if (mInternalWidget
) {
1098 *aMainWidget
= mInternalWidget
;
1100 *aMainWidget
= mParentWidget
;
1103 NS_IF_ADDREF(*aMainWidget
);
1109 nsWebBrowser::GetTitle(nsAString
& aTitle
) {
1110 NS_ENSURE_STATE(mDocShell
);
1112 NS_ENSURE_SUCCESS(mDocShell
->GetTitle(aTitle
), NS_ERROR_FAILURE
);
1118 nsWebBrowser::SetTitle(const nsAString
& aTitle
) {
1119 NS_ENSURE_STATE(mDocShell
);
1121 NS_ENSURE_SUCCESS(mDocShell
->SetTitle(aTitle
), NS_ERROR_FAILURE
);
1126 //*****************************************************************************
1127 // nsWebBrowser: Listener Helpers
1128 //*****************************************************************************
1130 void nsWebBrowser::SetDocShell(nsDocShell
* aDocShell
) {
1131 // We need to keep the docshell alive while we perform the changes, but we
1132 // don't need to call any methods on it.
1133 nsCOMPtr
<nsIDocShell
> kungFuDeathGrip(mDocShell
);
1134 mozilla::Unused
<< kungFuDeathGrip
;
1137 MOZ_ASSERT(!mDocShell
, "Should not overwrite an existing value!");
1139 mDocShell
= aDocShell
;
1141 // By default, do not allow DNS prefetch, so we don't break our frozen
1142 // API. Embeddors who decide to enable it should do so manually.
1143 mDocShell
->SetAllowDNSPrefetch(false);
1145 if (mDocShellTreeOwner
) {
1146 mDocShellTreeOwner
->RemoveFromWatcher(); // evil twin of Add in Create()
1149 mDocShell
->Destroy();
1151 if (!mWillChangeProcess
&& mDocShell
) {
1152 mDocShell
->GetBrowsingContext()->Detach(/* aFromIPC */ true);
1155 mDocShell
= nullptr;
1159 void nsWebBrowser::EnsureDocShellTreeOwner() {
1160 if (mDocShellTreeOwner
) {
1164 mDocShellTreeOwner
= new nsDocShellTreeOwner();
1165 mDocShellTreeOwner
->WebBrowser(this);
1168 void nsWebBrowser::WindowActivated() {
1169 #if defined(DEBUG_smaug)
1170 RefPtr
<dom::Document
> document
= mDocShell
->GetDocument();
1171 nsAutoString documentURI
;
1172 document
->GetDocumentURI(documentURI
);
1173 printf("nsWebBrowser::NS_ACTIVATE %p %s\n", (void*)this,
1174 NS_ConvertUTF16toUTF8(documentURI
).get());
1176 FocusActivate(nsFocusManager::GenerateFocusActionId());
1179 void nsWebBrowser::WindowDeactivated() {
1180 #if defined(DEBUG_smaug)
1181 RefPtr
<dom::Document
> document
= mDocShell
->GetDocument();
1182 nsAutoString documentURI
;
1183 document
->GetDocumentURI(documentURI
);
1184 printf("nsWebBrowser::NS_DEACTIVATE %p %s\n", (void*)this,
1185 NS_ConvertUTF16toUTF8(documentURI
).get());
1187 FocusDeactivate(nsFocusManager::GenerateFocusActionId());
1190 bool nsWebBrowser::PaintWindow(nsIWidget
* aWidget
,
1191 LayoutDeviceIntRegion aRegion
) {
1192 WindowRenderer
* renderer
= aWidget
->GetWindowRenderer();
1193 NS_ASSERTION(renderer
, "Must be in paint event");
1194 if (FallbackRenderer
* fallback
= renderer
->AsFallback()) {
1195 if (fallback
->BeginTransaction()) {
1196 fallback
->EndTransactionWithColor(aRegion
.GetBounds().ToUnknownRect(),
1197 ToDeviceColor(mBackgroundColor
));
1204 void nsWebBrowser::FocusActivate(uint64_t aActionId
) {
1205 if (RefPtr
<nsFocusManager
> fm
= nsFocusManager::GetFocusManager()) {
1206 if (nsCOMPtr
<nsPIDOMWindowOuter
> window
= GetWindow()) {
1207 fm
->WindowRaised(window
, aActionId
);
1212 void nsWebBrowser::FocusDeactivate(uint64_t aActionId
) {
1213 if (RefPtr
<nsFocusManager
> fm
= nsFocusManager::GetFocusManager()) {
1214 if (nsCOMPtr
<nsPIDOMWindowOuter
> window
= GetWindow()) {
1215 fm
->WindowLowered(window
, aActionId
);
1220 void nsWebBrowser::SetWillChangeProcess() {
1221 mWillChangeProcess
= true;
1223 nsDocShell::Cast(mDocShell
)->SetWillChangeProcess();
1227 void nsWebBrowser::WidgetListenerDelegate::WindowActivated() {
1228 RefPtr
<nsWebBrowser
> holder
= mWebBrowser
;
1229 holder
->WindowActivated();
1232 void nsWebBrowser::WidgetListenerDelegate::WindowDeactivated() {
1233 RefPtr
<nsWebBrowser
> holder
= mWebBrowser
;
1234 holder
->WindowDeactivated();
1237 bool nsWebBrowser::WidgetListenerDelegate::PaintWindow(
1238 nsIWidget
* aWidget
, mozilla::LayoutDeviceIntRegion aRegion
) {
1239 RefPtr
<nsWebBrowser
> holder
= mWebBrowser
;
1240 return holder
->PaintWindow(aWidget
, aRegion
);