1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 // Local Includes
8 #include "nsWebBrowser.h"
9
10 // Helper Classes
11 #include "nsGfxCIID.h"
12 #include "nsWidgetsCID.h"
13
14 #include "gfxUtils.h"
15 #include "mozilla/gfx/2D.h"
16
17 // Interfaces Needed
18 #include "gfxContext.h"
19 #include "nsReadableUtils.h"
20 #include "nsIInterfaceRequestor.h"
21 #include "nsIInterfaceRequestorUtils.h"
22 #include "nsIWebBrowserChrome.h"
23 #include "nsPIDOMWindow.h"
24 #include "nsIWebProgress.h"
25 #include "nsIWebProgressListener.h"
26 #include "nsIURI.h"
27 #include "nsIWebBrowserPersist.h"
28 #include "nsFocusManager.h"
29 #include "Layers.h"
30 #include "nsILoadContext.h"
31 #include "nsComponentManagerUtils.h"
32 #include "nsDocShell.h"
33 #include "nsServiceManagerUtils.h"
34
35 #include "mozilla/dom/Element.h"
36 #include "mozilla/dom/BrowsingContext.h"
37 #include "mozilla/dom/LoadURIOptionsBinding.h"
38 #include "mozilla/dom/WindowGlobalChild.h"
39
40 // for painting the background window
41 #include "mozilla/LookAndFeel.h"
42 #include "mozilla/ServoStyleConsts.h"
43
44 // Printing Includes
45 #ifdef NS_PRINTING
46 # include "nsIWebBrowserPrint.h"
47 # include "nsIContentViewer.h"
48 #endif
49
50 // PSM2 includes
51 #include "nsISecureBrowserUI.h"
52 #include "nsXULAppAPI.h"
53
54 using namespace mozilla;
55 using namespace mozilla::gfx;
56 using namespace mozilla::layers;
57
nsWebBrowser(int aItemType)58 nsWebBrowser::nsWebBrowser(int aItemType)
59 : mContentType(aItemType),
60 mShouldEnableHistory(true),
61 mWillChangeProcess(false),
62 mParentNativeWindow(nullptr),
63 mProgressListener(nullptr),
64 mWidgetListenerDelegate(this),
65 mBackgroundColor(0),
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");
72 }
73
~nsWebBrowser()74 nsWebBrowser::~nsWebBrowser() { InternalDestroy(); }
75
EnsureWidget()76 nsIWidget* nsWebBrowser::EnsureWidget() {
77 if (mParentWidget) {
78 return mParentWidget;
79 }
80
81 mInternalWidget = nsIWidget::CreateChildWindow();
82 if (NS_WARN_IF(!mInternalWidget)) {
83 return nullptr;
84 }
85
86 nsWidgetInitData widgetInit;
87 widgetInit.clipChildren = true;
88 widgetInit.mWindowType = eWindowType_child;
89 LayoutDeviceIntRect bounds(0, 0, 0, 0);
90
91 mInternalWidget->SetWidgetListener(&mWidgetListenerDelegate);
92 NS_ENSURE_SUCCESS(mInternalWidget->Create(nullptr, mParentNativeWindow,
93 bounds, &widgetInit),
94 nullptr);
95
96 return mInternalWidget;
97 }
98
99 /* static */
Create(nsIWebBrowserChrome * aContainerWindow,nsIWidget * aParentWidget,dom::BrowsingContext * aBrowsingContext,dom::WindowGlobalChild * aInitialWindowChild)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);
106
107 RefPtr<nsWebBrowser> browser = new nsWebBrowser(
108 aBrowsingContext->IsContent() ? typeContentWrapper : typeChromeWrapper);
109
110 // nsWebBrowser::SetContainer also calls nsWebBrowser::EnsureDocShellTreeOwner
111 NS_ENSURE_SUCCESS(browser->SetContainerWindow(aContainerWindow), nullptr);
112 NS_ENSURE_SUCCESS(browser->SetParentWidget(aParentWidget), nullptr);
113
114 nsCOMPtr<nsIWidget> docShellParentWidget = browser->EnsureWidget();
115 if (NS_WARN_IF(!docShellParentWidget)) {
116 return nullptr;
117 }
118
119 uint64_t outerWindowId =
120 aInitialWindowChild ? aInitialWindowChild->OuterWindowId() : 0;
121
122 RefPtr<nsDocShell> docShell =
123 nsDocShell::Create(aBrowsingContext, outerWindowId);
124 if (NS_WARN_IF(!docShell)) {
125 return nullptr;
126 }
127 browser->SetDocShell(docShell);
128 MOZ_ASSERT(browser->mDocShell == docShell);
129
130 // get the system default window background colour
131 //
132 // TODO(emilio): Can we get the color-scheme from somewhere here?
133 browser->mBackgroundColor = LookAndFeel::Color(
134 LookAndFeel::ColorID::WindowBackground, LookAndFeel::ColorScheme::Light,
135 LookAndFeel::UseStandins::No);
136
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);
145
146 docShell->SetTreeOwner(docShellTreeOwner);
147
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
151 // event.
152
153 nsresult rv = docShell->InitWindow(nullptr, docShellParentWidget, 0, 0, 0, 0);
154 if (NS_WARN_IF(NS_FAILED(rv))) {
155 return nullptr;
156 }
157
158 docShellTreeOwner->AddToWatcher(); // evil twin of Remove in SetDocShell(0)
159 docShellTreeOwner->AddChromeListeners();
160
161 if (aInitialWindowChild) {
162 docShell->CreateContentViewerForActor(aInitialWindowChild);
163 }
164
165 return browser.forget();
166 }
167
InternalDestroy()168 void nsWebBrowser::InternalDestroy() {
169 if (mInternalWidget) {
170 mInternalWidget->SetWidgetListener(nullptr);
171 mInternalWidget->Destroy();
172 mInternalWidget = nullptr; // Force release here.
173 }
174
175 SetDocShell(nullptr);
176
177 if (mDocShellTreeOwner) {
178 mDocShellTreeOwner->WebBrowser(nullptr);
179 mDocShellTreeOwner = nullptr;
180 }
181 }
182
183 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWebBrowser)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWebBrowser)184 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWebBrowser)
185
186 NS_IMPL_CYCLE_COLLECTION_WEAK(nsWebBrowser, mDocShell)
187
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)
199 NS_INTERFACE_MAP_END
200
201 ///*****************************************************************************
202 // nsWebBrowser::nsIInterfaceRequestor
203 //*****************************************************************************
204
205 NS_IMETHODIMP
206 nsWebBrowser::GetInterface(const nsIID& aIID, void** aSink) {
207 NS_ENSURE_ARG_POINTER(aSink);
208
209 if (NS_SUCCEEDED(QueryInterface(aIID, aSink))) {
210 return NS_OK;
211 }
212
213 if (mDocShell) {
214 #ifdef NS_PRINTING
215 if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) {
216 nsCOMPtr<nsIContentViewer> viewer;
217 mDocShell->GetContentViewer(getter_AddRefs(viewer));
218 if (!viewer) {
219 return NS_NOINTERFACE;
220 }
221
222 nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint(do_QueryInterface(viewer));
223 nsIWebBrowserPrint* print = (nsIWebBrowserPrint*)webBrowserPrint.get();
224 NS_ASSERTION(print, "This MUST support this interface!");
225 NS_ADDREF(print);
226 *aSink = print;
227 return NS_OK;
228 }
229 #endif
230 return mDocShell->GetInterface(aIID, aSink);
231 }
232
233 return NS_NOINTERFACE;
234 }
235
236 //*****************************************************************************
237 // nsWebBrowser::nsIWebBrowser
238 //*****************************************************************************
239
240 NS_IMETHODIMP
GetContainerWindow(nsIWebBrowserChrome ** aTopWindow)241 nsWebBrowser::GetContainerWindow(nsIWebBrowserChrome** aTopWindow) {
242 NS_ENSURE_ARG_POINTER(aTopWindow);
243
244 nsCOMPtr<nsIWebBrowserChrome> top;
245 if (mDocShellTreeOwner) {
246 top = mDocShellTreeOwner->GetWebBrowserChrome();
247 }
248
249 top.forget(aTopWindow);
250
251 return NS_OK;
252 }
253
254 NS_IMETHODIMP
SetContainerWindow(nsIWebBrowserChrome * aTopWindow)255 nsWebBrowser::SetContainerWindow(nsIWebBrowserChrome* aTopWindow) {
256 EnsureDocShellTreeOwner();
257 return mDocShellTreeOwner->SetWebBrowserChrome(aTopWindow);
258 }
259
260 NS_IMETHODIMP
GetContentDOMWindow(mozIDOMWindowProxy ** aResult)261 nsWebBrowser::GetContentDOMWindow(mozIDOMWindowProxy** aResult) {
262 if (!mDocShell) {
263 return NS_ERROR_UNEXPECTED;
264 }
265
266 nsCOMPtr<nsPIDOMWindowOuter> retval = mDocShell->GetWindow();
267 retval.forget(aResult);
268 return *aResult ? NS_OK : NS_ERROR_FAILURE;
269 }
270
SetOriginAttributes(const OriginAttributes & aAttrs)271 void nsWebBrowser::SetOriginAttributes(const OriginAttributes& aAttrs) {
272 mOriginAttributes = aAttrs;
273 }
274
275 //*****************************************************************************
276 // nsWebBrowser::nsIDocShellTreeItem
277 //*****************************************************************************
278
279 NS_IMETHODIMP
GetName(nsAString & aName)280 nsWebBrowser::GetName(nsAString& aName) {
281 if (mDocShell) {
282 mDocShell->GetName(aName);
283 }
284
285 return NS_OK;
286 }
287
288 NS_IMETHODIMP
SetName(const nsAString & aName)289 nsWebBrowser::SetName(const nsAString& aName) {
290 if (mDocShell) {
291 return mDocShell->SetName(aName);
292 }
293
294 return NS_OK;
295 }
296
297 NS_IMETHODIMP
NameEquals(const nsAString & aName,bool * aResult)298 nsWebBrowser::NameEquals(const nsAString& aName, bool* aResult) {
299 NS_ENSURE_ARG_POINTER(aResult);
300 if (mDocShell) {
301 return mDocShell->NameEquals(aName, aResult);
302 }
303
304 return NS_OK;
305 }
306
307 /* virtual */
ItemType()308 int32_t nsWebBrowser::ItemType() { return mContentType; }
309
310 NS_IMETHODIMP
GetItemType(int32_t * aItemType)311 nsWebBrowser::GetItemType(int32_t* aItemType) {
312 NS_ENSURE_ARG_POINTER(aItemType);
313
314 *aItemType = ItemType();
315 return NS_OK;
316 }
317
318 NS_IMETHODIMP
GetInProcessParent(nsIDocShellTreeItem ** aParent)319 nsWebBrowser::GetInProcessParent(nsIDocShellTreeItem** aParent) {
320 *aParent = nullptr;
321 return NS_OK;
322 }
323
324 NS_IMETHODIMP
GetInProcessSameTypeParent(nsIDocShellTreeItem ** aParent)325 nsWebBrowser::GetInProcessSameTypeParent(nsIDocShellTreeItem** aParent) {
326 *aParent = nullptr;
327
328 return NS_OK;
329 }
330
331 NS_IMETHODIMP
GetInProcessRootTreeItem(nsIDocShellTreeItem ** aRootTreeItem)332 nsWebBrowser::GetInProcessRootTreeItem(nsIDocShellTreeItem** aRootTreeItem) {
333 NS_ENSURE_ARG_POINTER(aRootTreeItem);
334 *aRootTreeItem = static_cast<nsIDocShellTreeItem*>(this);
335
336 nsCOMPtr<nsIDocShellTreeItem> parent;
337 NS_ENSURE_SUCCESS(GetInProcessParent(getter_AddRefs(parent)),
338 NS_ERROR_FAILURE);
339 while (parent) {
340 *aRootTreeItem = parent;
341 NS_ENSURE_SUCCESS(
342 (*aRootTreeItem)->GetInProcessParent(getter_AddRefs(parent)),
343 NS_ERROR_FAILURE);
344 }
345 NS_ADDREF(*aRootTreeItem);
346 return NS_OK;
347 }
348
349 NS_IMETHODIMP
GetInProcessSameTypeRootTreeItem(nsIDocShellTreeItem ** aRootTreeItem)350 nsWebBrowser::GetInProcessSameTypeRootTreeItem(
351 nsIDocShellTreeItem** aRootTreeItem) {
352 NS_ENSURE_ARG_POINTER(aRootTreeItem);
353 *aRootTreeItem = static_cast<nsIDocShellTreeItem*>(this);
354
355 nsCOMPtr<nsIDocShellTreeItem> parent;
356 NS_ENSURE_SUCCESS(GetInProcessSameTypeParent(getter_AddRefs(parent)),
357 NS_ERROR_FAILURE);
358 while (parent) {
359 *aRootTreeItem = parent;
360 NS_ENSURE_SUCCESS(
361 (*aRootTreeItem)->GetInProcessSameTypeParent(getter_AddRefs(parent)),
362 NS_ERROR_FAILURE);
363 }
364 NS_ADDREF(*aRootTreeItem);
365 return NS_OK;
366 }
367
GetDocument()368 dom::Document* nsWebBrowser::GetDocument() {
369 return mDocShell ? mDocShell->GetDocument() : nullptr;
370 }
371
GetWindow()372 nsPIDOMWindowOuter* nsWebBrowser::GetWindow() {
373 return mDocShell ? mDocShell->GetWindow() : nullptr;
374 }
375
376 NS_IMETHODIMP
GetBrowsingContextXPCOM(dom::BrowsingContext ** aBrowsingContext)377 nsWebBrowser::GetBrowsingContextXPCOM(dom::BrowsingContext** aBrowsingContext) {
378 NS_ENSURE_STATE(mDocShell);
379 return mDocShell->GetBrowsingContextXPCOM(aBrowsingContext);
380 }
381
GetBrowsingContext()382 dom::BrowsingContext* nsWebBrowser::GetBrowsingContext() {
383 return mDocShell->GetBrowsingContext();
384 }
385
386 NS_IMETHODIMP
GetDomWindow(mozIDOMWindowProxy ** aWindow)387 nsWebBrowser::GetDomWindow(mozIDOMWindowProxy** aWindow) {
388 if (!mDocShell) return NS_ERROR_NOT_INITIALIZED;
389 return mDocShell->GetDomWindow(aWindow);
390 }
391
392 NS_IMETHODIMP
GetTreeOwner(nsIDocShellTreeOwner ** aTreeOwner)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;
399 } else {
400 *aTreeOwner = mDocShellTreeOwner;
401 }
402 }
403 NS_IF_ADDREF(*aTreeOwner);
404 return NS_OK;
405 }
406
407 NS_IMETHODIMP
SetTreeOwner(nsIDocShellTreeOwner * aTreeOwner)408 nsWebBrowser::SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner) {
409 EnsureDocShellTreeOwner();
410 return mDocShellTreeOwner->SetTreeOwner(aTreeOwner);
411 }
412
413 //*****************************************************************************
414 // nsWebBrowser::nsIDocShellTreeItem
415 //*****************************************************************************
416
417 NS_IMETHODIMP
GetInProcessChildCount(int32_t * aChildCount)418 nsWebBrowser::GetInProcessChildCount(int32_t* aChildCount) {
419 NS_ENSURE_ARG_POINTER(aChildCount);
420 *aChildCount = 0;
421 return NS_OK;
422 }
423
424 NS_IMETHODIMP
AddChild(nsIDocShellTreeItem * aChild)425 nsWebBrowser::AddChild(nsIDocShellTreeItem* aChild) {
426 return NS_ERROR_UNEXPECTED;
427 }
428
429 NS_IMETHODIMP
RemoveChild(nsIDocShellTreeItem * aChild)430 nsWebBrowser::RemoveChild(nsIDocShellTreeItem* aChild) {
431 return NS_ERROR_UNEXPECTED;
432 }
433
434 NS_IMETHODIMP
GetInProcessChildAt(int32_t aIndex,nsIDocShellTreeItem ** aChild)435 nsWebBrowser::GetInProcessChildAt(int32_t aIndex,
436 nsIDocShellTreeItem** aChild) {
437 return NS_ERROR_UNEXPECTED;
438 }
439
440 //*****************************************************************************
441 // nsWebBrowser::nsIWebNavigation
442 //*****************************************************************************
443
444 NS_IMETHODIMP
GetCanGoBack(bool * aCanGoBack)445 nsWebBrowser::GetCanGoBack(bool* aCanGoBack) {
446 NS_ENSURE_STATE(mDocShell);
447
448 return mDocShell->GetCanGoBack(aCanGoBack);
449 }
450
451 NS_IMETHODIMP
GetCanGoForward(bool * aCanGoForward)452 nsWebBrowser::GetCanGoForward(bool* aCanGoForward) {
453 NS_ENSURE_STATE(mDocShell);
454
455 return mDocShell->GetCanGoForward(aCanGoForward);
456 }
457
458 NS_IMETHODIMP
GoBack(bool aRequireUserInteraction,bool aUserActivation)459 nsWebBrowser::GoBack(bool aRequireUserInteraction, bool aUserActivation) {
460 NS_ENSURE_STATE(mDocShell);
461
462 return mDocShell->GoBack(aRequireUserInteraction, aUserActivation);
463 }
464
465 NS_IMETHODIMP
GoForward(bool aRequireUserInteraction,bool aUserActivation)466 nsWebBrowser::GoForward(bool aRequireUserInteraction, bool aUserActivation) {
467 NS_ENSURE_STATE(mDocShell);
468
469 return mDocShell->GoForward(aRequireUserInteraction, aUserActivation);
470 }
471
LoadURI(const nsAString & aURI,const dom::LoadURIOptions & aLoadURIOptions)472 nsresult nsWebBrowser::LoadURI(const nsAString& aURI,
473 const dom::LoadURIOptions& aLoadURIOptions) {
474 #ifndef ANDROID
475 MOZ_ASSERT(aLoadURIOptions.mTriggeringPrincipal,
476 "nsWebBrowser::LoadURI - Need a valid triggeringPrincipal");
477 #endif
478 NS_ENSURE_STATE(mDocShell);
479
480 return mDocShell->LoadURI(aURI, aLoadURIOptions);
481 }
482
483 NS_IMETHODIMP
LoadURIFromScript(const nsAString & aURI,JS::Handle<JS::Value> aLoadURIOptions,JSContext * aCx)484 nsWebBrowser::LoadURIFromScript(const nsAString& aURI,
485 JS::Handle<JS::Value> aLoadURIOptions,
486 JSContext* aCx) {
487 // generate dictionary for loadURIOptions and forward call
488 dom::LoadURIOptions loadURIOptions;
489 if (!loadURIOptions.Init(aCx, aLoadURIOptions)) {
490 return NS_ERROR_INVALID_ARG;
491 }
492 return LoadURI(aURI, loadURIOptions);
493 }
494
495 NS_IMETHODIMP
ResumeRedirectedLoad(uint64_t aIdentifier,int32_t aHistoryIndex)496 nsWebBrowser::ResumeRedirectedLoad(uint64_t aIdentifier,
497 int32_t aHistoryIndex) {
498 NS_ENSURE_STATE(mDocShell);
499
500 return mDocShell->ResumeRedirectedLoad(aIdentifier, aHistoryIndex);
501 }
502
503 NS_IMETHODIMP
Reload(uint32_t aReloadFlags)504 nsWebBrowser::Reload(uint32_t aReloadFlags) {
505 NS_ENSURE_STATE(mDocShell);
506
507 return mDocShell->Reload(aReloadFlags);
508 }
509
510 NS_IMETHODIMP
GotoIndex(int32_t aIndex,bool aUserActivation)511 nsWebBrowser::GotoIndex(int32_t aIndex, bool aUserActivation) {
512 NS_ENSURE_STATE(mDocShell);
513
514 return mDocShell->GotoIndex(aIndex, aUserActivation);
515 }
516
517 NS_IMETHODIMP
Stop(uint32_t aStopFlags)518 nsWebBrowser::Stop(uint32_t aStopFlags) {
519 NS_ENSURE_STATE(mDocShell);
520
521 return mDocShell->Stop(aStopFlags);
522 }
523
524 NS_IMETHODIMP
GetCurrentURI(nsIURI ** aURI)525 nsWebBrowser::GetCurrentURI(nsIURI** aURI) {
526 NS_ENSURE_STATE(mDocShell);
527
528 return mDocShell->GetCurrentURI(aURI);
529 }
530
531 // XXX(nika): Consider making the mozilla::dom::ChildSHistory version the
532 // canonical one?
533 NS_IMETHODIMP
GetSessionHistoryXPCOM(nsISupports ** aSessionHistory)534 nsWebBrowser::GetSessionHistoryXPCOM(nsISupports** aSessionHistory) {
535 NS_ENSURE_ARG_POINTER(aSessionHistory);
536 *aSessionHistory = nullptr;
537 if (mDocShell) {
538 return mDocShell->GetSessionHistoryXPCOM(aSessionHistory);
539 }
540 return NS_OK;
541 }
542
543 NS_IMETHODIMP
GetDocument(dom::Document ** aDocument)544 nsWebBrowser::GetDocument(dom::Document** aDocument) {
545 NS_ENSURE_STATE(mDocShell);
546
547 return mDocShell->GetDocument(aDocument);
548 }
549
SetAllowDNSPrefetch(bool aAllowPrefetch)550 void nsWebBrowser::SetAllowDNSPrefetch(bool aAllowPrefetch) {
551 MOZ_ASSERT(mDocShell);
552 mDocShell->SetAllowDNSPrefetch(aAllowPrefetch);
553 }
554
555 //*****************************************************************************
556 // nsWebBrowser::nsIWebProgressListener
557 //*****************************************************************************
558
559 NS_IMETHODIMP
OnStateChange(nsIWebProgress * aWebProgress,nsIRequest * aRequest,uint32_t aStateFlags,nsresult aStatus)560 nsWebBrowser::OnStateChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
561 uint32_t aStateFlags, nsresult aStatus) {
562 if (mPersist) {
563 mPersist->GetCurrentState(&mPersistCurrentState);
564 }
565 if (aStateFlags & STATE_IS_NETWORK && aStateFlags & STATE_STOP) {
566 mPersist = nullptr;
567 }
568 if (mProgressListener) {
569 return mProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags,
570 aStatus);
571 }
572 return NS_OK;
573 }
574
575 NS_IMETHODIMP
OnProgressChange(nsIWebProgress * aWebProgress,nsIRequest * aRequest,int32_t aCurSelfProgress,int32_t aMaxSelfProgress,int32_t aCurTotalProgress,int32_t aMaxTotalProgress)576 nsWebBrowser::OnProgressChange(nsIWebProgress* aWebProgress,
577 nsIRequest* aRequest, int32_t aCurSelfProgress,
578 int32_t aMaxSelfProgress,
579 int32_t aCurTotalProgress,
580 int32_t aMaxTotalProgress) {
581 if (mPersist) {
582 mPersist->GetCurrentState(&mPersistCurrentState);
583 }
584 if (mProgressListener) {
585 return mProgressListener->OnProgressChange(
586 aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress,
587 aCurTotalProgress, aMaxTotalProgress);
588 }
589 return NS_OK;
590 }
591
592 NS_IMETHODIMP
OnLocationChange(nsIWebProgress * aWebProgress,nsIRequest * aRequest,nsIURI * aLocation,uint32_t aFlags)593 nsWebBrowser::OnLocationChange(nsIWebProgress* aWebProgress,
594 nsIRequest* aRequest, nsIURI* aLocation,
595 uint32_t aFlags) {
596 if (mProgressListener) {
597 return mProgressListener->OnLocationChange(aWebProgress, aRequest,
598 aLocation, aFlags);
599 }
600 return NS_OK;
601 }
602
603 NS_IMETHODIMP
OnStatusChange(nsIWebProgress * aWebProgress,nsIRequest * aRequest,nsresult aStatus,const char16_t * aMessage)604 nsWebBrowser::OnStatusChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
605 nsresult aStatus, const char16_t* aMessage) {
606 if (mProgressListener) {
607 return mProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus,
608 aMessage);
609 }
610 return NS_OK;
611 }
612
613 NS_IMETHODIMP
OnSecurityChange(nsIWebProgress * aWebProgress,nsIRequest * aRequest,uint32_t aState)614 nsWebBrowser::OnSecurityChange(nsIWebProgress* aWebProgress,
615 nsIRequest* aRequest, uint32_t aState) {
616 if (mProgressListener) {
617 return mProgressListener->OnSecurityChange(aWebProgress, aRequest, aState);
618 }
619 return NS_OK;
620 }
621
622 NS_IMETHODIMP
OnContentBlockingEvent(nsIWebProgress * aWebProgress,nsIRequest * aRequest,uint32_t aEvent)623 nsWebBrowser::OnContentBlockingEvent(nsIWebProgress* aWebProgress,
624 nsIRequest* aRequest, uint32_t aEvent) {
625 if (mProgressListener) {
626 return mProgressListener->OnContentBlockingEvent(aWebProgress, aRequest,
627 aEvent);
628 }
629 return NS_OK;
630 }
631
632 //*****************************************************************************
633 // nsWebBrowser::nsIWebBrowserPersist
634 //*****************************************************************************
635
636 NS_IMETHODIMP
GetPersistFlags(uint32_t * aPersistFlags)637 nsWebBrowser::GetPersistFlags(uint32_t* aPersistFlags) {
638 NS_ENSURE_ARG_POINTER(aPersistFlags);
639 nsresult rv = NS_OK;
640 if (mPersist) {
641 rv = mPersist->GetPersistFlags(&mPersistFlags);
642 }
643 *aPersistFlags = mPersistFlags;
644 return rv;
645 }
646
647 NS_IMETHODIMP
SetPersistFlags(uint32_t aPersistFlags)648 nsWebBrowser::SetPersistFlags(uint32_t aPersistFlags) {
649 nsresult rv = NS_OK;
650 mPersistFlags = aPersistFlags;
651 if (mPersist) {
652 rv = mPersist->SetPersistFlags(mPersistFlags);
653 mPersist->GetPersistFlags(&mPersistFlags);
654 }
655 return rv;
656 }
657
658 NS_IMETHODIMP
GetCurrentState(uint32_t * aCurrentState)659 nsWebBrowser::GetCurrentState(uint32_t* aCurrentState) {
660 NS_ENSURE_ARG_POINTER(aCurrentState);
661 if (mPersist) {
662 mPersist->GetCurrentState(&mPersistCurrentState);
663 }
664 *aCurrentState = mPersistCurrentState;
665 return NS_OK;
666 }
667
668 NS_IMETHODIMP
GetResult(nsresult * aResult)669 nsWebBrowser::GetResult(nsresult* aResult) {
670 NS_ENSURE_ARG_POINTER(aResult);
671 if (mPersist) {
672 mPersist->GetResult(&mPersistResult);
673 }
674 *aResult = mPersistResult;
675 return NS_OK;
676 }
677
678 NS_IMETHODIMP
GetProgressListener(nsIWebProgressListener ** aProgressListener)679 nsWebBrowser::GetProgressListener(nsIWebProgressListener** aProgressListener) {
680 NS_ENSURE_ARG_POINTER(aProgressListener);
681 *aProgressListener = mProgressListener;
682 NS_IF_ADDREF(*aProgressListener);
683 return NS_OK;
684 }
685
686 NS_IMETHODIMP
SetProgressListener(nsIWebProgressListener * aProgressListener)687 nsWebBrowser::SetProgressListener(nsIWebProgressListener* aProgressListener) {
688 mProgressListener = aProgressListener;
689 return NS_OK;
690 }
691
692 NS_IMETHODIMP
SaveURI(nsIURI * aURI,nsIPrincipal * aPrincipal,uint32_t aCacheKey,nsIReferrerInfo * aReferrerInfo,nsICookieJarSettings * aCookieJarSettings,nsIInputStream * aPostData,const char * aExtraHeaders,nsISupports * aFile,nsContentPolicyType aContentPolicyType,nsILoadContext * aPrivacyContext)693 nsWebBrowser::SaveURI(nsIURI* aURI, nsIPrincipal* aPrincipal,
694 uint32_t aCacheKey, nsIReferrerInfo* aReferrerInfo,
695 nsICookieJarSettings* aCookieJarSettings,
696 nsIInputStream* aPostData, const char* aExtraHeaders,
697 nsISupports* aFile,
698 nsContentPolicyType aContentPolicyType,
699 nsILoadContext* aPrivacyContext) {
700 return SavePrivacyAwareURI(
701 aURI, aPrincipal, aCacheKey, aReferrerInfo, aCookieJarSettings, aPostData,
702 aExtraHeaders, aFile, aContentPolicyType,
703 aPrivacyContext && aPrivacyContext->UsePrivateBrowsing());
704 }
705
706 NS_IMETHODIMP
SavePrivacyAwareURI(nsIURI * aURI,nsIPrincipal * aPrincipal,uint32_t aCacheKey,nsIReferrerInfo * aReferrerInfo,nsICookieJarSettings * aCookieJarSettings,nsIInputStream * aPostData,const char * aExtraHeaders,nsISupports * aFile,nsContentPolicyType aContentPolicyType,bool aIsPrivate)707 nsWebBrowser::SavePrivacyAwareURI(
708 nsIURI* aURI, nsIPrincipal* aPrincipal, uint32_t aCacheKey,
709 nsIReferrerInfo* aReferrerInfo, nsICookieJarSettings* aCookieJarSettings,
710 nsIInputStream* aPostData, const char* aExtraHeaders, nsISupports* aFile,
711 nsContentPolicyType aContentPolicyType, bool aIsPrivate) {
712 if (mPersist) {
713 uint32_t currentState;
714 mPersist->GetCurrentState(¤tState);
715 if (currentState == PERSIST_STATE_FINISHED) {
716 mPersist = nullptr;
717 } else {
718 // You can't save again until the last save has completed
719 return NS_ERROR_FAILURE;
720 }
721 }
722
723 nsCOMPtr<nsIURI> uri;
724 if (aURI) {
725 uri = aURI;
726 } else {
727 nsresult rv = GetCurrentURI(getter_AddRefs(uri));
728 if (NS_FAILED(rv)) {
729 return NS_ERROR_FAILURE;
730 }
731 }
732
733 // Create a throwaway persistence object to do the work
734 nsresult rv;
735 mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
736 NS_ENSURE_SUCCESS(rv, rv);
737 mPersist->SetProgressListener(this);
738 mPersist->SetPersistFlags(mPersistFlags);
739 mPersist->GetCurrentState(&mPersistCurrentState);
740
741 rv = mPersist->SavePrivacyAwareURI(
742 uri, aPrincipal, aCacheKey, aReferrerInfo, aCookieJarSettings, aPostData,
743 aExtraHeaders, aFile, aContentPolicyType, aIsPrivate);
744 if (NS_FAILED(rv)) {
745 mPersist = nullptr;
746 }
747 return rv;
748 }
749
750 NS_IMETHODIMP
SaveChannel(nsIChannel * aChannel,nsISupports * aFile)751 nsWebBrowser::SaveChannel(nsIChannel* aChannel, nsISupports* aFile) {
752 if (mPersist) {
753 uint32_t currentState;
754 mPersist->GetCurrentState(¤tState);
755 if (currentState == PERSIST_STATE_FINISHED) {
756 mPersist = nullptr;
757 } else {
758 // You can't save again until the last save has completed
759 return NS_ERROR_FAILURE;
760 }
761 }
762
763 // Create a throwaway persistence object to do the work
764 nsresult rv;
765 mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
766 NS_ENSURE_SUCCESS(rv, rv);
767 mPersist->SetProgressListener(this);
768 mPersist->SetPersistFlags(mPersistFlags);
769 mPersist->GetCurrentState(&mPersistCurrentState);
770 rv = mPersist->SaveChannel(aChannel, aFile);
771 if (NS_FAILED(rv)) {
772 mPersist = nullptr;
773 }
774 return rv;
775 }
776
777 NS_IMETHODIMP
SaveDocument(nsISupports * aDocumentish,nsISupports * aFile,nsISupports * aDataPath,const char * aOutputContentType,uint32_t aEncodingFlags,uint32_t aWrapColumn)778 nsWebBrowser::SaveDocument(nsISupports* aDocumentish, nsISupports* aFile,
779 nsISupports* aDataPath,
780 const char* aOutputContentType,
781 uint32_t aEncodingFlags, uint32_t aWrapColumn) {
782 if (mPersist) {
783 uint32_t currentState;
784 mPersist->GetCurrentState(¤tState);
785 if (currentState == PERSIST_STATE_FINISHED) {
786 mPersist = nullptr;
787 } else {
788 // You can't save again until the last save has completed
789 return NS_ERROR_FAILURE;
790 }
791 }
792
793 // Use the specified DOM document, or if none is specified, the one
794 // attached to the web browser.
795
796 nsCOMPtr<nsISupports> doc;
797 if (aDocumentish) {
798 doc = aDocumentish;
799 } else {
800 RefPtr<dom::Document> domDoc;
801 GetDocument(getter_AddRefs(domDoc));
802 doc = already_AddRefed<nsISupports>(ToSupports(domDoc.forget().take()));
803 }
804 if (!doc) {
805 return NS_ERROR_FAILURE;
806 }
807
808 // Create a throwaway persistence object to do the work
809 nsresult rv;
810 mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
811 NS_ENSURE_SUCCESS(rv, rv);
812 mPersist->SetProgressListener(this);
813 mPersist->SetPersistFlags(mPersistFlags);
814 mPersist->GetCurrentState(&mPersistCurrentState);
815 rv = mPersist->SaveDocument(doc, aFile, aDataPath, aOutputContentType,
816 aEncodingFlags, aWrapColumn);
817 if (NS_FAILED(rv)) {
818 mPersist = nullptr;
819 }
820 return rv;
821 }
822
823 NS_IMETHODIMP
CancelSave()824 nsWebBrowser::CancelSave() {
825 if (mPersist) {
826 return mPersist->CancelSave();
827 }
828 return NS_OK;
829 }
830
831 NS_IMETHODIMP
Cancel(nsresult aReason)832 nsWebBrowser::Cancel(nsresult aReason) {
833 if (mPersist) {
834 return mPersist->Cancel(aReason);
835 }
836 return NS_OK;
837 }
838
839 //*****************************************************************************
840 // nsWebBrowser::nsIBaseWindow
841 //*****************************************************************************
842
843 NS_IMETHODIMP
InitWindow(nativeWindow aParentNativeWindow,nsIWidget * aParentWidget,int32_t aX,int32_t aY,int32_t aCX,int32_t aCY)844 nsWebBrowser::InitWindow(nativeWindow aParentNativeWindow,
845 nsIWidget* aParentWidget, int32_t aX, int32_t aY,
846 int32_t aCX, int32_t aCY) {
847 // nsIBaseWindow::InitWindow and nsIBaseWindow::Create
848 // implementations have been merged into nsWebBrowser::Create
849 MOZ_DIAGNOSTIC_ASSERT(false);
850 return NS_ERROR_NULL_POINTER;
851 }
852
853 NS_IMETHODIMP
Destroy()854 nsWebBrowser::Destroy() {
855 InternalDestroy();
856
857 return NS_OK;
858 }
859
860 NS_IMETHODIMP
GetUnscaledDevicePixelsPerCSSPixel(double * aScale)861 nsWebBrowser::GetUnscaledDevicePixelsPerCSSPixel(double* aScale) {
862 *aScale = mParentWidget ? mParentWidget->GetDefaultScale().scale : 1.0;
863 return NS_OK;
864 }
865
866 NS_IMETHODIMP
GetDevicePixelsPerDesktopPixel(double * aScale)867 nsWebBrowser::GetDevicePixelsPerDesktopPixel(double* aScale) {
868 *aScale =
869 mParentWidget ? mParentWidget->GetDesktopToDeviceScale().scale : 1.0;
870 return NS_OK;
871 }
872
873 NS_IMETHODIMP
SetPositionDesktopPix(int32_t aX,int32_t aY)874 nsWebBrowser::SetPositionDesktopPix(int32_t aX, int32_t aY) {
875 // XXX jfkthame
876 // It's not clear to me whether this will be fully correct across
877 // potential multi-screen, mixed-DPI configurations for all platforms;
878 // we might need to add code paths that make it possible to pass the
879 // desktop-pix parameters all the way through to the native widget,
880 // to avoid the risk of device-pixel coords mapping to the wrong
881 // display on OS X with mixed retina/non-retina screens.
882 double scale = 1.0;
883 GetDevicePixelsPerDesktopPixel(&scale);
884 return SetPosition(NSToIntRound(aX * scale), NSToIntRound(aY * scale));
885 }
886
887 NS_IMETHODIMP
SetPosition(int32_t aX,int32_t aY)888 nsWebBrowser::SetPosition(int32_t aX, int32_t aY) {
889 int32_t cx = 0;
890 int32_t cy = 0;
891
892 GetSize(&cx, &cy);
893
894 return SetPositionAndSize(aX, aY, cx, cy, 0);
895 }
896
897 NS_IMETHODIMP
GetPosition(int32_t * aX,int32_t * aY)898 nsWebBrowser::GetPosition(int32_t* aX, int32_t* aY) {
899 return GetPositionAndSize(aX, aY, nullptr, nullptr);
900 }
901
902 NS_IMETHODIMP
SetSize(int32_t aCX,int32_t aCY,bool aRepaint)903 nsWebBrowser::SetSize(int32_t aCX, int32_t aCY, bool aRepaint) {
904 int32_t x = 0;
905 int32_t y = 0;
906
907 GetPosition(&x, &y);
908
909 return SetPositionAndSize(x, y, aCX, aCY,
910 aRepaint ? nsIBaseWindow::eRepaint : 0);
911 }
912
913 NS_IMETHODIMP
GetSize(int32_t * aCX,int32_t * aCY)914 nsWebBrowser::GetSize(int32_t* aCX, int32_t* aCY) {
915 return GetPositionAndSize(nullptr, nullptr, aCX, aCY);
916 }
917
918 NS_IMETHODIMP
SetPositionAndSize(int32_t aX,int32_t aY,int32_t aCX,int32_t aCY,uint32_t aFlags)919 nsWebBrowser::SetPositionAndSize(int32_t aX, int32_t aY, int32_t aCX,
920 int32_t aCY, uint32_t aFlags) {
921 int32_t doc_x = aX;
922 int32_t doc_y = aY;
923
924 // If there is an internal widget we need to make the docShell coordinates
925 // relative to the internal widget rather than the calling app's parent.
926 // We also need to resize our widget then.
927 if (mInternalWidget) {
928 doc_x = doc_y = 0;
929 mInternalWidget->Resize(aX, aY, aCX, aCY,
930 !!(aFlags & nsIBaseWindow::eRepaint));
931 }
932 // Now reposition/ resize the doc
933 NS_ENSURE_SUCCESS(
934 mDocShell->SetPositionAndSize(doc_x, doc_y, aCX, aCY, aFlags),
935 NS_ERROR_FAILURE);
936
937 return NS_OK;
938 }
939
940 NS_IMETHODIMP
GetPositionAndSize(int32_t * aX,int32_t * aY,int32_t * aCX,int32_t * aCY)941 nsWebBrowser::GetPositionAndSize(int32_t* aX, int32_t* aY, int32_t* aCX,
942 int32_t* aCY) {
943 if (mInternalWidget) {
944 LayoutDeviceIntRect bounds = mInternalWidget->GetBounds();
945
946 if (aX) {
947 *aX = bounds.X();
948 }
949 if (aY) {
950 *aY = bounds.Y();
951 }
952 if (aCX) {
953 *aCX = bounds.Width();
954 }
955 if (aCY) {
956 *aCY = bounds.Height();
957 }
958 return NS_OK;
959 } else {
960 // Can directly return this as it is the
961 // same interface, thus same returns.
962 return mDocShell->GetPositionAndSize(aX, aY, aCX, aCY);
963 }
964 return NS_OK;
965 }
966
967 NS_IMETHODIMP
Repaint(bool aForce)968 nsWebBrowser::Repaint(bool aForce) {
969 NS_ENSURE_STATE(mDocShell);
970 // Can directly return this as it is the
971 // same interface, thus same returns.
972 return mDocShell->Repaint(aForce);
973 }
974
975 NS_IMETHODIMP
GetParentWidget(nsIWidget ** aParentWidget)976 nsWebBrowser::GetParentWidget(nsIWidget** aParentWidget) {
977 NS_ENSURE_ARG_POINTER(aParentWidget);
978
979 *aParentWidget = mParentWidget;
980
981 NS_IF_ADDREF(*aParentWidget);
982
983 return NS_OK;
984 }
985
986 NS_IMETHODIMP
SetParentWidget(nsIWidget * aParentWidget)987 nsWebBrowser::SetParentWidget(nsIWidget* aParentWidget) {
988 NS_ENSURE_STATE(!mDocShell);
989
990 mParentWidget = aParentWidget;
991 if (mParentWidget) {
992 mParentNativeWindow = mParentWidget->GetNativeData(NS_NATIVE_WIDGET);
993 } else {
994 mParentNativeWindow = nullptr;
995 }
996
997 return NS_OK;
998 }
999
1000 NS_IMETHODIMP
GetParentNativeWindow(nativeWindow * aParentNativeWindow)1001 nsWebBrowser::GetParentNativeWindow(nativeWindow* aParentNativeWindow) {
1002 NS_ENSURE_ARG_POINTER(aParentNativeWindow);
1003
1004 *aParentNativeWindow = mParentNativeWindow;
1005
1006 return NS_OK;
1007 }
1008
1009 NS_IMETHODIMP
SetParentNativeWindow(nativeWindow aParentNativeWindow)1010 nsWebBrowser::SetParentNativeWindow(nativeWindow aParentNativeWindow) {
1011 NS_ENSURE_STATE(!mDocShell);
1012
1013 mParentNativeWindow = aParentNativeWindow;
1014
1015 return NS_OK;
1016 }
1017
1018 NS_IMETHODIMP
GetNativeHandle(nsAString & aNativeHandle)1019 nsWebBrowser::GetNativeHandle(nsAString& aNativeHandle) {
1020 // the nativeHandle should be accessed from nsIAppWindow
1021 return NS_ERROR_NOT_IMPLEMENTED;
1022 }
1023
1024 NS_IMETHODIMP
GetVisibility(bool * aVisibility)1025 nsWebBrowser::GetVisibility(bool* aVisibility) {
1026 NS_ENSURE_ARG_POINTER(aVisibility);
1027
1028 if (mDocShell) {
1029 NS_ENSURE_SUCCESS(mDocShell->GetVisibility(aVisibility), NS_ERROR_FAILURE);
1030 }
1031
1032 return NS_OK;
1033 }
1034
1035 NS_IMETHODIMP
SetVisibility(bool aVisibility)1036 nsWebBrowser::SetVisibility(bool aVisibility) {
1037 if (mDocShell) {
1038 NS_ENSURE_SUCCESS(mDocShell->SetVisibility(aVisibility), NS_ERROR_FAILURE);
1039 if (mInternalWidget) {
1040 mInternalWidget->Show(aVisibility);
1041 }
1042 }
1043
1044 return NS_OK;
1045 }
1046
1047 NS_IMETHODIMP
GetEnabled(bool * aEnabled)1048 nsWebBrowser::GetEnabled(bool* aEnabled) {
1049 if (mInternalWidget) {
1050 *aEnabled = mInternalWidget->IsEnabled();
1051 return NS_OK;
1052 }
1053
1054 return NS_ERROR_FAILURE;
1055 }
1056
1057 NS_IMETHODIMP
SetEnabled(bool aEnabled)1058 nsWebBrowser::SetEnabled(bool aEnabled) {
1059 if (mInternalWidget) {
1060 mInternalWidget->Enable(aEnabled);
1061 return NS_OK;
1062 }
1063 return NS_ERROR_FAILURE;
1064 }
1065
1066 NS_IMETHODIMP
GetMainWidget(nsIWidget ** aMainWidget)1067 nsWebBrowser::GetMainWidget(nsIWidget** aMainWidget) {
1068 NS_ENSURE_ARG_POINTER(aMainWidget);
1069
1070 if (mInternalWidget) {
1071 *aMainWidget = mInternalWidget;
1072 } else {
1073 *aMainWidget = mParentWidget;
1074 }
1075
1076 NS_IF_ADDREF(*aMainWidget);
1077
1078 return NS_OK;
1079 }
1080
1081 NS_IMETHODIMP
GetTitle(nsAString & aTitle)1082 nsWebBrowser::GetTitle(nsAString& aTitle) {
1083 NS_ENSURE_STATE(mDocShell);
1084
1085 NS_ENSURE_SUCCESS(mDocShell->GetTitle(aTitle), NS_ERROR_FAILURE);
1086
1087 return NS_OK;
1088 }
1089
1090 NS_IMETHODIMP
SetTitle(const nsAString & aTitle)1091 nsWebBrowser::SetTitle(const nsAString& aTitle) {
1092 NS_ENSURE_STATE(mDocShell);
1093
1094 NS_ENSURE_SUCCESS(mDocShell->SetTitle(aTitle), NS_ERROR_FAILURE);
1095
1096 return NS_OK;
1097 }
1098
1099 //*****************************************************************************
1100 // nsWebBrowser: Listener Helpers
1101 //*****************************************************************************
1102
SetDocShell(nsDocShell * aDocShell)1103 void nsWebBrowser::SetDocShell(nsDocShell* aDocShell) {
1104 // We need to keep the docshell alive while we perform the changes, but we
1105 // don't need to call any methods on it.
1106 nsCOMPtr<nsIDocShell> kungFuDeathGrip(mDocShell);
1107 mozilla::Unused << kungFuDeathGrip;
1108
1109 if (aDocShell) {
1110 MOZ_ASSERT(!mDocShell, "Should not overwrite an existing value!");
1111
1112 mDocShell = aDocShell;
1113
1114 // By default, do not allow DNS prefetch, so we don't break our frozen
1115 // API. Embeddors who decide to enable it should do so manually.
1116 mDocShell->SetAllowDNSPrefetch(false);
1117 } else {
1118 if (mDocShellTreeOwner) {
1119 mDocShellTreeOwner->RemoveFromWatcher(); // evil twin of Add in Create()
1120 }
1121 if (mDocShell) {
1122 mDocShell->Destroy();
1123 }
1124 if (!mWillChangeProcess && mDocShell) {
1125 mDocShell->GetBrowsingContext()->Detach(/* aFromIPC */ true);
1126 }
1127
1128 mDocShell = nullptr;
1129 }
1130 }
1131
EnsureDocShellTreeOwner()1132 void nsWebBrowser::EnsureDocShellTreeOwner() {
1133 if (mDocShellTreeOwner) {
1134 return;
1135 }
1136
1137 mDocShellTreeOwner = new nsDocShellTreeOwner();
1138 mDocShellTreeOwner->WebBrowser(this);
1139 }
1140
DrawPaintedLayer(PaintedLayer * aLayer,gfxContext * aContext,const nsIntRegion & aRegionToDraw,const nsIntRegion & aDirtyRegion,DrawRegionClip aClip,const nsIntRegion & aRegionToInvalidate,void * aCallbackData)1141 static void DrawPaintedLayer(PaintedLayer* aLayer, gfxContext* aContext,
1142 const nsIntRegion& aRegionToDraw,
1143 const nsIntRegion& aDirtyRegion,
1144 DrawRegionClip aClip,
1145 const nsIntRegion& aRegionToInvalidate,
1146 void* aCallbackData) {
1147 DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
1148
1149 ColorPattern color(ToDeviceColor(*static_cast<nscolor*>(aCallbackData)));
1150 nsIntRect dirtyRect = aRegionToDraw.GetBounds();
1151 aDrawTarget.FillRect(
1152 Rect(dirtyRect.X(), dirtyRect.Y(), dirtyRect.Width(), dirtyRect.Height()),
1153 color);
1154 }
1155
WindowActivated()1156 void nsWebBrowser::WindowActivated() {
1157 #if defined(DEBUG_smaug)
1158 RefPtr<dom::Document> document = mDocShell->GetDocument();
1159 nsAutoString documentURI;
1160 document->GetDocumentURI(documentURI);
1161 printf("nsWebBrowser::NS_ACTIVATE %p %s\n", (void*)this,
1162 NS_ConvertUTF16toUTF8(documentURI).get());
1163 #endif
1164 FocusActivate(nsFocusManager::GenerateFocusActionId());
1165 }
1166
WindowDeactivated()1167 void nsWebBrowser::WindowDeactivated() {
1168 #if defined(DEBUG_smaug)
1169 RefPtr<dom::Document> document = mDocShell->GetDocument();
1170 nsAutoString documentURI;
1171 document->GetDocumentURI(documentURI);
1172 printf("nsWebBrowser::NS_DEACTIVATE %p %s\n", (void*)this,
1173 NS_ConvertUTF16toUTF8(documentURI).get());
1174 #endif
1175 FocusDeactivate(nsFocusManager::GenerateFocusActionId());
1176 }
1177
PaintWindow(nsIWidget * aWidget,LayoutDeviceIntRegion aRegion)1178 bool nsWebBrowser::PaintWindow(nsIWidget* aWidget,
1179 LayoutDeviceIntRegion aRegion) {
1180 LayerManager* layerManager = aWidget->GetLayerManager();
1181 NS_ASSERTION(layerManager, "Must be in paint event");
1182
1183 layerManager->BeginTransaction();
1184 RefPtr<PaintedLayer> root = layerManager->CreatePaintedLayer();
1185 if (root) {
1186 nsIntRect dirtyRect = aRegion.GetBounds().ToUnknownRect();
1187 root->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(dirtyRect));
1188 layerManager->SetRoot(root);
1189 }
1190
1191 layerManager->EndTransaction(DrawPaintedLayer, &mBackgroundColor);
1192 return true;
1193 }
1194
FocusActivate(uint64_t aActionId)1195 void nsWebBrowser::FocusActivate(uint64_t aActionId) {
1196 nsFocusManager* fm = nsFocusManager::GetFocusManager();
1197 nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
1198 if (fm && window) {
1199 fm->WindowRaised(window, aActionId);
1200 }
1201 }
1202
FocusDeactivate(uint64_t aActionId)1203 void nsWebBrowser::FocusDeactivate(uint64_t aActionId) {
1204 nsFocusManager* fm = nsFocusManager::GetFocusManager();
1205 nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
1206 if (fm && window) {
1207 fm->WindowLowered(window, aActionId);
1208 }
1209 }
1210
SetWillChangeProcess()1211 void nsWebBrowser::SetWillChangeProcess() {
1212 mWillChangeProcess = true;
1213 if (mDocShell) {
1214 nsDocShell::Cast(mDocShell)->SetWillChangeProcess();
1215 }
1216 }
1217
WindowActivated()1218 void nsWebBrowser::WidgetListenerDelegate::WindowActivated() {
1219 RefPtr<nsWebBrowser> holder = mWebBrowser;
1220 holder->WindowActivated();
1221 }
1222
WindowDeactivated()1223 void nsWebBrowser::WidgetListenerDelegate::WindowDeactivated() {
1224 RefPtr<nsWebBrowser> holder = mWebBrowser;
1225 holder->WindowDeactivated();
1226 }
1227
PaintWindow(nsIWidget * aWidget,mozilla::LayoutDeviceIntRegion aRegion)1228 bool nsWebBrowser::WidgetListenerDelegate::PaintWindow(
1229 nsIWidget* aWidget, mozilla::LayoutDeviceIntRegion aRegion) {
1230 RefPtr<nsWebBrowser> holder = mWebBrowser;
1231 return holder->PaintWindow(aWidget, aRegion);
1232 }
1233