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