Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 // Local Includes
7 #include "nsWebBrowser.h"
9 // Helper Classes
10 #include "nsGfxCIID.h"
11 #include "nsWidgetsCID.h"
13 //Interfaces Needed
14 #include "nsReadableUtils.h"
15 #include "nsIComponentManager.h"
16 #include "nsIDOMDocument.h"
17 #include "nsIDOMWindow.h"
18 #include "nsIDOMElement.h"
19 #include "nsIInterfaceRequestor.h"
20 #include "nsIInterfaceRequestorUtils.h"
21 #include "nsIWebBrowserChrome.h"
22 #include "nsPIDOMWindow.h"
23 #include "nsIWebProgress.h"
24 #include "nsIWebProgressListener.h"
25 #include "nsIWebBrowserFocus.h"
26 #include "nsIWebBrowserStream.h"
27 #include "nsIPresShell.h"
28 #include "nsIURIContentListener.h"
29 #include "nsISHistoryListener.h"
30 #include "nsIURI.h"
31 #include "nsIWebBrowserPersist.h"
32 #include "nsCWebBrowserPersist.h"
33 #include "nsIServiceManager.h"
34 #include "nsAutoPtr.h"
35 #include "nsFocusManager.h"
36 #include "Layers.h"
37 #include "gfxContext.h"
38 #include "nsILoadContext.h"
40 // for painting the background window
41 #include "mozilla/LookAndFeel.h"
43 // Printing Includes
44 #ifdef NS_PRINTING
45 #include "nsIWebBrowserPrint.h"
46 #include "nsIContentViewer.h"
47 #endif
49 // PSM2 includes
50 #include "nsISecureBrowserUI.h"
51 #include "nsXULAppAPI.h"
53 using namespace mozilla;
54 using namespace mozilla::layers;
56 static NS_DEFINE_CID(kChildCID, NS_CHILD_CID);
59 //*****************************************************************************
60 //*** nsWebBrowser: Object Management
61 //*****************************************************************************
63 nsWebBrowser::nsWebBrowser() : mDocShellTreeOwner(nullptr),
64 mInitInfo(nullptr),
65 mContentType(typeContentWrapper),
66 mActivating(false),
67 mShouldEnableHistory(true),
68 mIsActive(true),
69 mParentNativeWindow(nullptr),
70 mProgressListener(nullptr),
71 mBackgroundColor(0),
72 mPersistCurrentState(nsIWebBrowserPersist::PERSIST_STATE_READY),
73 mPersistResult(NS_OK),
74 mPersistFlags(nsIWebBrowserPersist::PERSIST_FLAGS_NONE),
75 mStream(nullptr),
76 mParentWidget(nullptr),
77 mListenerArray(nullptr)
78 {
79 mInitInfo = new nsWebBrowserInitInfo();
80 mWWatch = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
81 NS_ASSERTION(mWWatch, "failed to get WindowWatcher");
82 }
84 nsWebBrowser::~nsWebBrowser()
85 {
86 InternalDestroy();
87 }
89 NS_IMETHODIMP nsWebBrowser::InternalDestroy()
90 {
92 if (mInternalWidget) {
93 mInternalWidget->SetWidgetListener(nullptr);
94 mInternalWidget->Destroy();
95 mInternalWidget = nullptr; // Force release here.
96 }
98 SetDocShell(nullptr);
100 if(mDocShellTreeOwner)
101 {
102 mDocShellTreeOwner->WebBrowser(nullptr);
103 NS_RELEASE(mDocShellTreeOwner);
104 }
105 if(mInitInfo)
106 {
107 delete mInitInfo;
108 mInitInfo = nullptr;
109 }
111 if (mListenerArray) {
112 for (uint32_t i = 0, end = mListenerArray->Length(); i < end; i++) {
113 nsWebBrowserListenerState *state = mListenerArray->ElementAt(i);
114 delete state;
115 }
116 delete mListenerArray;
117 mListenerArray = nullptr;
118 }
120 return NS_OK;
121 }
124 //*****************************************************************************
125 // nsWebBrowser::nsISupports
126 //*****************************************************************************
128 NS_IMPL_ADDREF(nsWebBrowser)
129 NS_IMPL_RELEASE(nsWebBrowser)
131 NS_INTERFACE_MAP_BEGIN(nsWebBrowser)
132 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowser)
133 NS_INTERFACE_MAP_ENTRY(nsIWebBrowser)
134 NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
135 NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
136 NS_INTERFACE_MAP_ENTRY(nsIScrollable)
137 NS_INTERFACE_MAP_ENTRY(nsITextScroll)
138 NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem)
139 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
140 NS_INTERFACE_MAP_ENTRY(nsIWebBrowserSetup)
141 NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPersist)
142 NS_INTERFACE_MAP_ENTRY(nsICancelable)
143 NS_INTERFACE_MAP_ENTRY(nsIWebBrowserFocus)
144 NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
145 NS_INTERFACE_MAP_ENTRY(nsIWebBrowserStream)
146 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
147 NS_INTERFACE_MAP_END
149 ///*****************************************************************************
150 // nsWebBrowser::nsIInterfaceRequestor
151 //*****************************************************************************
153 NS_IMETHODIMP nsWebBrowser::GetInterface(const nsIID& aIID, void** aSink)
154 {
155 NS_ENSURE_ARG_POINTER(aSink);
157 if(NS_SUCCEEDED(QueryInterface(aIID, aSink)))
158 return NS_OK;
160 if (mDocShell) {
161 #ifdef NS_PRINTING
162 if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) {
163 nsCOMPtr<nsIContentViewer> viewer;
164 mDocShell->GetContentViewer(getter_AddRefs(viewer));
165 if (!viewer)
166 return NS_NOINTERFACE;
168 nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint(do_QueryInterface(viewer));
169 nsIWebBrowserPrint* print = (nsIWebBrowserPrint*)webBrowserPrint.get();
170 NS_ASSERTION(print, "This MUST support this interface!");
171 NS_ADDREF(print);
172 *aSink = print;
173 return NS_OK;
174 }
175 #endif
176 return mDocShellAsReq->GetInterface(aIID, aSink);
177 }
179 return NS_NOINTERFACE;
180 }
182 //*****************************************************************************
183 // nsWebBrowser::nsIWebBrowser
184 //*****************************************************************************
186 // listeners that currently support registration through AddWebBrowserListener:
187 // - nsIWebProgressListener
188 NS_IMETHODIMP nsWebBrowser::AddWebBrowserListener(nsIWeakReference *aListener, const nsIID& aIID)
189 {
190 NS_ENSURE_ARG_POINTER(aListener);
192 nsresult rv = NS_OK;
193 if (!mWebProgress) {
194 // The window hasn't been created yet, so queue up the listener. They'll be
195 // registered when the window gets created.
196 nsAutoPtr<nsWebBrowserListenerState> state;
197 state = new nsWebBrowserListenerState();
198 if (!state) return NS_ERROR_OUT_OF_MEMORY;
200 state->mWeakPtr = aListener;
201 state->mID = aIID;
203 if (!mListenerArray) {
204 mListenerArray = new nsTArray<nsWebBrowserListenerState*>();
205 if (!mListenerArray) {
206 return NS_ERROR_OUT_OF_MEMORY;
207 }
208 }
210 if (!mListenerArray->AppendElement(state)) {
211 return NS_ERROR_OUT_OF_MEMORY;
212 }
214 // We're all set now; don't delete |state| after this point
215 state.forget();
216 } else {
217 nsCOMPtr<nsISupports> supports(do_QueryReferent(aListener));
218 if (!supports) return NS_ERROR_INVALID_ARG;
219 rv = BindListener(supports, aIID);
220 }
222 return rv;
223 }
225 NS_IMETHODIMP nsWebBrowser::BindListener(nsISupports *aListener, const nsIID& aIID) {
226 NS_ENSURE_ARG_POINTER(aListener);
227 NS_ASSERTION(mWebProgress, "this should only be called after we've retrieved a progress iface");
228 nsresult rv = NS_OK;
230 // register this listener for the specified interface id
231 if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) {
232 nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(aListener, &rv);
233 if (NS_FAILED(rv)) return rv;
234 NS_ENSURE_STATE(mWebProgress);
235 rv = mWebProgress->AddProgressListener(listener, nsIWebProgress::NOTIFY_ALL);
236 }
237 else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) {
238 nsCOMPtr<nsISHistory> shistory(do_GetInterface(mDocShell, &rv));
239 if (NS_FAILED(rv)) return rv;
240 nsCOMPtr<nsISHistoryListener> listener(do_QueryInterface(aListener, &rv));
241 if (NS_FAILED(rv)) return rv;
242 rv = shistory->AddSHistoryListener(listener);
243 }
244 return rv;
245 }
247 NS_IMETHODIMP nsWebBrowser::RemoveWebBrowserListener(nsIWeakReference *aListener, const nsIID& aIID)
248 {
249 NS_ENSURE_ARG_POINTER(aListener);
251 nsresult rv = NS_OK;
252 if (!mWebProgress) {
253 // if there's no-one to register the listener w/, and we don't have a queue going,
254 // the the called is calling Remove before an Add which doesn't make sense.
255 if (!mListenerArray) return NS_ERROR_FAILURE;
257 // iterate the array and remove the queued listener
258 int32_t count = mListenerArray->Length();
259 while (count > 0) {
260 nsWebBrowserListenerState *state = mListenerArray->ElementAt(count);
261 NS_ASSERTION(state, "list construction problem");
263 if (state->Equals(aListener, aIID)) {
264 // this is the one, pull it out.
265 mListenerArray->RemoveElementAt(count);
266 break;
267 }
268 count--;
269 }
271 // if we've emptied the array, get rid of it.
272 if (0 >= mListenerArray->Length()) {
273 for (uint32_t i = 0, end = mListenerArray->Length(); i < end; i++) {
274 nsWebBrowserListenerState *state = mListenerArray->ElementAt(i);
275 delete state;
276 }
277 delete mListenerArray;
278 mListenerArray = nullptr;
279 }
281 } else {
282 nsCOMPtr<nsISupports> supports(do_QueryReferent(aListener));
283 if (!supports) return NS_ERROR_INVALID_ARG;
284 rv = UnBindListener(supports, aIID);
285 }
287 return rv;
288 }
290 NS_IMETHODIMP nsWebBrowser::UnBindListener(nsISupports *aListener, const nsIID& aIID) {
291 NS_ENSURE_ARG_POINTER(aListener);
292 NS_ASSERTION(mWebProgress, "this should only be called after we've retrieved a progress iface");
293 nsresult rv = NS_OK;
295 // remove the listener for the specified interface id
296 if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) {
297 nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(aListener, &rv);
298 if (NS_FAILED(rv)) return rv;
299 NS_ENSURE_STATE(mWebProgress);
300 rv = mWebProgress->RemoveProgressListener(listener);
301 }
302 else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) {
303 nsCOMPtr<nsISHistory> shistory(do_GetInterface(mDocShell, &rv));
304 if (NS_FAILED(rv)) return rv;
305 nsCOMPtr<nsISHistoryListener> listener(do_QueryInterface(aListener, &rv));
306 if (NS_FAILED(rv)) return rv;
307 rv = shistory->RemoveSHistoryListener(listener);
308 }
309 return rv;
310 }
312 NS_IMETHODIMP nsWebBrowser::EnableGlobalHistory(bool aEnable)
313 {
314 NS_ENSURE_STATE(mDocShell);
316 return mDocShell->SetUseGlobalHistory(aEnable);
317 }
319 NS_IMETHODIMP nsWebBrowser::GetContainerWindow(nsIWebBrowserChrome** aTopWindow)
320 {
321 NS_ENSURE_ARG_POINTER(aTopWindow);
323 if(mDocShellTreeOwner) {
324 *aTopWindow = mDocShellTreeOwner->GetWebBrowserChrome().take();
325 } else {
326 *aTopWindow = nullptr;
327 }
329 return NS_OK;
330 }
332 NS_IMETHODIMP nsWebBrowser::SetContainerWindow(nsIWebBrowserChrome* aTopWindow)
333 {
334 NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE);
335 return mDocShellTreeOwner->SetWebBrowserChrome(aTopWindow);
336 }
338 NS_IMETHODIMP nsWebBrowser::GetParentURIContentListener(nsIURIContentListener**
339 aParentContentListener)
340 {
341 NS_ENSURE_ARG_POINTER(aParentContentListener);
342 *aParentContentListener = nullptr;
344 // get the interface from the docshell
345 nsCOMPtr<nsIURIContentListener> listener(do_GetInterface(mDocShell));
347 if (listener)
348 return listener->GetParentContentListener(aParentContentListener);
349 return NS_OK;
350 }
352 NS_IMETHODIMP nsWebBrowser::SetParentURIContentListener(nsIURIContentListener*
353 aParentContentListener)
354 {
355 // get the interface from the docshell
356 nsCOMPtr<nsIURIContentListener> listener(do_GetInterface(mDocShell));
358 if (listener)
359 return listener->SetParentContentListener(aParentContentListener);
360 return NS_ERROR_FAILURE;
361 }
363 NS_IMETHODIMP nsWebBrowser::GetContentDOMWindow(nsIDOMWindow **_retval)
364 {
365 NS_ENSURE_STATE(mDocShell);
366 nsresult rv = NS_OK;
367 nsCOMPtr<nsIDOMWindow> retval = do_GetInterface(mDocShell, &rv);
368 if (NS_FAILED(rv)) return rv;
370 *_retval = retval;
371 NS_ADDREF(*_retval);
372 return rv;
373 }
375 NS_IMETHODIMP nsWebBrowser::GetIsActive(bool *rv)
376 {
377 *rv = mIsActive;
378 return NS_OK;
379 }
381 NS_IMETHODIMP nsWebBrowser::SetIsActive(bool aIsActive)
382 {
383 // Set our copy of the value
384 mIsActive = aIsActive;
386 // If we have a docshell, pass on the request
387 if (mDocShell)
388 return mDocShell->SetIsActive(aIsActive);
389 return NS_OK;
390 }
392 //*****************************************************************************
393 // nsWebBrowser::nsIDocShellTreeItem
394 //*****************************************************************************
396 NS_IMETHODIMP nsWebBrowser::GetName(nsAString& aName)
397 {
398 if(mDocShell)
399 mDocShell->GetName(aName);
400 else
401 aName = mInitInfo->name;
403 return NS_OK;
404 }
406 NS_IMETHODIMP nsWebBrowser::SetName(const nsAString& aName)
407 {
408 if(mDocShell)
409 {
410 return mDocShell->SetName(aName);
411 }
412 else
413 mInitInfo->name = aName;
415 return NS_OK;
416 }
418 NS_IMETHODIMP nsWebBrowser::NameEquals(const char16_t *aName, bool *_retval)
419 {
420 NS_ENSURE_ARG_POINTER(aName);
421 NS_ENSURE_ARG_POINTER(_retval);
422 if(mDocShell)
423 {
424 return mDocShell->NameEquals(aName, _retval);
425 }
426 else
427 *_retval = mInitInfo->name.Equals(aName);
429 return NS_OK;
430 }
432 /* virtual */ int32_t
433 nsWebBrowser::ItemType()
434 {
435 return mContentType;
436 }
438 NS_IMETHODIMP nsWebBrowser::GetItemType(int32_t* aItemType)
439 {
440 NS_ENSURE_ARG_POINTER(aItemType);
442 *aItemType = ItemType();
443 return NS_OK;
444 }
446 NS_IMETHODIMP nsWebBrowser::SetItemType(int32_t aItemType)
447 {
448 NS_ENSURE_TRUE((aItemType == typeContentWrapper || aItemType == typeChromeWrapper), NS_ERROR_FAILURE);
449 mContentType = aItemType;
450 if (mDocShell)
451 mDocShell->SetItemType(mContentType == typeChromeWrapper
452 ? static_cast<int32_t>(typeChrome)
453 : static_cast<int32_t>(typeContent));
454 return NS_OK;
455 }
457 NS_IMETHODIMP nsWebBrowser::GetParent(nsIDocShellTreeItem** aParent)
458 {
459 *aParent = nullptr;
460 return NS_OK;
461 }
463 NS_IMETHODIMP nsWebBrowser::GetSameTypeParent(nsIDocShellTreeItem** aParent)
464 {
465 *aParent = nullptr;
467 return NS_OK;
468 }
470 NS_IMETHODIMP nsWebBrowser::GetRootTreeItem(nsIDocShellTreeItem** aRootTreeItem)
471 {
472 NS_ENSURE_ARG_POINTER(aRootTreeItem);
473 *aRootTreeItem = static_cast<nsIDocShellTreeItem*>(this);
475 nsCOMPtr<nsIDocShellTreeItem> parent;
476 NS_ENSURE_SUCCESS(GetParent(getter_AddRefs(parent)), NS_ERROR_FAILURE);
477 while(parent)
478 {
479 *aRootTreeItem = parent;
480 NS_ENSURE_SUCCESS((*aRootTreeItem)->GetParent(getter_AddRefs(parent)), NS_ERROR_FAILURE);
481 }
482 NS_ADDREF(*aRootTreeItem);
483 return NS_OK;
484 }
486 NS_IMETHODIMP nsWebBrowser::GetSameTypeRootTreeItem(nsIDocShellTreeItem** aRootTreeItem)
487 {
488 NS_ENSURE_ARG_POINTER(aRootTreeItem);
489 *aRootTreeItem = static_cast<nsIDocShellTreeItem*>(this);
491 nsCOMPtr<nsIDocShellTreeItem> parent;
492 NS_ENSURE_SUCCESS(GetSameTypeParent(getter_AddRefs(parent)), NS_ERROR_FAILURE);
493 while(parent)
494 {
495 *aRootTreeItem = parent;
496 NS_ENSURE_SUCCESS((*aRootTreeItem)->GetSameTypeParent(getter_AddRefs(parent)),
497 NS_ERROR_FAILURE);
498 }
499 NS_ADDREF(*aRootTreeItem);
500 return NS_OK;
501 }
503 NS_IMETHODIMP nsWebBrowser::FindItemWithName(const char16_t *aName,
504 nsISupports* aRequestor, nsIDocShellTreeItem* aOriginalRequestor,
505 nsIDocShellTreeItem **_retval)
506 {
507 NS_ENSURE_STATE(mDocShell);
508 NS_ASSERTION(mDocShellTreeOwner, "This should always be set when in this situation");
510 return mDocShell->FindItemWithName(aName,
511 static_cast<nsIDocShellTreeOwner*>(mDocShellTreeOwner),
512 aOriginalRequestor, _retval);
513 }
515 NS_IMETHODIMP nsWebBrowser::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner)
516 {
517 NS_ENSURE_ARG_POINTER(aTreeOwner);
518 *aTreeOwner = nullptr;
519 if(mDocShellTreeOwner)
520 {
521 if (mDocShellTreeOwner->mTreeOwner)
522 {
523 *aTreeOwner = mDocShellTreeOwner->mTreeOwner;
524 }
525 else
526 {
527 *aTreeOwner = mDocShellTreeOwner;
528 }
529 }
530 NS_IF_ADDREF(*aTreeOwner);
531 return NS_OK;
532 }
534 NS_IMETHODIMP nsWebBrowser::SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner)
535 {
536 NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE);
537 return mDocShellTreeOwner->SetTreeOwner(aTreeOwner);
538 }
540 //*****************************************************************************
541 // nsWebBrowser::nsIDocShellTreeItem
542 //*****************************************************************************
544 NS_IMETHODIMP nsWebBrowser::GetChildCount(int32_t * aChildCount)
545 {
546 NS_ENSURE_ARG_POINTER(aChildCount);
547 *aChildCount = 0;
548 return NS_OK;
549 }
551 NS_IMETHODIMP nsWebBrowser::AddChild(nsIDocShellTreeItem * aChild)
552 {
553 return NS_ERROR_UNEXPECTED;
554 }
556 NS_IMETHODIMP nsWebBrowser::RemoveChild(nsIDocShellTreeItem * aChild)
557 {
558 return NS_ERROR_UNEXPECTED;
559 }
561 NS_IMETHODIMP nsWebBrowser::GetChildAt(int32_t aIndex,
562 nsIDocShellTreeItem ** aChild)
563 {
564 return NS_ERROR_UNEXPECTED;
565 }
567 NS_IMETHODIMP nsWebBrowser::FindChildWithName(
568 const char16_t * aName,
569 bool aRecurse, bool aSameType,
570 nsIDocShellTreeItem * aRequestor,
571 nsIDocShellTreeItem * aOriginalRequestor,
572 nsIDocShellTreeItem ** _retval)
573 {
574 NS_ENSURE_ARG_POINTER(_retval);
576 *_retval = nullptr;
577 return NS_OK;
578 }
580 //*****************************************************************************
581 // nsWebBrowser::nsIWebNavigation
582 //*****************************************************************************
584 NS_IMETHODIMP nsWebBrowser::GetCanGoBack(bool* aCanGoBack)
585 {
586 NS_ENSURE_STATE(mDocShell);
588 return mDocShellAsNav->GetCanGoBack(aCanGoBack);
589 }
591 NS_IMETHODIMP nsWebBrowser::GetCanGoForward(bool* aCanGoForward)
592 {
593 NS_ENSURE_STATE(mDocShell);
595 return mDocShellAsNav->GetCanGoForward(aCanGoForward);
596 }
598 NS_IMETHODIMP nsWebBrowser::GoBack()
599 {
600 NS_ENSURE_STATE(mDocShell);
602 return mDocShellAsNav->GoBack();
603 }
605 NS_IMETHODIMP nsWebBrowser::GoForward()
606 {
607 NS_ENSURE_STATE(mDocShell);
609 return mDocShellAsNav->GoForward();
610 }
612 NS_IMETHODIMP nsWebBrowser::LoadURIWithBase(const char16_t* aURI,
613 uint32_t aLoadFlags,
614 nsIURI* aReferringURI,
615 nsIInputStream* aPostDataStream,
616 nsIInputStream* aExtraHeaderStream,
617 nsIURI* aBaseURI)
618 {
619 NS_ENSURE_STATE(mDocShell);
621 return mDocShellAsNav->LoadURIWithBase(aURI,
622 aLoadFlags,
623 aReferringURI,
624 aPostDataStream,
625 aExtraHeaderStream,
626 aBaseURI);
627 }
629 NS_IMETHODIMP nsWebBrowser::LoadURI(const char16_t* aURI,
630 uint32_t aLoadFlags,
631 nsIURI* aReferringURI,
632 nsIInputStream* aPostDataStream,
633 nsIInputStream* aExtraHeaderStream)
634 {
635 NS_ENSURE_STATE(mDocShell);
637 return mDocShellAsNav->LoadURI(aURI,
638 aLoadFlags,
639 aReferringURI,
640 aPostDataStream,
641 aExtraHeaderStream);
642 }
644 NS_IMETHODIMP nsWebBrowser::Reload(uint32_t aReloadFlags)
645 {
646 NS_ENSURE_STATE(mDocShell);
648 return mDocShellAsNav->Reload(aReloadFlags);
649 }
651 NS_IMETHODIMP nsWebBrowser::GotoIndex(int32_t aIndex)
652 {
653 NS_ENSURE_STATE(mDocShell);
655 return mDocShellAsNav->GotoIndex(aIndex);
656 }
658 NS_IMETHODIMP nsWebBrowser::Stop(uint32_t aStopFlags)
659 {
660 NS_ENSURE_STATE(mDocShell);
662 return mDocShellAsNav->Stop(aStopFlags);
663 }
665 NS_IMETHODIMP nsWebBrowser::GetCurrentURI(nsIURI** aURI)
666 {
667 NS_ENSURE_STATE(mDocShell);
669 return mDocShellAsNav->GetCurrentURI(aURI);
670 }
672 NS_IMETHODIMP nsWebBrowser::GetReferringURI(nsIURI** aURI)
673 {
674 NS_ENSURE_STATE(mDocShell);
676 return mDocShellAsNav->GetReferringURI(aURI);
677 }
679 NS_IMETHODIMP nsWebBrowser::SetSessionHistory(nsISHistory* aSessionHistory)
680 {
681 if(mDocShell)
682 return mDocShellAsNav->SetSessionHistory(aSessionHistory);
683 else
684 mInitInfo->sessionHistory = aSessionHistory;
686 return NS_OK;
687 }
689 NS_IMETHODIMP nsWebBrowser::GetSessionHistory(nsISHistory** aSessionHistory)
690 {
691 NS_ENSURE_ARG_POINTER(aSessionHistory);
692 if(mDocShell)
693 return mDocShellAsNav->GetSessionHistory(aSessionHistory);
694 else
695 *aSessionHistory = mInitInfo->sessionHistory;
697 NS_IF_ADDREF(*aSessionHistory);
699 return NS_OK;
700 }
703 NS_IMETHODIMP nsWebBrowser::GetDocument(nsIDOMDocument** aDocument)
704 {
705 NS_ENSURE_STATE(mDocShell);
707 return mDocShellAsNav->GetDocument(aDocument);
708 }
711 //*****************************************************************************
712 // nsWebBrowser::nsIWebBrowserSetup
713 //*****************************************************************************
715 /* void setProperty (in unsigned long aId, in unsigned long aValue); */
716 NS_IMETHODIMP nsWebBrowser::SetProperty(uint32_t aId, uint32_t aValue)
717 {
718 nsresult rv = NS_OK;
720 switch (aId)
721 {
722 case nsIWebBrowserSetup::SETUP_ALLOW_PLUGINS:
723 {
724 NS_ENSURE_STATE(mDocShell);
725 NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
726 aValue == static_cast<uint32_t>(false)),
727 NS_ERROR_INVALID_ARG);
728 mDocShell->SetAllowPlugins(!!aValue);
729 }
730 break;
731 case nsIWebBrowserSetup::SETUP_ALLOW_JAVASCRIPT:
732 {
733 NS_ENSURE_STATE(mDocShell);
734 NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
735 aValue == static_cast<uint32_t>(false)),
736 NS_ERROR_INVALID_ARG);
737 mDocShell->SetAllowJavascript(!!aValue);
738 }
739 break;
740 case nsIWebBrowserSetup::SETUP_ALLOW_META_REDIRECTS:
741 {
742 NS_ENSURE_STATE(mDocShell);
743 NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
744 aValue == static_cast<uint32_t>(false)),
745 NS_ERROR_INVALID_ARG);
746 mDocShell->SetAllowMetaRedirects(!!aValue);
747 }
748 break;
749 case nsIWebBrowserSetup::SETUP_ALLOW_SUBFRAMES:
750 {
751 NS_ENSURE_STATE(mDocShell);
752 NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
753 aValue == static_cast<uint32_t>(false)),
754 NS_ERROR_INVALID_ARG);
755 mDocShell->SetAllowSubframes(!!aValue);
756 }
757 break;
758 case nsIWebBrowserSetup::SETUP_ALLOW_IMAGES:
759 {
760 NS_ENSURE_STATE(mDocShell);
761 NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
762 aValue == static_cast<uint32_t>(false)),
763 NS_ERROR_INVALID_ARG);
764 mDocShell->SetAllowImages(!!aValue);
765 }
766 break;
767 case nsIWebBrowserSetup::SETUP_ALLOW_DNS_PREFETCH:
768 {
769 NS_ENSURE_STATE(mDocShell);
770 NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
771 aValue == static_cast<uint32_t>(false)),
772 NS_ERROR_INVALID_ARG);
773 mDocShell->SetAllowDNSPrefetch(!!aValue);
774 }
775 break;
776 case nsIWebBrowserSetup::SETUP_USE_GLOBAL_HISTORY:
777 {
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 rv = EnableGlobalHistory(!!aValue);
783 mShouldEnableHistory = aValue;
784 }
785 break;
786 case nsIWebBrowserSetup::SETUP_FOCUS_DOC_BEFORE_CONTENT:
787 {
788 // obsolete
789 }
790 break;
791 case nsIWebBrowserSetup::SETUP_IS_CHROME_WRAPPER:
792 {
793 NS_ENSURE_TRUE((aValue == static_cast<uint32_t>(true) ||
794 aValue == static_cast<uint32_t>(false)),
795 NS_ERROR_INVALID_ARG);
796 SetItemType(aValue ? static_cast<int32_t>(typeChromeWrapper)
797 : static_cast<int32_t>(typeContentWrapper));
798 }
799 break;
800 default:
801 rv = NS_ERROR_INVALID_ARG;
803 }
804 return rv;
805 }
808 //*****************************************************************************
809 // nsWebBrowser::nsIWebProgressListener
810 //*****************************************************************************
812 /* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in nsresult aStatus); */
813 NS_IMETHODIMP nsWebBrowser::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
814 {
815 if (mPersist)
816 {
817 mPersist->GetCurrentState(&mPersistCurrentState);
818 }
819 if (aStateFlags & STATE_IS_NETWORK && aStateFlags & STATE_STOP)
820 {
821 mPersist = nullptr;
822 }
823 if (mProgressListener)
824 {
825 return mProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
826 }
827 return NS_OK;
828 }
830 /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
831 NS_IMETHODIMP nsWebBrowser::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
832 {
833 if (mPersist)
834 {
835 mPersist->GetCurrentState(&mPersistCurrentState);
836 }
837 if (mProgressListener)
838 {
839 return mProgressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
840 }
841 return NS_OK;
842 }
844 /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location, in unsigned long aFlags); */
845 NS_IMETHODIMP nsWebBrowser::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags)
846 {
847 if (mProgressListener)
848 {
849 return mProgressListener->OnLocationChange(aWebProgress, aRequest, location, aFlags);
850 }
851 return NS_OK;
852 }
854 /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
855 NS_IMETHODIMP nsWebBrowser::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage)
856 {
857 if (mProgressListener)
858 {
859 return mProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
860 }
861 return NS_OK;
862 }
864 /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
865 NS_IMETHODIMP nsWebBrowser::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state)
866 {
867 if (mProgressListener)
868 {
869 return mProgressListener->OnSecurityChange(aWebProgress, aRequest, state);
870 }
871 return NS_OK;
872 }
874 //*****************************************************************************
875 // nsWebBrowser::nsIWebBrowserPersist
876 //*****************************************************************************
878 /* attribute unsigned long persistFlags; */
879 NS_IMETHODIMP nsWebBrowser::GetPersistFlags(uint32_t *aPersistFlags)
880 {
881 NS_ENSURE_ARG_POINTER(aPersistFlags);
882 nsresult rv = NS_OK;
883 if (mPersist)
884 {
885 rv = mPersist->GetPersistFlags(&mPersistFlags);
886 }
887 *aPersistFlags = mPersistFlags;
888 return rv;
889 }
890 NS_IMETHODIMP nsWebBrowser::SetPersistFlags(uint32_t aPersistFlags)
891 {
892 nsresult rv = NS_OK;
893 mPersistFlags = aPersistFlags;
894 if (mPersist)
895 {
896 rv = mPersist->SetPersistFlags(mPersistFlags);
897 mPersist->GetPersistFlags(&mPersistFlags);
898 }
899 return rv;
900 }
903 /* readonly attribute unsigned long currentState; */
904 NS_IMETHODIMP nsWebBrowser::GetCurrentState(uint32_t *aCurrentState)
905 {
906 NS_ENSURE_ARG_POINTER(aCurrentState);
907 if (mPersist)
908 {
909 mPersist->GetCurrentState(&mPersistCurrentState);
910 }
911 *aCurrentState = mPersistCurrentState;
912 return NS_OK;
913 }
915 /* readonly attribute nsresult result; */
916 NS_IMETHODIMP nsWebBrowser::GetResult(nsresult *aResult)
917 {
918 NS_ENSURE_ARG_POINTER(aResult);
919 if (mPersist)
920 {
921 mPersist->GetResult(&mPersistResult);
922 }
923 *aResult = mPersistResult;
924 return NS_OK;
925 }
927 /* attribute nsIWebBrowserPersistProgress progressListener; */
928 NS_IMETHODIMP nsWebBrowser::GetProgressListener(nsIWebProgressListener * *aProgressListener)
929 {
930 NS_ENSURE_ARG_POINTER(aProgressListener);
931 *aProgressListener = mProgressListener;
932 NS_IF_ADDREF(*aProgressListener);
933 return NS_OK;
934 }
936 NS_IMETHODIMP nsWebBrowser::SetProgressListener(nsIWebProgressListener * aProgressListener)
937 {
938 mProgressListener = aProgressListener;
939 return NS_OK;
940 }
942 /* void saveURI (in nsIURI aURI, in nsIURI aReferrer,
943 in nsISupports aCacheKey, in nsIInputStream aPostData, in wstring aExtraHeaders,
944 in nsISupports aFile, in nsILoadContext aPrivacyContext); */
945 NS_IMETHODIMP nsWebBrowser::SaveURI(
946 nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer, nsIInputStream *aPostData,
947 const char *aExtraHeaders, nsISupports *aFile, nsILoadContext* aPrivacyContext)
948 {
949 return SavePrivacyAwareURI(aURI, aCacheKey, aReferrer, aPostData, aExtraHeaders,
950 aFile, aPrivacyContext && aPrivacyContext->UsePrivateBrowsing());
951 }
953 NS_IMETHODIMP nsWebBrowser::SavePrivacyAwareURI(
954 nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer, nsIInputStream *aPostData,
955 const char *aExtraHeaders, nsISupports *aFile, bool aIsPrivate)
956 {
957 if (mPersist)
958 {
959 uint32_t currentState;
960 mPersist->GetCurrentState(¤tState);
961 if (currentState == PERSIST_STATE_FINISHED)
962 {
963 mPersist = nullptr;
964 }
965 else
966 {
967 // You can't save again until the last save has completed
968 return NS_ERROR_FAILURE;
969 }
970 }
972 nsCOMPtr<nsIURI> uri;
973 if (aURI)
974 {
975 uri = aURI;
976 }
977 else
978 {
979 nsresult rv = GetCurrentURI(getter_AddRefs(uri));
980 if (NS_FAILED(rv))
981 {
982 return NS_ERROR_FAILURE;
983 }
984 }
986 // Create a throwaway persistence object to do the work
987 nsresult rv;
988 mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
989 NS_ENSURE_SUCCESS(rv, rv);
990 mPersist->SetProgressListener(this);
991 mPersist->SetPersistFlags(mPersistFlags);
992 mPersist->GetCurrentState(&mPersistCurrentState);
993 rv = mPersist->SavePrivacyAwareURI(uri, aCacheKey, aReferrer, aPostData,
994 aExtraHeaders, aFile, aIsPrivate);
995 if (NS_FAILED(rv))
996 {
997 mPersist = nullptr;
998 }
999 return rv;
1000 }
1002 /* void saveChannel (in nsIChannel aChannel, in nsISupports aFile); */
1003 NS_IMETHODIMP nsWebBrowser::SaveChannel(
1004 nsIChannel* aChannel, nsISupports *aFile)
1005 {
1006 if (mPersist)
1007 {
1008 uint32_t currentState;
1009 mPersist->GetCurrentState(¤tState);
1010 if (currentState == PERSIST_STATE_FINISHED)
1011 {
1012 mPersist = nullptr;
1013 }
1014 else
1015 {
1016 // You can't save again until the last save has completed
1017 return NS_ERROR_FAILURE;
1018 }
1019 }
1021 // Create a throwaway persistence object to do the work
1022 nsresult rv;
1023 mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
1024 NS_ENSURE_SUCCESS(rv, rv);
1025 mPersist->SetProgressListener(this);
1026 mPersist->SetPersistFlags(mPersistFlags);
1027 mPersist->GetCurrentState(&mPersistCurrentState);
1028 rv = mPersist->SaveChannel(aChannel, aFile);
1029 if (NS_FAILED(rv))
1030 {
1031 mPersist = nullptr;
1032 }
1033 return rv;
1034 }
1036 /* void saveDocument (in nsIDOMDocument document, in nsISupports aFile, in nsISupports aDataPath); */
1037 NS_IMETHODIMP nsWebBrowser::SaveDocument(
1038 nsIDOMDocument *aDocument, nsISupports *aFile, nsISupports *aDataPath,
1039 const char *aOutputContentType, uint32_t aEncodingFlags, uint32_t aWrapColumn)
1040 {
1041 if (mPersist)
1042 {
1043 uint32_t currentState;
1044 mPersist->GetCurrentState(¤tState);
1045 if (currentState == PERSIST_STATE_FINISHED)
1046 {
1047 mPersist = nullptr;
1048 }
1049 else
1050 {
1051 // You can't save again until the last save has completed
1052 return NS_ERROR_FAILURE;
1053 }
1054 }
1056 // Use the specified DOM document, or if none is specified, the one
1057 // attached to the web browser.
1059 nsCOMPtr<nsIDOMDocument> doc;
1060 if (aDocument)
1061 {
1062 doc = do_QueryInterface(aDocument);
1063 }
1064 else
1065 {
1066 GetDocument(getter_AddRefs(doc));
1067 }
1068 if (!doc)
1069 {
1070 return NS_ERROR_FAILURE;
1071 }
1073 // Create a throwaway persistence object to do the work
1074 nsresult rv;
1075 mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
1076 NS_ENSURE_SUCCESS(rv, rv);
1077 mPersist->SetProgressListener(this);
1078 mPersist->SetPersistFlags(mPersistFlags);
1079 mPersist->GetCurrentState(&mPersistCurrentState);
1080 rv = mPersist->SaveDocument(doc, aFile, aDataPath, aOutputContentType, aEncodingFlags, aWrapColumn);
1081 if (NS_FAILED(rv))
1082 {
1083 mPersist = nullptr;
1084 }
1085 return rv;
1086 }
1088 /* void cancelSave(); */
1089 NS_IMETHODIMP nsWebBrowser::CancelSave()
1090 {
1091 if (mPersist)
1092 {
1093 return mPersist->CancelSave();
1094 }
1095 return NS_OK;
1096 }
1098 /* void cancel(nsresult aReason); */
1099 NS_IMETHODIMP nsWebBrowser::Cancel(nsresult aReason)
1100 {
1101 if (mPersist)
1102 {
1103 return mPersist->Cancel(aReason);
1104 }
1105 return NS_OK;
1106 }
1111 //*****************************************************************************
1112 // nsWebBrowser::nsIBaseWindow
1113 //*****************************************************************************
1115 NS_IMETHODIMP nsWebBrowser::InitWindow(nativeWindow aParentNativeWindow,
1116 nsIWidget* aParentWidget, int32_t aX, int32_t aY, int32_t aCX, int32_t aCY)
1117 {
1118 NS_ENSURE_ARG(aParentNativeWindow || aParentWidget);
1119 NS_ENSURE_STATE(!mDocShell || mInitInfo);
1121 if(aParentWidget)
1122 NS_ENSURE_SUCCESS(SetParentWidget(aParentWidget), NS_ERROR_FAILURE);
1123 else
1124 NS_ENSURE_SUCCESS(SetParentNativeWindow(aParentNativeWindow),
1125 NS_ERROR_FAILURE);
1127 NS_ENSURE_SUCCESS(SetPositionAndSize(aX, aY, aCX, aCY, false),
1128 NS_ERROR_FAILURE);
1130 return NS_OK;
1131 }
1133 NS_IMETHODIMP nsWebBrowser::Create()
1134 {
1135 NS_ENSURE_STATE(!mDocShell && (mParentNativeWindow || mParentWidget));
1137 nsresult rv = EnsureDocShellTreeOwner();
1138 NS_ENSURE_SUCCESS(rv, rv);
1140 nsCOMPtr<nsIWidget> docShellParentWidget(mParentWidget);
1141 if(!mParentWidget) // We need to create a widget
1142 {
1143 // Create the widget
1144 mInternalWidget = do_CreateInstance(kChildCID, &rv);
1145 NS_ENSURE_SUCCESS(rv, rv);
1147 docShellParentWidget = mInternalWidget;
1148 nsWidgetInitData widgetInit;
1150 widgetInit.clipChildren = true;
1152 widgetInit.mWindowType = eWindowType_child;
1153 nsIntRect bounds(mInitInfo->x, mInitInfo->y, mInitInfo->cx, mInitInfo->cy);
1155 mInternalWidget->SetWidgetListener(this);
1156 mInternalWidget->Create(nullptr, mParentNativeWindow, bounds, nullptr, &widgetInit);
1157 }
1159 nsCOMPtr<nsIDocShell> docShell(do_CreateInstance("@mozilla.org/docshell;1", &rv));
1160 NS_ENSURE_SUCCESS(rv, rv);
1161 rv = SetDocShell(docShell);
1162 NS_ENSURE_SUCCESS(rv, rv);
1164 // get the system default window background colour
1165 LookAndFeel::GetColor(LookAndFeel::eColorID_WindowBackground,
1166 &mBackgroundColor);
1168 // the docshell has been set so we now have our listener registrars.
1169 if (mListenerArray) {
1170 // we had queued up some listeners, let's register them now.
1171 uint32_t count = mListenerArray->Length();
1172 uint32_t i = 0;
1173 NS_ASSERTION(count > 0, "array construction problem");
1174 while (i < count) {
1175 nsWebBrowserListenerState *state = mListenerArray->ElementAt(i);
1176 NS_ASSERTION(state, "array construction problem");
1177 nsCOMPtr<nsISupports> listener = do_QueryReferent(state->mWeakPtr);
1178 NS_ASSERTION(listener, "bad listener");
1179 (void)BindListener(listener, state->mID);
1180 i++;
1181 }
1182 for (uint32_t i = 0, end = mListenerArray->Length(); i < end; i++) {
1183 nsWebBrowserListenerState *state = mListenerArray->ElementAt(i);
1184 delete state;
1185 }
1186 delete mListenerArray;
1187 mListenerArray = nullptr;
1188 }
1190 // HACK ALERT - this registration registers the nsDocShellTreeOwner as a
1191 // nsIWebBrowserListener so it can setup its MouseListener in one of the
1192 // progress callbacks. If we can register the MouseListener another way, this
1193 // registration can go away, and nsDocShellTreeOwner can stop implementing
1194 // nsIWebProgressListener.
1195 nsCOMPtr<nsISupports> supports = nullptr;
1196 (void)mDocShellTreeOwner->QueryInterface(NS_GET_IID(nsIWebProgressListener),
1197 static_cast<void**>(getter_AddRefs(supports)));
1198 (void)BindListener(supports, NS_GET_IID(nsIWebProgressListener));
1200 NS_ENSURE_SUCCESS(mDocShellAsWin->InitWindow(nullptr,
1201 docShellParentWidget, mInitInfo->x, mInitInfo->y, mInitInfo->cx,
1202 mInitInfo->cy), NS_ERROR_FAILURE);
1204 mDocShell->SetName(mInitInfo->name);
1205 if (mContentType == typeChromeWrapper)
1206 {
1207 mDocShell->SetItemType(nsIDocShellTreeItem::typeChrome);
1208 }
1209 else
1210 {
1211 mDocShell->SetItemType(nsIDocShellTreeItem::typeContent);
1212 }
1213 mDocShell->SetTreeOwner(mDocShellTreeOwner);
1215 // If the webbrowser is a content docshell item then we won't hear any
1216 // events from subframes. To solve that we install our own chrome event handler
1217 // that always gets called (even for subframes) for any bubbling event.
1219 if (!mInitInfo->sessionHistory) {
1220 mInitInfo->sessionHistory = do_CreateInstance(NS_SHISTORY_CONTRACTID, &rv);
1221 NS_ENSURE_SUCCESS(rv, rv);
1222 }
1223 mDocShellAsNav->SetSessionHistory(mInitInfo->sessionHistory);
1225 if (XRE_GetProcessType() == GeckoProcessType_Default) {
1226 // Hook up global history. Do not fail if we can't - just warn.
1227 rv = EnableGlobalHistory(mShouldEnableHistory);
1228 NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "EnableGlobalHistory() failed");
1229 }
1231 NS_ENSURE_SUCCESS(mDocShellAsWin->Create(), NS_ERROR_FAILURE);
1233 // Hook into the OnSecurityChange() notification for lock/unlock icon
1234 // updates
1235 nsCOMPtr<nsIDOMWindow> domWindow;
1236 rv = GetContentDOMWindow(getter_AddRefs(domWindow));
1237 if (NS_SUCCEEDED(rv))
1238 {
1239 // this works because the implementation of nsISecureBrowserUI
1240 // (nsSecureBrowserUIImpl) gets a docShell from the domWindow,
1241 // and calls docShell->SetSecurityUI(this);
1242 nsCOMPtr<nsISecureBrowserUI> securityUI =
1243 do_CreateInstance(NS_SECURE_BROWSER_UI_CONTRACTID, &rv);
1244 if (NS_SUCCEEDED(rv))
1245 securityUI->Init(domWindow);
1246 }
1248 mDocShellTreeOwner->AddToWatcher(); // evil twin of Remove in SetDocShell(0)
1249 mDocShellTreeOwner->AddChromeListeners();
1251 delete mInitInfo;
1252 mInitInfo = nullptr;
1254 return NS_OK;
1255 }
1257 NS_IMETHODIMP nsWebBrowser::Destroy()
1258 {
1259 InternalDestroy();
1261 if(!mInitInfo)
1262 mInitInfo = new nsWebBrowserInitInfo();
1264 return NS_OK;
1265 }
1267 NS_IMETHODIMP nsWebBrowser::GetUnscaledDevicePixelsPerCSSPixel(double *aScale)
1268 {
1269 *aScale = mParentWidget ? mParentWidget->GetDefaultScale().scale : 1.0;
1270 return NS_OK;
1271 }
1273 NS_IMETHODIMP nsWebBrowser::SetPosition(int32_t aX, int32_t aY)
1274 {
1275 int32_t cx = 0;
1276 int32_t cy = 0;
1278 GetSize(&cx, &cy);
1280 return SetPositionAndSize(aX, aY, cx, cy, false);
1281 }
1283 NS_IMETHODIMP nsWebBrowser::GetPosition(int32_t* aX, int32_t* aY)
1284 {
1285 return GetPositionAndSize(aX, aY, nullptr, nullptr);
1286 }
1288 NS_IMETHODIMP nsWebBrowser::SetSize(int32_t aCX, int32_t aCY, bool aRepaint)
1289 {
1290 int32_t x = 0;
1291 int32_t y = 0;
1293 GetPosition(&x, &y);
1295 return SetPositionAndSize(x, y, aCX, aCY, aRepaint);
1296 }
1298 NS_IMETHODIMP nsWebBrowser::GetSize(int32_t* aCX, int32_t* aCY)
1299 {
1300 return GetPositionAndSize(nullptr, nullptr, aCX, aCY);
1301 }
1303 NS_IMETHODIMP nsWebBrowser::SetPositionAndSize(int32_t aX, int32_t aY,
1304 int32_t aCX, int32_t aCY, bool aRepaint)
1305 {
1306 if(!mDocShell)
1307 {
1308 mInitInfo->x = aX;
1309 mInitInfo->y = aY;
1310 mInitInfo->cx = aCX;
1311 mInitInfo->cy = aCY;
1312 }
1313 else
1314 {
1315 int32_t doc_x = aX;
1316 int32_t doc_y = aY;
1318 // If there is an internal widget we need to make the docShell coordinates
1319 // relative to the internal widget rather than the calling app's parent.
1320 // We also need to resize our widget then.
1321 if(mInternalWidget)
1322 {
1323 doc_x = doc_y = 0;
1324 NS_ENSURE_SUCCESS(mInternalWidget->Resize(aX, aY, aCX, aCY, aRepaint),
1325 NS_ERROR_FAILURE);
1326 }
1327 // Now reposition/ resize the doc
1328 NS_ENSURE_SUCCESS(mDocShellAsWin->SetPositionAndSize(doc_x, doc_y, aCX, aCY,
1329 aRepaint), NS_ERROR_FAILURE);
1330 }
1332 return NS_OK;
1333 }
1335 NS_IMETHODIMP nsWebBrowser::GetPositionAndSize(int32_t* aX, int32_t* aY,
1336 int32_t* aCX, int32_t* aCY)
1337 {
1338 if(!mDocShell)
1339 {
1340 if(aX)
1341 *aX = mInitInfo->x;
1342 if(aY)
1343 *aY = mInitInfo->y;
1344 if(aCX)
1345 *aCX = mInitInfo->cx;
1346 if(aCY)
1347 *aCY = mInitInfo->cy;
1348 }
1349 else
1350 {
1351 if(mInternalWidget)
1352 {
1353 nsIntRect bounds;
1354 NS_ENSURE_SUCCESS(mInternalWidget->GetBounds(bounds), NS_ERROR_FAILURE);
1356 if(aX)
1357 *aX = bounds.x;
1358 if(aY)
1359 *aY = bounds.y;
1360 if(aCX)
1361 *aCX = bounds.width;
1362 if(aCY)
1363 *aCY = bounds.height;
1364 return NS_OK;
1365 }
1366 else
1367 return mDocShellAsWin->GetPositionAndSize(aX, aY, aCX, aCY); // Can directly return this as it is the
1368 }
1369 return NS_OK;
1370 }
1372 NS_IMETHODIMP nsWebBrowser::Repaint(bool aForce)
1373 {
1374 NS_ENSURE_STATE(mDocShell);
1375 return mDocShellAsWin->Repaint(aForce); // Can directly return this as it is the
1376 } // same interface, thus same returns.
1378 NS_IMETHODIMP nsWebBrowser::GetParentWidget(nsIWidget** aParentWidget)
1379 {
1380 NS_ENSURE_ARG_POINTER(aParentWidget);
1382 *aParentWidget = mParentWidget;
1384 NS_IF_ADDREF(*aParentWidget);
1386 return NS_OK;
1387 }
1389 NS_IMETHODIMP nsWebBrowser::SetParentWidget(nsIWidget* aParentWidget)
1390 {
1391 NS_ENSURE_STATE(!mDocShell);
1393 mParentWidget = aParentWidget;
1394 if(mParentWidget)
1395 mParentNativeWindow = mParentWidget->GetNativeData(NS_NATIVE_WIDGET);
1396 else
1397 mParentNativeWindow = nullptr;
1399 return NS_OK;
1400 }
1402 NS_IMETHODIMP nsWebBrowser::GetParentNativeWindow(nativeWindow* aParentNativeWindow)
1403 {
1404 NS_ENSURE_ARG_POINTER(aParentNativeWindow);
1406 *aParentNativeWindow = mParentNativeWindow;
1408 return NS_OK;
1409 }
1411 NS_IMETHODIMP nsWebBrowser::SetParentNativeWindow(nativeWindow aParentNativeWindow)
1412 {
1413 NS_ENSURE_STATE(!mDocShell);
1415 mParentNativeWindow = aParentNativeWindow;
1417 return NS_OK;
1418 }
1420 NS_IMETHODIMP nsWebBrowser::GetNativeHandle(nsAString& aNativeHandle)
1421 {
1422 // the nativeHandle should be accessed from nsIXULWindow
1423 return NS_ERROR_NOT_IMPLEMENTED;
1424 }
1426 NS_IMETHODIMP nsWebBrowser::GetVisibility(bool* visibility)
1427 {
1428 NS_ENSURE_ARG_POINTER(visibility);
1430 if(!mDocShell)
1431 *visibility = mInitInfo->visible;
1432 else
1433 NS_ENSURE_SUCCESS(mDocShellAsWin->GetVisibility(visibility), NS_ERROR_FAILURE);
1435 return NS_OK;
1436 }
1438 NS_IMETHODIMP nsWebBrowser::SetVisibility(bool aVisibility)
1439 {
1440 if(!mDocShell)
1441 mInitInfo->visible = aVisibility;
1442 else
1443 {
1444 NS_ENSURE_SUCCESS(mDocShellAsWin->SetVisibility(aVisibility), NS_ERROR_FAILURE);
1445 if(mInternalWidget)
1446 mInternalWidget->Show(aVisibility);
1447 }
1449 return NS_OK;
1450 }
1452 NS_IMETHODIMP nsWebBrowser::GetEnabled(bool* aEnabled)
1453 {
1454 if (mInternalWidget) {
1455 *aEnabled = mInternalWidget->IsEnabled();
1456 return NS_OK;
1457 }
1459 return NS_ERROR_FAILURE;
1460 }
1462 NS_IMETHODIMP nsWebBrowser::SetEnabled(bool aEnabled)
1463 {
1464 if (mInternalWidget)
1465 return mInternalWidget->Enable(aEnabled);
1466 return NS_ERROR_FAILURE;
1467 }
1469 NS_IMETHODIMP nsWebBrowser::GetMainWidget(nsIWidget** mainWidget)
1470 {
1471 NS_ENSURE_ARG_POINTER(mainWidget);
1473 if(mInternalWidget)
1474 *mainWidget = mInternalWidget;
1475 else
1476 *mainWidget = mParentWidget;
1478 NS_IF_ADDREF(*mainWidget);
1480 return NS_OK;
1481 }
1483 NS_IMETHODIMP nsWebBrowser::SetFocus()
1484 {
1485 nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
1486 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
1488 nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1489 return fm ? fm->SetFocusedWindow(window) : NS_OK;
1490 }
1492 NS_IMETHODIMP nsWebBrowser::GetTitle(char16_t** aTitle)
1493 {
1494 NS_ENSURE_ARG_POINTER(aTitle);
1495 NS_ENSURE_STATE(mDocShell);
1497 NS_ENSURE_SUCCESS(mDocShellAsWin->GetTitle(aTitle), NS_ERROR_FAILURE);
1499 return NS_OK;
1500 }
1502 NS_IMETHODIMP nsWebBrowser::SetTitle(const char16_t* aTitle)
1503 {
1504 NS_ENSURE_STATE(mDocShell);
1506 NS_ENSURE_SUCCESS(mDocShellAsWin->SetTitle(aTitle), NS_ERROR_FAILURE);
1508 return NS_OK;
1509 }
1511 //*****************************************************************************
1512 // nsWebBrowser::nsIScrollable
1513 //*****************************************************************************
1515 NS_IMETHODIMP nsWebBrowser::GetDefaultScrollbarPreferences(int32_t aScrollOrientation,
1516 int32_t* aScrollbarPref)
1517 {
1518 NS_ENSURE_STATE(mDocShell);
1520 return mDocShellAsScrollable->GetDefaultScrollbarPreferences(aScrollOrientation,
1521 aScrollbarPref);
1522 }
1524 NS_IMETHODIMP nsWebBrowser::SetDefaultScrollbarPreferences(int32_t aScrollOrientation,
1525 int32_t aScrollbarPref)
1526 {
1527 NS_ENSURE_STATE(mDocShell);
1529 return mDocShellAsScrollable->SetDefaultScrollbarPreferences(aScrollOrientation,
1530 aScrollbarPref);
1531 }
1533 NS_IMETHODIMP nsWebBrowser::GetScrollbarVisibility(bool* aVerticalVisible,
1534 bool* aHorizontalVisible)
1535 {
1536 NS_ENSURE_STATE(mDocShell);
1538 return mDocShellAsScrollable->GetScrollbarVisibility(aVerticalVisible,
1539 aHorizontalVisible);
1540 }
1542 //*****************************************************************************
1543 // nsWebBrowser::nsITextScroll
1544 //*****************************************************************************
1546 NS_IMETHODIMP nsWebBrowser::ScrollByLines(int32_t aNumLines)
1547 {
1548 NS_ENSURE_STATE(mDocShell);
1550 return mDocShellAsTextScroll->ScrollByLines(aNumLines);
1551 }
1553 NS_IMETHODIMP nsWebBrowser::ScrollByPages(int32_t aNumPages)
1554 {
1555 NS_ENSURE_STATE(mDocShell);
1557 return mDocShellAsTextScroll->ScrollByPages(aNumPages);
1558 }
1561 //*****************************************************************************
1562 // nsWebBrowser: Listener Helpers
1563 //*****************************************************************************
1565 NS_IMETHODIMP nsWebBrowser::SetDocShell(nsIDocShell* aDocShell)
1566 {
1567 nsCOMPtr<nsIDocShell> kungFuDeathGrip(mDocShell);
1568 if(aDocShell)
1569 {
1570 NS_ENSURE_TRUE(!mDocShell, NS_ERROR_FAILURE);
1572 nsCOMPtr<nsIInterfaceRequestor> req(do_QueryInterface(aDocShell));
1573 nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(aDocShell));
1574 nsCOMPtr<nsIWebNavigation> nav(do_QueryInterface(aDocShell));
1575 nsCOMPtr<nsIScrollable> scrollable(do_QueryInterface(aDocShell));
1576 nsCOMPtr<nsITextScroll> textScroll(do_QueryInterface(aDocShell));
1577 nsCOMPtr<nsIWebProgress> progress(do_GetInterface(aDocShell));
1578 NS_ENSURE_TRUE(req && baseWin && nav && scrollable && textScroll && progress,
1579 NS_ERROR_FAILURE);
1581 mDocShell = aDocShell;
1582 mDocShellAsReq = req;
1583 mDocShellAsWin = baseWin;
1584 mDocShellAsNav = nav;
1585 mDocShellAsScrollable = scrollable;
1586 mDocShellAsTextScroll = textScroll;
1587 mWebProgress = progress;
1589 // By default, do not allow DNS prefetch, so we don't break our frozen
1590 // API. Embeddors who decide to enable it should do so manually.
1591 mDocShell->SetAllowDNSPrefetch(false);
1593 // It's possible to call setIsActive() on us before we have a docshell.
1594 // If we're getting a docshell now, pass along our desired value. The
1595 // default here (true) matches the default of the docshell, so this is
1596 // a no-op unless setIsActive(false) has been called on us.
1597 mDocShell->SetIsActive(mIsActive);
1598 }
1599 else
1600 {
1601 if (mDocShellTreeOwner)
1602 mDocShellTreeOwner->RemoveFromWatcher(); // evil twin of Add in Create()
1603 if (mDocShellAsWin)
1604 mDocShellAsWin->Destroy();
1606 mDocShell = nullptr;
1607 mDocShellAsReq = nullptr;
1608 mDocShellAsWin = nullptr;
1609 mDocShellAsNav = nullptr;
1610 mDocShellAsScrollable = nullptr;
1611 mDocShellAsTextScroll = nullptr;
1612 mWebProgress = nullptr;
1613 }
1615 return NS_OK;
1616 }
1618 NS_IMETHODIMP nsWebBrowser::EnsureDocShellTreeOwner()
1619 {
1620 if(mDocShellTreeOwner)
1621 return NS_OK;
1623 mDocShellTreeOwner = new nsDocShellTreeOwner();
1624 NS_ENSURE_TRUE(mDocShellTreeOwner, NS_ERROR_OUT_OF_MEMORY);
1626 NS_ADDREF(mDocShellTreeOwner);
1627 mDocShellTreeOwner->WebBrowser(this);
1629 return NS_OK;
1630 }
1632 static void DrawThebesLayer(ThebesLayer* aLayer,
1633 gfxContext* aContext,
1634 const nsIntRegion& aRegionToDraw,
1635 DrawRegionClip aClip,
1636 const nsIntRegion& aRegionToInvalidate,
1637 void* aCallbackData)
1638 {
1639 nscolor* color = static_cast<nscolor*>(aCallbackData);
1640 aContext->NewPath();
1641 aContext->SetColor(gfxRGBA(*color));
1642 nsIntRect dirtyRect = aRegionToDraw.GetBounds();
1643 aContext->Rectangle(gfxRect(dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height));
1644 aContext->Fill();
1645 }
1647 void nsWebBrowser::WindowRaised(nsIWidget* aWidget)
1648 {
1649 #if defined(DEBUG_smaug)
1650 nsCOMPtr<nsIDOMDocument> domDocument = do_GetInterface(mDocShell);
1651 nsAutoString documentURI;
1652 domDocument->GetDocumentURI(documentURI);
1653 printf("nsWebBrowser::NS_ACTIVATE %p %s\n", (void*)this,
1654 NS_ConvertUTF16toUTF8(documentURI).get());
1655 #endif
1656 Activate();
1657 }
1659 void nsWebBrowser::WindowLowered(nsIWidget* aWidget)
1660 {
1661 #if defined(DEBUG_smaug)
1662 nsCOMPtr<nsIDOMDocument> domDocument = do_GetInterface(mDocShell);
1663 nsAutoString documentURI;
1664 domDocument->GetDocumentURI(documentURI);
1665 printf("nsWebBrowser::NS_DEACTIVATE %p %s\n", (void*)this,
1666 NS_ConvertUTF16toUTF8(documentURI).get());
1667 #endif
1668 Deactivate();
1669 }
1671 bool nsWebBrowser::PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion)
1672 {
1673 LayerManager* layerManager = aWidget->GetLayerManager();
1674 NS_ASSERTION(layerManager, "Must be in paint event");
1676 layerManager->BeginTransaction();
1677 nsRefPtr<ThebesLayer> root = layerManager->CreateThebesLayer();
1678 if (root) {
1679 nsIntRect dirtyRect = aRegion.GetBounds();
1680 root->SetVisibleRegion(dirtyRect);
1681 layerManager->SetRoot(root);
1682 }
1684 layerManager->EndTransaction(DrawThebesLayer, &mBackgroundColor);
1685 return true;
1686 }
1688 NS_IMETHODIMP nsWebBrowser::GetPrimaryContentWindow(nsIDOMWindow** aDOMWindow)
1689 {
1690 *aDOMWindow = 0;
1692 nsCOMPtr<nsIDocShellTreeItem> item;
1693 NS_ENSURE_TRUE(mDocShellTreeOwner, NS_ERROR_FAILURE);
1694 mDocShellTreeOwner->GetPrimaryContentShell(getter_AddRefs(item));
1695 NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
1697 nsCOMPtr<nsIDocShell> docShell;
1698 docShell = do_QueryInterface(item);
1699 NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
1701 nsCOMPtr<nsIDOMWindow> domWindow = do_GetInterface(docShell);
1702 NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
1704 *aDOMWindow = domWindow;
1705 NS_ADDREF(*aDOMWindow);
1706 return NS_OK;
1708 }
1709 //*****************************************************************************
1710 // nsWebBrowser::nsIWebBrowserFocus
1711 //*****************************************************************************
1713 /* void activate (); */
1714 NS_IMETHODIMP nsWebBrowser::Activate(void)
1715 {
1716 nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1717 nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
1718 if (fm && window)
1719 return fm->WindowRaised(window);
1720 return NS_OK;
1721 }
1723 /* void deactivate (); */
1724 NS_IMETHODIMP nsWebBrowser::Deactivate(void)
1725 {
1726 nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1727 nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
1728 if (fm && window)
1729 return fm->WindowLowered(window);
1730 return NS_OK;
1731 }
1733 /* void setFocusAtFirstElement (); */
1734 NS_IMETHODIMP nsWebBrowser::SetFocusAtFirstElement(void)
1735 {
1736 return NS_OK;
1737 }
1739 /* void setFocusAtLastElement (); */
1740 NS_IMETHODIMP nsWebBrowser::SetFocusAtLastElement(void)
1741 {
1742 return NS_OK;
1743 }
1745 /* attribute nsIDOMWindow focusedWindow; */
1746 NS_IMETHODIMP nsWebBrowser::GetFocusedWindow(nsIDOMWindow * *aFocusedWindow)
1747 {
1748 NS_ENSURE_ARG_POINTER(aFocusedWindow);
1749 *aFocusedWindow = nullptr;
1751 nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
1752 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
1754 nsCOMPtr<nsIDOMElement> focusedElement;
1755 nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1756 return fm ? fm->GetFocusedElementForWindow(window, true, aFocusedWindow,
1757 getter_AddRefs(focusedElement)) : NS_OK;
1758 }
1760 NS_IMETHODIMP nsWebBrowser::SetFocusedWindow(nsIDOMWindow * aFocusedWindow)
1761 {
1762 nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1763 return fm ? fm->SetFocusedWindow(aFocusedWindow) : NS_OK;
1764 }
1766 /* attribute nsIDOMElement focusedElement; */
1767 NS_IMETHODIMP nsWebBrowser::GetFocusedElement(nsIDOMElement * *aFocusedElement)
1768 {
1769 NS_ENSURE_ARG_POINTER(aFocusedElement);
1771 nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mDocShell);
1772 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
1774 nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1775 return fm ? fm->GetFocusedElementForWindow(window, true, nullptr, aFocusedElement) : NS_OK;
1776 }
1778 NS_IMETHODIMP nsWebBrowser::SetFocusedElement(nsIDOMElement * aFocusedElement)
1779 {
1780 nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1781 return fm ? fm->SetFocus(aFocusedElement, 0) : NS_OK;
1782 }
1784 //*****************************************************************************
1785 // nsWebBrowser::nsIWebBrowserStream
1786 //*****************************************************************************
1788 /* void openStream(in nsIURI aBaseURI, in ACString aContentType); */
1789 NS_IMETHODIMP nsWebBrowser::OpenStream(nsIURI *aBaseURI, const nsACString& aContentType)
1790 {
1791 nsresult rv;
1793 if (!mStream) {
1794 mStream = new nsEmbedStream();
1795 if (!mStream)
1796 return NS_ERROR_OUT_OF_MEMORY;
1798 mStreamGuard = do_QueryInterface(mStream);
1799 mStream->InitOwner(this);
1800 rv = mStream->Init();
1801 if (NS_FAILED(rv))
1802 return rv;
1803 }
1805 return mStream->OpenStream(aBaseURI, aContentType);
1806 }
1808 /* void appendToStream([const, array, size_is(aLen)] in octet aData,
1809 * in unsigned long aLen); */
1810 NS_IMETHODIMP nsWebBrowser::AppendToStream(const uint8_t *aData, uint32_t aLen)
1811 {
1812 if (!mStream)
1813 return NS_ERROR_FAILURE;
1815 return mStream->AppendToStream(aData, aLen);
1816 }
1818 /* void closeStream (); */
1819 NS_IMETHODIMP nsWebBrowser::CloseStream()
1820 {
1821 nsresult rv;
1823 if (!mStream)
1824 return NS_ERROR_FAILURE;
1825 rv = mStream->CloseStream();
1827 // release
1828 mStream = 0;
1829 mStreamGuard = 0;
1831 return rv;
1832 }