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 mProgressListener(nullptr),
63 mWidgetListenerDelegate(this),
65 mPersistCurrentState(nsIWebBrowserPersist::PERSIST_STATE_READY
),
66 mPersistResult(NS_OK
),
67 mPersistFlags(nsIWebBrowserPersist::PERSIST_FLAGS_NONE
),
68 mParentWidget(nullptr) {
69 mWWatch
= do_GetService(NS_WINDOWWATCHER_CONTRACTID
);
70 NS_ASSERTION(mWWatch
, "failed to get WindowWatcher");
73 nsWebBrowser::~nsWebBrowser() { InternalDestroy(); }
75 nsIWidget
* nsWebBrowser::EnsureWidget() {
80 mInternalWidget
= nsIWidget::CreateChildWindow();
81 if (NS_WARN_IF(!mInternalWidget
)) {
85 widget::InitData widgetInit
;
86 widgetInit
.mClipChildren
= true;
87 widgetInit
.mWindowType
= widget::WindowType::Child
;
88 LayoutDeviceIntRect
bounds(0, 0, 0, 0);
90 mInternalWidget
->SetWidgetListener(&mWidgetListenerDelegate
);
91 NS_ENSURE_SUCCESS(mInternalWidget
->Create(mParentWidget
, bounds
, &widgetInit
),
94 return mInternalWidget
;
98 already_AddRefed
<nsWebBrowser
> nsWebBrowser::Create(
99 nsIWebBrowserChrome
* aContainerWindow
, nsIWidget
* aParentWidget
,
100 dom::BrowsingContext
* aBrowsingContext
,
101 dom::WindowGlobalChild
* aInitialWindowChild
) {
102 MOZ_ASSERT_IF(aInitialWindowChild
,
103 aInitialWindowChild
->BrowsingContext() == aBrowsingContext
);
105 RefPtr
<nsWebBrowser
> browser
= new nsWebBrowser(
106 aBrowsingContext
->IsContent() ? typeContentWrapper
: typeChromeWrapper
);
108 // nsWebBrowser::SetContainer also calls nsWebBrowser::EnsureDocShellTreeOwner
109 NS_ENSURE_SUCCESS(browser
->SetContainerWindow(aContainerWindow
), nullptr);
110 NS_ENSURE_SUCCESS(browser
->SetParentWidget(aParentWidget
), nullptr);
112 nsCOMPtr
<nsIWidget
> docShellParentWidget
= browser
->EnsureWidget();
113 if (NS_WARN_IF(!docShellParentWidget
)) {
117 uint64_t outerWindowId
=
118 aInitialWindowChild
? aInitialWindowChild
->OuterWindowId() : 0;
120 RefPtr
<nsDocShell
> docShell
=
121 nsDocShell::Create(aBrowsingContext
, outerWindowId
);
122 if (NS_WARN_IF(!docShell
)) {
125 browser
->SetDocShell(docShell
);
126 MOZ_ASSERT(browser
->mDocShell
== docShell
);
128 // get the system default window background colour
130 // TODO(emilio): Can we get the color-scheme from somewhere here?
131 browser
->mBackgroundColor
=
132 LookAndFeel::Color(LookAndFeel::ColorID::Window
, ColorScheme::Light
,
133 LookAndFeel::UseStandins::No
);
135 // HACK ALERT - this registration registers the nsDocShellTreeOwner as a
136 // nsIWebBrowserListener so it can setup its MouseListener in one of the
137 // progress callbacks. If we can register the MouseListener another way, this
138 // registration can go away, and nsDocShellTreeOwner can stop implementing
139 // nsIWebProgressListener.
140 RefPtr
<nsDocShellTreeOwner
> docShellTreeOwner
= browser
->mDocShellTreeOwner
;
141 Unused
<< docShell
->AddProgressListener(docShellTreeOwner
,
142 nsIWebProgress::NOTIFY_ALL
);
144 docShell
->SetTreeOwner(docShellTreeOwner
);
146 // If the webbrowser is a content docshell item then we won't hear any
147 // events from subframes. To solve that we install our own chrome event
148 // handler that always gets called (even for subframes) for any bubbling
150 nsresult rv
= docShell
->InitWindow(docShellParentWidget
, 0, 0, 0, 0);
151 if (NS_WARN_IF(NS_FAILED(rv
))) {
155 docShellTreeOwner
->AddToWatcher(); // evil twin of Remove in SetDocShell(0)
156 docShellTreeOwner
->AddChromeListeners();
158 if (aInitialWindowChild
) {
159 docShell
->CreateDocumentViewerForActor(aInitialWindowChild
);
162 return browser
.forget();
165 void nsWebBrowser::InternalDestroy() {
166 if (mInternalWidget
) {
167 mInternalWidget
->SetWidgetListener(nullptr);
168 mInternalWidget
->Destroy();
169 mInternalWidget
= nullptr; // Force release here.
172 SetDocShell(nullptr);
174 if (mDocShellTreeOwner
) {
175 mDocShellTreeOwner
->WebBrowser(nullptr);
176 mDocShellTreeOwner
= nullptr;
180 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWebBrowser
)
181 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWebBrowser
)
183 NS_IMPL_CYCLE_COLLECTION_WEAK(nsWebBrowser
, mDocShell
)
185 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWebBrowser
)
186 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIWebBrowser
)
187 NS_INTERFACE_MAP_ENTRY(nsIWebBrowser
)
188 NS_INTERFACE_MAP_ENTRY(nsIWebNavigation
)
189 NS_INTERFACE_MAP_ENTRY(nsIBaseWindow
)
190 NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem
)
191 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor
)
192 NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPersist
)
193 NS_INTERFACE_MAP_ENTRY(nsICancelable
)
194 NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener
)
195 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference
)
198 ///*****************************************************************************
199 // nsWebBrowser::nsIInterfaceRequestor
200 //*****************************************************************************
203 nsWebBrowser::GetInterface(const nsIID
& aIID
, void** aSink
) {
204 NS_ENSURE_ARG_POINTER(aSink
);
206 if (NS_SUCCEEDED(QueryInterface(aIID
, aSink
))) {
212 if (aIID
.Equals(NS_GET_IID(nsIWebBrowserPrint
))) {
213 nsCOMPtr
<nsIDocumentViewer
> viewer
;
214 mDocShell
->GetDocViewer(getter_AddRefs(viewer
));
216 return NS_NOINTERFACE
;
219 nsCOMPtr
<nsIWebBrowserPrint
> webBrowserPrint(do_QueryInterface(viewer
));
220 nsIWebBrowserPrint
* print
= (nsIWebBrowserPrint
*)webBrowserPrint
.get();
221 NS_ASSERTION(print
, "This MUST support this interface!");
227 return mDocShell
->GetInterface(aIID
, aSink
);
230 return NS_NOINTERFACE
;
233 //*****************************************************************************
234 // nsWebBrowser::nsIWebBrowser
235 //*****************************************************************************
238 nsWebBrowser::GetContainerWindow(nsIWebBrowserChrome
** aTopWindow
) {
239 NS_ENSURE_ARG_POINTER(aTopWindow
);
241 nsCOMPtr
<nsIWebBrowserChrome
> top
;
242 if (mDocShellTreeOwner
) {
243 top
= mDocShellTreeOwner
->GetWebBrowserChrome();
246 top
.forget(aTopWindow
);
252 nsWebBrowser::SetContainerWindow(nsIWebBrowserChrome
* aTopWindow
) {
253 EnsureDocShellTreeOwner();
254 return mDocShellTreeOwner
->SetWebBrowserChrome(aTopWindow
);
258 nsWebBrowser::GetContentDOMWindow(mozIDOMWindowProxy
** aResult
) {
260 return NS_ERROR_UNEXPECTED
;
263 nsCOMPtr
<nsPIDOMWindowOuter
> retval
= mDocShell
->GetWindow();
264 retval
.forget(aResult
);
265 return *aResult
? NS_OK
: NS_ERROR_FAILURE
;
268 void nsWebBrowser::SetOriginAttributes(const OriginAttributes
& aAttrs
) {
269 mOriginAttributes
= aAttrs
;
272 //*****************************************************************************
273 // nsWebBrowser::nsIDocShellTreeItem
274 //*****************************************************************************
277 nsWebBrowser::GetName(nsAString
& aName
) {
279 mDocShell
->GetName(aName
);
286 nsWebBrowser::SetName(const nsAString
& aName
) {
288 return mDocShell
->SetName(aName
);
295 nsWebBrowser::NameEquals(const nsAString
& aName
, bool* aResult
) {
296 NS_ENSURE_ARG_POINTER(aResult
);
298 return mDocShell
->NameEquals(aName
, aResult
);
305 int32_t nsWebBrowser::ItemType() { return mContentType
; }
308 nsWebBrowser::GetItemType(int32_t* aItemType
) {
309 NS_ENSURE_ARG_POINTER(aItemType
);
311 *aItemType
= ItemType();
316 nsWebBrowser::GetInProcessParent(nsIDocShellTreeItem
** aParent
) {
322 nsWebBrowser::GetInProcessSameTypeParent(nsIDocShellTreeItem
** aParent
) {
329 nsWebBrowser::GetInProcessRootTreeItem(nsIDocShellTreeItem
** aRootTreeItem
) {
330 NS_ENSURE_ARG_POINTER(aRootTreeItem
);
331 *aRootTreeItem
= static_cast<nsIDocShellTreeItem
*>(this);
333 nsCOMPtr
<nsIDocShellTreeItem
> parent
;
334 NS_ENSURE_SUCCESS(GetInProcessParent(getter_AddRefs(parent
)),
337 *aRootTreeItem
= parent
;
339 (*aRootTreeItem
)->GetInProcessParent(getter_AddRefs(parent
)),
342 NS_ADDREF(*aRootTreeItem
);
347 nsWebBrowser::GetInProcessSameTypeRootTreeItem(
348 nsIDocShellTreeItem
** aRootTreeItem
) {
349 NS_ENSURE_ARG_POINTER(aRootTreeItem
);
350 *aRootTreeItem
= static_cast<nsIDocShellTreeItem
*>(this);
352 nsCOMPtr
<nsIDocShellTreeItem
> parent
;
353 NS_ENSURE_SUCCESS(GetInProcessSameTypeParent(getter_AddRefs(parent
)),
356 *aRootTreeItem
= parent
;
358 (*aRootTreeItem
)->GetInProcessSameTypeParent(getter_AddRefs(parent
)),
361 NS_ADDREF(*aRootTreeItem
);
365 dom::Document
* nsWebBrowser::GetDocument() {
366 return mDocShell
? mDocShell
->GetDocument() : nullptr;
369 nsPIDOMWindowOuter
* nsWebBrowser::GetWindow() {
370 return mDocShell
? mDocShell
->GetWindow() : nullptr;
374 nsWebBrowser::GetBrowsingContextXPCOM(dom::BrowsingContext
** aBrowsingContext
) {
375 NS_ENSURE_STATE(mDocShell
);
376 return mDocShell
->GetBrowsingContextXPCOM(aBrowsingContext
);
379 dom::BrowsingContext
* nsWebBrowser::GetBrowsingContext() {
380 return mDocShell
->GetBrowsingContext();
384 nsWebBrowser::GetDomWindow(mozIDOMWindowProxy
** aWindow
) {
385 if (!mDocShell
) return NS_ERROR_NOT_INITIALIZED
;
386 return mDocShell
->GetDomWindow(aWindow
);
390 nsWebBrowser::GetTreeOwner(nsIDocShellTreeOwner
** aTreeOwner
) {
391 NS_ENSURE_ARG_POINTER(aTreeOwner
);
392 *aTreeOwner
= nullptr;
393 if (mDocShellTreeOwner
) {
394 if (mDocShellTreeOwner
->mTreeOwner
) {
395 *aTreeOwner
= mDocShellTreeOwner
->mTreeOwner
;
397 *aTreeOwner
= mDocShellTreeOwner
;
400 NS_IF_ADDREF(*aTreeOwner
);
405 nsWebBrowser::SetTreeOwner(nsIDocShellTreeOwner
* aTreeOwner
) {
406 EnsureDocShellTreeOwner();
407 return mDocShellTreeOwner
->SetTreeOwner(aTreeOwner
);
410 //*****************************************************************************
411 // nsWebBrowser::nsIDocShellTreeItem
412 //*****************************************************************************
415 nsWebBrowser::GetInProcessChildCount(int32_t* aChildCount
) {
416 NS_ENSURE_ARG_POINTER(aChildCount
);
422 nsWebBrowser::AddChild(nsIDocShellTreeItem
* aChild
) {
423 return NS_ERROR_UNEXPECTED
;
427 nsWebBrowser::RemoveChild(nsIDocShellTreeItem
* aChild
) {
428 return NS_ERROR_UNEXPECTED
;
432 nsWebBrowser::GetInProcessChildAt(int32_t aIndex
,
433 nsIDocShellTreeItem
** aChild
) {
434 return NS_ERROR_UNEXPECTED
;
437 //*****************************************************************************
438 // nsWebBrowser::nsIWebNavigation
439 //*****************************************************************************
442 nsWebBrowser::GetCanGoBack(bool* aCanGoBack
) {
443 NS_ENSURE_STATE(mDocShell
);
445 return mDocShell
->GetCanGoBack(aCanGoBack
);
449 nsWebBrowser::GetCanGoBackIgnoringUserInteraction(bool* aCanGoBack
) {
450 NS_ENSURE_STATE(mDocShell
);
452 return mDocShell
->GetCanGoBackIgnoringUserInteraction(aCanGoBack
);
456 nsWebBrowser::GetCanGoForward(bool* aCanGoForward
) {
457 NS_ENSURE_STATE(mDocShell
);
459 return mDocShell
->GetCanGoForward(aCanGoForward
);
463 nsWebBrowser::GoBack(bool aRequireUserInteraction
, bool aUserActivation
) {
464 NS_ENSURE_STATE(mDocShell
);
466 RefPtr
<nsDocShell
> docShell
= mDocShell
;
467 return docShell
->GoBack(aRequireUserInteraction
, aUserActivation
);
471 nsWebBrowser::GoForward(bool aRequireUserInteraction
, bool aUserActivation
) {
472 NS_ENSURE_STATE(mDocShell
);
474 RefPtr
<nsDocShell
> docShell
= mDocShell
;
475 return docShell
->GoForward(aRequireUserInteraction
, aUserActivation
);
478 nsresult
nsWebBrowser::LoadURI(nsIURI
* aURI
,
479 const dom::LoadURIOptions
& aLoadURIOptions
) {
481 MOZ_ASSERT(aLoadURIOptions
.mTriggeringPrincipal
,
482 "nsWebBrowser::LoadURI - Need a valid triggeringPrincipal");
484 NS_ENSURE_STATE(mDocShell
);
486 RefPtr
<nsDocShell
> docShell
= mDocShell
;
487 return docShell
->LoadURI(aURI
, aLoadURIOptions
);
491 nsWebBrowser::LoadURIFromScript(nsIURI
* aURI
,
492 JS::Handle
<JS::Value
> aLoadURIOptions
,
494 // generate dictionary for loadURIOptions and forward call
495 dom::LoadURIOptions loadURIOptions
;
496 if (!loadURIOptions
.Init(aCx
, aLoadURIOptions
)) {
497 return NS_ERROR_INVALID_ARG
;
499 return LoadURI(aURI
, loadURIOptions
);
502 nsresult
nsWebBrowser::FixupAndLoadURIString(
503 const nsAString
& aURI
, const dom::LoadURIOptions
& aLoadURIOptions
) {
506 aLoadURIOptions
.mTriggeringPrincipal
,
507 "nsWebBrowser::FixupAndLoadURIString - Need a valid triggeringPrincipal");
509 NS_ENSURE_STATE(mDocShell
);
511 RefPtr
<nsDocShell
> docShell
= mDocShell
;
512 return docShell
->FixupAndLoadURIString(aURI
, aLoadURIOptions
);
516 nsWebBrowser::FixupAndLoadURIStringFromScript(
517 const nsAString
& aURI
, JS::Handle
<JS::Value
> aLoadURIOptions
,
519 // generate dictionary for loadURIOptions and forward call
520 dom::LoadURIOptions loadURIOptions
;
521 if (!loadURIOptions
.Init(aCx
, aLoadURIOptions
)) {
522 return NS_ERROR_INVALID_ARG
;
524 return FixupAndLoadURIString(aURI
, loadURIOptions
);
528 nsWebBrowser::ResumeRedirectedLoad(uint64_t aIdentifier
,
529 int32_t aHistoryIndex
) {
530 NS_ENSURE_STATE(mDocShell
);
532 return mDocShell
->ResumeRedirectedLoad(aIdentifier
, aHistoryIndex
);
536 nsWebBrowser::Reload(uint32_t aReloadFlags
) {
537 NS_ENSURE_STATE(mDocShell
);
539 RefPtr
<nsDocShell
> docShell
= mDocShell
;
540 return docShell
->Reload(aReloadFlags
);
544 nsWebBrowser::GotoIndex(int32_t aIndex
, bool aUserActivation
) {
545 NS_ENSURE_STATE(mDocShell
);
547 RefPtr
<nsDocShell
> docShell
= mDocShell
;
548 return docShell
->GotoIndex(aIndex
, aUserActivation
);
552 nsWebBrowser::Stop(uint32_t aStopFlags
) {
553 NS_ENSURE_STATE(mDocShell
);
555 return mDocShell
->Stop(aStopFlags
);
559 nsWebBrowser::GetCurrentURI(nsIURI
** aURI
) {
560 NS_ENSURE_STATE(mDocShell
);
562 return mDocShell
->GetCurrentURI(aURI
);
565 // XXX(nika): Consider making the mozilla::dom::ChildSHistory version the
568 nsWebBrowser::GetSessionHistoryXPCOM(nsISupports
** aSessionHistory
) {
569 NS_ENSURE_ARG_POINTER(aSessionHistory
);
570 *aSessionHistory
= nullptr;
572 return mDocShell
->GetSessionHistoryXPCOM(aSessionHistory
);
578 nsWebBrowser::GetDocument(dom::Document
** aDocument
) {
579 NS_ENSURE_STATE(mDocShell
);
581 return mDocShell
->GetDocument(aDocument
);
584 void nsWebBrowser::SetAllowDNSPrefetch(bool aAllowPrefetch
) {
585 MOZ_ASSERT(mDocShell
);
586 mDocShell
->SetAllowDNSPrefetch(aAllowPrefetch
);
589 //*****************************************************************************
590 // nsWebBrowser::nsIWebProgressListener
591 //*****************************************************************************
594 nsWebBrowser::OnStateChange(nsIWebProgress
* aWebProgress
, nsIRequest
* aRequest
,
595 uint32_t aStateFlags
, nsresult aStatus
) {
597 mPersist
->GetCurrentState(&mPersistCurrentState
);
599 if (aStateFlags
& STATE_IS_NETWORK
&& aStateFlags
& STATE_STOP
) {
602 if (mProgressListener
) {
603 return mProgressListener
->OnStateChange(aWebProgress
, aRequest
, aStateFlags
,
610 nsWebBrowser::OnProgressChange(nsIWebProgress
* aWebProgress
,
611 nsIRequest
* aRequest
, int32_t aCurSelfProgress
,
612 int32_t aMaxSelfProgress
,
613 int32_t aCurTotalProgress
,
614 int32_t aMaxTotalProgress
) {
616 mPersist
->GetCurrentState(&mPersistCurrentState
);
618 if (mProgressListener
) {
619 return mProgressListener
->OnProgressChange(
620 aWebProgress
, aRequest
, aCurSelfProgress
, aMaxSelfProgress
,
621 aCurTotalProgress
, aMaxTotalProgress
);
627 nsWebBrowser::OnLocationChange(nsIWebProgress
* aWebProgress
,
628 nsIRequest
* aRequest
, nsIURI
* aLocation
,
630 if (mProgressListener
) {
631 return mProgressListener
->OnLocationChange(aWebProgress
, aRequest
,
638 nsWebBrowser::OnStatusChange(nsIWebProgress
* aWebProgress
, nsIRequest
* aRequest
,
639 nsresult aStatus
, const char16_t
* aMessage
) {
640 if (mProgressListener
) {
641 return mProgressListener
->OnStatusChange(aWebProgress
, aRequest
, aStatus
,
648 nsWebBrowser::OnSecurityChange(nsIWebProgress
* aWebProgress
,
649 nsIRequest
* aRequest
, uint32_t aState
) {
650 if (mProgressListener
) {
651 return mProgressListener
->OnSecurityChange(aWebProgress
, aRequest
, aState
);
657 nsWebBrowser::OnContentBlockingEvent(nsIWebProgress
* aWebProgress
,
658 nsIRequest
* aRequest
, uint32_t aEvent
) {
659 if (mProgressListener
) {
660 return mProgressListener
->OnContentBlockingEvent(aWebProgress
, aRequest
,
666 //*****************************************************************************
667 // nsWebBrowser::nsIWebBrowserPersist
668 //*****************************************************************************
671 nsWebBrowser::GetPersistFlags(uint32_t* aPersistFlags
) {
672 NS_ENSURE_ARG_POINTER(aPersistFlags
);
675 rv
= mPersist
->GetPersistFlags(&mPersistFlags
);
677 *aPersistFlags
= mPersistFlags
;
682 nsWebBrowser::SetPersistFlags(uint32_t aPersistFlags
) {
684 mPersistFlags
= aPersistFlags
;
686 rv
= mPersist
->SetPersistFlags(mPersistFlags
);
687 mPersist
->GetPersistFlags(&mPersistFlags
);
693 nsWebBrowser::GetCurrentState(uint32_t* aCurrentState
) {
694 NS_ENSURE_ARG_POINTER(aCurrentState
);
696 mPersist
->GetCurrentState(&mPersistCurrentState
);
698 *aCurrentState
= mPersistCurrentState
;
703 nsWebBrowser::GetResult(nsresult
* aResult
) {
704 NS_ENSURE_ARG_POINTER(aResult
);
706 mPersist
->GetResult(&mPersistResult
);
708 *aResult
= mPersistResult
;
713 nsWebBrowser::GetProgressListener(nsIWebProgressListener
** aProgressListener
) {
714 NS_ENSURE_ARG_POINTER(aProgressListener
);
715 *aProgressListener
= mProgressListener
;
716 NS_IF_ADDREF(*aProgressListener
);
721 nsWebBrowser::SetProgressListener(nsIWebProgressListener
* aProgressListener
) {
722 mProgressListener
= aProgressListener
;
727 nsWebBrowser::SaveURI(nsIURI
* aURI
, nsIPrincipal
* aPrincipal
,
728 uint32_t aCacheKey
, nsIReferrerInfo
* aReferrerInfo
,
729 nsICookieJarSettings
* aCookieJarSettings
,
730 nsIInputStream
* aPostData
, const char* aExtraHeaders
,
732 nsContentPolicyType aContentPolicyType
, bool aIsPrivate
) {
734 uint32_t currentState
;
735 mPersist
->GetCurrentState(¤tState
);
736 if (currentState
== PERSIST_STATE_FINISHED
) {
739 // You can't save again until the last save has completed
740 return NS_ERROR_FAILURE
;
744 nsCOMPtr
<nsIURI
> uri
;
748 nsresult rv
= GetCurrentURI(getter_AddRefs(uri
));
750 return NS_ERROR_FAILURE
;
754 // Create a throwaway persistence object to do the work
756 mPersist
= do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID
, &rv
);
757 NS_ENSURE_SUCCESS(rv
, rv
);
758 mPersist
->SetProgressListener(this);
759 mPersist
->SetPersistFlags(mPersistFlags
);
760 mPersist
->GetCurrentState(&mPersistCurrentState
);
762 rv
= mPersist
->SaveURI(uri
, aPrincipal
, aCacheKey
, aReferrerInfo
,
763 aCookieJarSettings
, aPostData
, aExtraHeaders
, aFile
,
764 aContentPolicyType
, aIsPrivate
);
772 nsWebBrowser::SaveChannel(nsIChannel
* aChannel
, nsISupports
* aFile
) {
774 uint32_t currentState
;
775 mPersist
->GetCurrentState(¤tState
);
776 if (currentState
== PERSIST_STATE_FINISHED
) {
779 // You can't save again until the last save has completed
780 return NS_ERROR_FAILURE
;
784 // Create a throwaway persistence object to do the work
786 mPersist
= do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID
, &rv
);
787 NS_ENSURE_SUCCESS(rv
, rv
);
788 mPersist
->SetProgressListener(this);
789 mPersist
->SetPersistFlags(mPersistFlags
);
790 mPersist
->GetCurrentState(&mPersistCurrentState
);
791 rv
= mPersist
->SaveChannel(aChannel
, aFile
);
799 nsWebBrowser::SaveDocument(nsISupports
* aDocumentish
, nsISupports
* aFile
,
800 nsISupports
* aDataPath
,
801 const char* aOutputContentType
,
802 uint32_t aEncodingFlags
, uint32_t aWrapColumn
) {
804 uint32_t currentState
;
805 mPersist
->GetCurrentState(¤tState
);
806 if (currentState
== PERSIST_STATE_FINISHED
) {
809 // You can't save again until the last save has completed
810 return NS_ERROR_FAILURE
;
814 // Use the specified DOM document, or if none is specified, the one
815 // attached to the web browser.
817 nsCOMPtr
<nsISupports
> doc
;
821 RefPtr
<dom::Document
> domDoc
;
822 GetDocument(getter_AddRefs(domDoc
));
823 doc
= already_AddRefed
<nsISupports
>(ToSupports(domDoc
.forget().take()));
826 return NS_ERROR_FAILURE
;
829 // Create a throwaway persistence object to do the work
831 mPersist
= do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID
, &rv
);
832 NS_ENSURE_SUCCESS(rv
, rv
);
833 RefPtr
<nsIWebBrowserPersist
> localPersist(mPersist
);
834 Unused
<< localPersist
;
835 mPersist
->SetProgressListener(this);
836 mPersist
->SetPersistFlags(mPersistFlags
);
837 mPersist
->GetCurrentState(&mPersistCurrentState
);
838 rv
= mPersist
->SaveDocument(doc
, aFile
, aDataPath
, aOutputContentType
,
839 aEncodingFlags
, aWrapColumn
);
847 nsWebBrowser::CancelSave() {
849 return mPersist
->CancelSave();
855 nsWebBrowser::Cancel(nsresult aReason
) {
857 return mPersist
->Cancel(aReason
);
862 //*****************************************************************************
863 // nsWebBrowser::nsIBaseWindow
864 //*****************************************************************************
867 nsWebBrowser::InitWindow(nsIWidget
* aParentWidget
, int32_t aX
, int32_t aY
,
868 int32_t aCX
, int32_t aCY
) {
869 // nsIBaseWindow::InitWindow and nsIBaseWindow::Create
870 // implementations have been merged into nsWebBrowser::Create
871 MOZ_DIAGNOSTIC_CRASH("Superceded by nsWebBrowser::Create()");
872 return NS_ERROR_NULL_POINTER
;
876 nsWebBrowser::Destroy() {
882 double nsWebBrowser::GetWidgetCSSToDeviceScale() {
883 return mParentWidget
? mParentWidget
->GetDefaultScale().scale
: 1.0;
887 nsWebBrowser::GetDevicePixelsPerDesktopPixel(double* aScale
) {
889 mParentWidget
? mParentWidget
->GetDesktopToDeviceScale().scale
: 1.0;
894 nsWebBrowser::SetPositionDesktopPix(int32_t aX
, int32_t aY
) {
896 // It's not clear to me whether this will be fully correct across
897 // potential multi-screen, mixed-DPI configurations for all platforms;
898 // we might need to add code paths that make it possible to pass the
899 // desktop-pix parameters all the way through to the native widget,
900 // to avoid the risk of device-pixel coords mapping to the wrong
901 // display on OS X with mixed retina/non-retina screens.
903 GetDevicePixelsPerDesktopPixel(&scale
);
904 return SetPosition(NSToIntRound(aX
* scale
), NSToIntRound(aY
* scale
));
908 nsWebBrowser::SetPosition(int32_t aX
, int32_t aY
) {
914 return SetPositionAndSize(aX
, aY
, cx
, cy
, 0);
918 nsWebBrowser::GetPosition(int32_t* aX
, int32_t* aY
) {
919 return GetPositionAndSize(aX
, aY
, nullptr, nullptr);
923 nsWebBrowser::SetSize(int32_t aCX
, int32_t aCY
, bool aRepaint
) {
929 return SetPositionAndSize(x
, y
, aCX
, aCY
,
930 aRepaint
? nsIBaseWindow::eRepaint
: 0);
934 nsWebBrowser::GetSize(int32_t* aCX
, int32_t* aCY
) {
935 return GetPositionAndSize(nullptr, nullptr, aCX
, aCY
);
939 nsWebBrowser::SetPositionAndSize(int32_t aX
, int32_t aY
, int32_t aCX
,
940 int32_t aCY
, uint32_t aFlags
) {
944 // If there is an internal widget we need to make the docShell coordinates
945 // relative to the internal widget rather than the calling app's parent.
946 // We also need to resize our widget then.
947 if (mInternalWidget
) {
949 mInternalWidget
->Resize(aX
, aY
, aCX
, aCY
,
950 !!(aFlags
& nsIBaseWindow::eRepaint
));
952 // Now reposition/ resize the doc
954 mDocShell
->SetPositionAndSize(doc_x
, doc_y
, aCX
, aCY
, aFlags
),
961 nsWebBrowser::GetPositionAndSize(int32_t* aX
, int32_t* aY
, int32_t* aCX
,
963 if (mInternalWidget
) {
964 LayoutDeviceIntRect bounds
= mInternalWidget
->GetBounds();
973 *aCX
= bounds
.Width();
976 *aCY
= bounds
.Height();
981 // Can directly return this as it is the
982 // same interface, thus same returns.
983 return mDocShell
->GetPositionAndSize(aX
, aY
, aCX
, aCY
);
987 nsWebBrowser::SetDimensions(DimensionRequest
&& aRequest
) {
988 return NS_ERROR_NOT_IMPLEMENTED
;
992 nsWebBrowser::GetDimensions(DimensionKind aDimensionKind
, int32_t* aX
,
993 int32_t* aY
, int32_t* aCX
, int32_t* aCY
) {
994 return NS_ERROR_NOT_IMPLEMENTED
;
998 nsWebBrowser::Repaint(bool aForce
) {
999 NS_ENSURE_STATE(mDocShell
);
1000 // Can directly return this as it is the
1001 // same interface, thus same returns.
1002 return mDocShell
->Repaint(aForce
);
1006 nsWebBrowser::GetParentWidget(nsIWidget
** aParentWidget
) {
1007 NS_ENSURE_ARG_POINTER(aParentWidget
);
1009 *aParentWidget
= mParentWidget
;
1011 NS_IF_ADDREF(*aParentWidget
);
1017 nsWebBrowser::SetParentWidget(nsIWidget
* aParentWidget
) {
1018 NS_ENSURE_STATE(!mDocShell
);
1019 mParentWidget
= aParentWidget
;
1024 nsWebBrowser::GetNativeHandle(nsAString
& aNativeHandle
) {
1025 // the nativeHandle should be accessed from nsIAppWindow
1026 return NS_ERROR_NOT_IMPLEMENTED
;
1030 nsWebBrowser::GetVisibility(bool* aVisibility
) {
1031 NS_ENSURE_ARG_POINTER(aVisibility
);
1034 NS_ENSURE_SUCCESS(mDocShell
->GetVisibility(aVisibility
), NS_ERROR_FAILURE
);
1041 nsWebBrowser::SetVisibility(bool aVisibility
) {
1043 NS_ENSURE_SUCCESS(mDocShell
->SetVisibility(aVisibility
), NS_ERROR_FAILURE
);
1044 if (mInternalWidget
) {
1045 mInternalWidget
->Show(aVisibility
);
1053 nsWebBrowser::GetEnabled(bool* aEnabled
) {
1054 if (mInternalWidget
) {
1055 *aEnabled
= mInternalWidget
->IsEnabled();
1059 return NS_ERROR_FAILURE
;
1063 nsWebBrowser::SetEnabled(bool aEnabled
) {
1064 if (mInternalWidget
) {
1065 mInternalWidget
->Enable(aEnabled
);
1068 return NS_ERROR_FAILURE
;
1072 nsWebBrowser::GetMainWidget(nsIWidget
** aMainWidget
) {
1073 NS_ENSURE_ARG_POINTER(aMainWidget
);
1075 if (mInternalWidget
) {
1076 *aMainWidget
= mInternalWidget
;
1078 *aMainWidget
= mParentWidget
;
1081 NS_IF_ADDREF(*aMainWidget
);
1087 nsWebBrowser::GetTitle(nsAString
& aTitle
) {
1088 NS_ENSURE_STATE(mDocShell
);
1090 NS_ENSURE_SUCCESS(mDocShell
->GetTitle(aTitle
), NS_ERROR_FAILURE
);
1096 nsWebBrowser::SetTitle(const nsAString
& aTitle
) {
1097 NS_ENSURE_STATE(mDocShell
);
1099 NS_ENSURE_SUCCESS(mDocShell
->SetTitle(aTitle
), NS_ERROR_FAILURE
);
1104 //*****************************************************************************
1105 // nsWebBrowser: Listener Helpers
1106 //*****************************************************************************
1108 void nsWebBrowser::SetDocShell(nsDocShell
* aDocShell
) {
1109 // We need to keep the docshell alive while we perform the changes, but we
1110 // don't need to call any methods on it.
1111 nsCOMPtr
<nsIDocShell
> kungFuDeathGrip(mDocShell
);
1112 mozilla::Unused
<< kungFuDeathGrip
;
1115 MOZ_ASSERT(!mDocShell
, "Should not overwrite an existing value!");
1117 mDocShell
= aDocShell
;
1119 // By default, do not allow DNS prefetch, so we don't break our frozen
1120 // API. Embeddors who decide to enable it should do so manually.
1121 mDocShell
->SetAllowDNSPrefetch(false);
1123 if (mDocShellTreeOwner
) {
1124 mDocShellTreeOwner
->RemoveFromWatcher(); // evil twin of Add in Create()
1127 mDocShell
->Destroy();
1129 if (!mWillChangeProcess
&& mDocShell
) {
1130 mDocShell
->GetBrowsingContext()->Detach(/* aFromIPC */ true);
1133 mDocShell
= nullptr;
1137 void nsWebBrowser::EnsureDocShellTreeOwner() {
1138 if (mDocShellTreeOwner
) {
1142 mDocShellTreeOwner
= new nsDocShellTreeOwner();
1143 mDocShellTreeOwner
->WebBrowser(this);
1146 void nsWebBrowser::WindowActivated() {
1147 #if defined(DEBUG_smaug)
1148 RefPtr
<dom::Document
> document
= mDocShell
->GetDocument();
1149 nsAutoString documentURI
;
1150 document
->GetDocumentURI(documentURI
);
1151 printf("nsWebBrowser::NS_ACTIVATE %p %s\n", (void*)this,
1152 NS_ConvertUTF16toUTF8(documentURI
).get());
1154 FocusActivate(nsFocusManager::GenerateFocusActionId());
1157 void nsWebBrowser::WindowDeactivated() {
1158 #if defined(DEBUG_smaug)
1159 RefPtr
<dom::Document
> document
= mDocShell
->GetDocument();
1160 nsAutoString documentURI
;
1161 document
->GetDocumentURI(documentURI
);
1162 printf("nsWebBrowser::NS_DEACTIVATE %p %s\n", (void*)this,
1163 NS_ConvertUTF16toUTF8(documentURI
).get());
1165 FocusDeactivate(nsFocusManager::GenerateFocusActionId());
1168 bool nsWebBrowser::PaintWindow(nsIWidget
* aWidget
,
1169 LayoutDeviceIntRegion aRegion
) {
1170 WindowRenderer
* renderer
= aWidget
->GetWindowRenderer();
1171 NS_ASSERTION(renderer
, "Must be in paint event");
1172 if (FallbackRenderer
* fallback
= renderer
->AsFallback()) {
1173 if (fallback
->BeginTransaction()) {
1174 fallback
->EndTransactionWithColor(aRegion
.GetBounds().ToUnknownRect(),
1175 ToDeviceColor(mBackgroundColor
));
1182 void nsWebBrowser::FocusActivate(uint64_t aActionId
) {
1183 if (RefPtr
<nsFocusManager
> fm
= nsFocusManager::GetFocusManager()) {
1184 if (nsCOMPtr
<nsPIDOMWindowOuter
> window
= GetWindow()) {
1185 fm
->WindowRaised(window
, aActionId
);
1190 void nsWebBrowser::FocusDeactivate(uint64_t aActionId
) {
1191 if (RefPtr
<nsFocusManager
> fm
= nsFocusManager::GetFocusManager()) {
1192 if (nsCOMPtr
<nsPIDOMWindowOuter
> window
= GetWindow()) {
1193 fm
->WindowLowered(window
, aActionId
);
1198 void nsWebBrowser::SetWillChangeProcess() {
1199 mWillChangeProcess
= true;
1201 nsDocShell::Cast(mDocShell
)->SetWillChangeProcess();
1205 void nsWebBrowser::WidgetListenerDelegate::WindowActivated() {
1206 RefPtr
<nsWebBrowser
> holder
= mWebBrowser
;
1207 holder
->WindowActivated();
1210 void nsWebBrowser::WidgetListenerDelegate::WindowDeactivated() {
1211 RefPtr
<nsWebBrowser
> holder
= mWebBrowser
;
1212 holder
->WindowDeactivated();
1215 bool nsWebBrowser::WidgetListenerDelegate::PaintWindow(
1216 nsIWidget
* aWidget
, mozilla::LayoutDeviceIntRegion aRegion
) {
1217 RefPtr
<nsWebBrowser
> holder
= mWebBrowser
;
1218 return holder
->PaintWindow(aWidget
, aRegion
);