2009-06-30 20:39:22 +00:00
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
2012-06-12 22:01:25 +00:00
/* vim: set sw=2 sts=2 ts=8 et tw=80 : */
2012-05-21 11:12:37 +00:00
/* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/. */
2009-06-30 20:39:22 +00:00
2012-07-17 23:59:45 +00:00
# include "base/basictypes.h"
2012-08-02 06:02:29 +00:00
# include "TabChild.h"
2012-07-17 23:59:45 +00:00
# include "BasicLayers.h"
2012-08-02 06:02:29 +00:00
# include "Blob.h"
# include "ContentChild.h"
2012-07-17 23:59:45 +00:00
# include "IndexedDBChild.h"
2010-11-24 13:58:21 +00:00
# include "mozilla/IntentionalCrash.h"
2012-07-17 23:59:45 +00:00
# include "mozilla/docshell/OfflineCacheUpdateChild.h"
2010-07-19 18:33:33 +00:00
# include "mozilla/dom/PContentChild.h"
2010-05-17 11:25:22 +00:00
# include "mozilla/dom/PContentDialogChild.h"
2012-07-17 23:59:45 +00:00
# include "mozilla/ipc/DocumentRendererChild.h"
# include "mozilla/layers/CompositorChild.h"
2010-08-20 23:24:41 +00:00
# include "mozilla/layers/PLayersChild.h"
2010-08-20 23:24:41 +00:00
# include "mozilla/layout/RenderFrameChild.h"
2012-08-08 20:37:57 +00:00
# include "mozilla/unused.h"
2009-06-30 20:39:22 +00:00
# include "nsComponentManagerUtils.h"
2012-07-17 23:59:45 +00:00
# include "nsComponentManagerUtils.h"
# include "nsContentUtils.h"
# include "nsEmbedCID.h"
# include "nsEventListenerManager.h"
2009-06-30 20:39:22 +00:00
# include "nsIBaseWindow.h"
2012-07-17 23:59:45 +00:00
# include "nsIComponentManager.h"
# include "nsIDOMClassInfo.h"
# include "nsIDOMEvent.h"
2009-10-29 17:58:31 +00:00
# include "nsIDOMWindow.h"
2012-07-17 23:59:45 +00:00
# include "nsIDOMWindowUtils.h"
2010-08-13 08:06:40 +00:00
# include "nsIDocShell.h"
2009-06-30 20:39:22 +00:00
# include "nsIDocShellTreeItem.h"
2009-10-29 17:58:31 +00:00
# include "nsIInterfaceRequestorUtils.h"
2009-11-05 18:14:22 +00:00
# include "nsIInterfaceRequestorUtils.h"
2012-07-17 23:59:45 +00:00
# include "nsIJSContextStack.h"
# include "nsIJSRuntimeService.h"
# include "nsISSLStatusProvider.h"
# include "nsIScriptContext.h"
# include "nsIScriptGlobalObject.h"
# include "nsIScriptSecurityManager.h"
# include "nsISecureBrowserUI.h"
# include "nsIServiceManager.h"
2009-11-05 18:14:22 +00:00
# include "nsISupportsImpl.h"
2010-03-26 18:39:39 +00:00
# include "nsIURI.h"
2012-07-17 23:59:45 +00:00
# include "nsIView.h"
# include "nsIWebBrowser.h"
2009-11-05 18:14:22 +00:00
# include "nsIWebBrowserFocus.h"
2012-07-17 23:59:45 +00:00
# include "nsIWebBrowserSetup.h"
# include "nsIWebProgress.h"
2010-02-20 17:05:20 +00:00
# include "nsIXPCSecurityManager.h"
2010-05-17 11:25:22 +00:00
# include "nsInterfaceHashtable.h"
2012-07-17 23:59:45 +00:00
# include "nsPIDOMWindow.h"
# include "nsPIWindowRoot.h"
2010-03-24 10:47:18 +00:00
# include "nsPresContext.h"
2012-07-20 06:48:27 +00:00
# include "nsPrintfCString.h"
2012-07-17 23:59:45 +00:00
# include "nsScriptLoader.h"
2010-08-13 08:06:40 +00:00
# include "nsSerializationHelper.h"
2012-07-17 23:59:45 +00:00
# include "nsThreadUtils.h"
# include "nsWeakReference.h"
2010-09-10 05:00:08 +00:00
# include "PCOMContentPermissionRequestChild.h"
2012-08-02 06:02:29 +00:00
# include "StructuredCloneUtils.h"
2011-01-14 22:03:21 +00:00
# include "xpcpublic.h"
2009-07-07 16:26:49 +00:00
2012-08-02 06:02:29 +00:00
using namespace mozilla ;
2009-08-12 16:18:08 +00:00
using namespace mozilla : : dom ;
2010-10-26 22:20:53 +00:00
using namespace mozilla : : ipc ;
2010-08-20 23:24:41 +00:00
using namespace mozilla : : layers ;
2010-08-20 23:24:41 +00:00
using namespace mozilla : : layout ;
2010-10-20 17:12:32 +00:00
using namespace mozilla : : docshell ;
2012-06-01 17:21:12 +00:00
using namespace mozilla : : dom : : indexedDB ;
2012-08-12 01:42:34 +00:00
using namespace mozilla : : widget ;
2009-06-30 20:39:22 +00:00
2009-11-17 14:22:23 +00:00
NS_IMPL_ISUPPORTS1 ( ContentListener , nsIDOMEventListener )
NS_IMETHODIMP
ContentListener : : HandleEvent ( nsIDOMEvent * aEvent )
{
RemoteDOMEvent remoteEvent ;
remoteEvent . mEvent = do_QueryInterface ( aEvent ) ;
NS_ENSURE_STATE ( remoteEvent . mEvent ) ;
2010-07-19 18:33:33 +00:00
mTabChild - > SendEvent ( remoteEvent ) ;
2009-11-17 14:22:23 +00:00
return NS_OK ;
}
2010-05-17 11:25:22 +00:00
class ContentDialogChild : public PContentDialogChild
{
public :
2010-11-09 02:49:00 +00:00
virtual bool Recv__delete__ ( const InfallibleTArray < int > & aIntParams ,
const InfallibleTArray < nsString > & aStringParams ) ;
2010-05-17 11:25:22 +00:00
} ;
2012-07-22 00:16:11 +00:00
TabChild : : TabChild ( PRUint32 aChromeFlags , bool aIsBrowserElement ,
PRUint32 aAppId )
2012-07-30 14:20:58 +00:00
: mRemoteFrame ( nullptr )
, mTabChildGlobal ( nullptr )
2010-07-19 18:33:33 +00:00
, mChromeFlags ( aChromeFlags )
2011-07-15 21:46:56 +00:00
, mOuterRect ( 0 , 0 , 0 , 0 )
2011-10-20 22:17:09 +00:00
, mLastBackgroundColor ( NS_RGB ( 255 , 255 , 255 ) )
2012-06-12 22:01:25 +00:00
, mDidFakeShow ( false )
2012-07-22 00:16:11 +00:00
, mIsBrowserElement ( aIsBrowserElement )
, mAppId ( aAppId )
2009-06-30 20:39:22 +00:00
{
2010-05-17 11:21:55 +00:00
printf ( " creating %d! \n " , NS_IsMainThread ( ) ) ;
2009-11-05 18:14:22 +00:00
}
2009-06-30 20:39:22 +00:00
2012-08-08 20:37:57 +00:00
nsresult
TabChild : : Observe ( nsISupports * aSubject ,
const char * aTopic ,
const PRUnichar * aData )
{
if ( ! strcmp ( aTopic , " dom-touch-listener-added " ) ) {
nsCOMPtr < nsIDOMWindow > subject ( do_QueryInterface ( aSubject ) ) ;
nsCOMPtr < nsIDOMWindow > win ( do_GetInterface ( mWebNav ) ) ;
nsCOMPtr < nsIDOMWindow > topSubject ;
subject - > GetTop ( getter_AddRefs ( topSubject ) ) ;
if ( win = = topSubject ) {
SendNotifyDOMTouchListenerAdded ( ) ;
}
2012-08-08 20:38:06 +00:00
} else if ( ! strcmp ( aTopic , " cancel-default-pan-zoom " ) ) {
nsCOMPtr < nsIDocShell > docShell ( do_QueryInterface ( aSubject ) ) ;
nsCOMPtr < nsITabChild > tabChild ( GetTabChildFrom ( docShell ) ) ;
if ( tabChild = = this ) {
mRemoteFrame - > CancelDefaultPanZoom ( ) ;
}
2012-08-09 04:39:02 +00:00
} else if ( ! strcmp ( aTopic , " browser-zoom-to-rect " ) ) {
nsCOMPtr < nsIDocShell > docShell ( do_QueryInterface ( aSubject ) ) ;
nsCOMPtr < nsITabChild > tabChild ( GetTabChildFrom ( docShell ) ) ;
if ( tabChild = = this ) {
gfxRect rect ;
sscanf ( NS_ConvertUTF16toUTF8 ( aData ) . get ( ) ,
" { \" x \" :%lf, \" y \" :%lf, \" w \" :%lf, \" h \" :%lf} " ,
& rect . x , & rect . y , & rect . width , & rect . height ) ;
SendZoomToRect ( rect ) ;
}
2012-08-08 20:37:57 +00:00
}
return NS_OK ;
}
2009-11-05 18:14:22 +00:00
nsresult
TabChild : : Init ( )
{
nsCOMPtr < nsIWebBrowser > webBrowser = do_CreateInstance ( NS_WEBBROWSER_CONTRACTID ) ;
if ( ! webBrowser ) {
NS_ERROR ( " Couldn't create a nsWebBrowser? " ) ;
return NS_ERROR_FAILURE ;
}
webBrowser - > SetContainerWindow ( this ) ;
mWebNav = do_QueryInterface ( webBrowser ) ;
NS_ASSERTION ( mWebNav , " nsWebBrowser doesn't implement nsIWebNavigation? " ) ;
nsCOMPtr < nsIDocShellTreeItem > docShellItem ( do_QueryInterface ( mWebNav ) ) ;
docShellItem - > SetItemType ( nsIDocShellTreeItem : : typeContentWrapper ) ;
2012-08-08 20:37:57 +00:00
nsCOMPtr < nsIObserverService > observerService =
do_GetService ( NS_OBSERVERSERVICE_CONTRACTID ) ;
if ( observerService ) {
observerService - > AddObserver ( this ,
" dom-touch-listener-added " ,
false ) ;
2012-08-08 20:38:06 +00:00
observerService - > AddObserver ( this ,
" cancel-default-pan-zoom " ,
false ) ;
2012-08-09 04:39:02 +00:00
observerService - > AddObserver ( this ,
" browser-zoom-to-rect " ,
false ) ;
2012-08-08 20:37:57 +00:00
}
2009-11-05 18:14:22 +00:00
return NS_OK ;
}
2010-05-17 11:25:22 +00:00
NS_INTERFACE_MAP_BEGIN ( TabChild )
2011-06-16 18:21:08 +00:00
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS ( nsISupports , nsIWebBrowserChrome )
2010-05-17 11:25:22 +00:00
NS_INTERFACE_MAP_ENTRY ( nsIWebBrowserChrome )
NS_INTERFACE_MAP_ENTRY ( nsIWebBrowserChrome2 )
NS_INTERFACE_MAP_ENTRY ( nsIEmbeddingSiteWindow )
NS_INTERFACE_MAP_ENTRY ( nsIWebBrowserChromeFocus )
NS_INTERFACE_MAP_ENTRY ( nsIInterfaceRequestor )
NS_INTERFACE_MAP_ENTRY ( nsIWindowProvider )
NS_INTERFACE_MAP_ENTRY ( nsITabChild )
NS_INTERFACE_MAP_ENTRY ( nsIDialogCreator )
2010-09-18 02:11:05 +00:00
NS_INTERFACE_MAP_ENTRY ( nsSupportsWeakReference )
2010-05-17 11:25:22 +00:00
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF ( TabChild )
NS_IMPL_RELEASE ( TabChild )
2009-11-05 18:14:22 +00:00
NS_IMETHODIMP
TabChild : : SetStatus ( PRUint32 aStatusType , const PRUnichar * aStatus )
{
2011-01-04 16:40:54 +00:00
// FIXME/bug 617804: should the platform support this?
return NS_OK ;
2009-11-05 18:14:22 +00:00
}
NS_IMETHODIMP
TabChild : : GetWebBrowser ( nsIWebBrowser * * aWebBrowser )
{
2010-11-03 13:00:49 +00:00
NS_NOTREACHED ( " TabChild::GetWebBrowser not supported in TabChild " ) ;
2009-11-05 18:14:22 +00:00
return NS_ERROR_NOT_IMPLEMENTED ;
}
NS_IMETHODIMP
TabChild : : SetWebBrowser ( nsIWebBrowser * aWebBrowser )
{
2010-11-03 13:00:49 +00:00
NS_NOTREACHED ( " TabChild::SetWebBrowser not supported in TabChild " ) ;
2009-11-05 18:14:22 +00:00
return NS_ERROR_NOT_IMPLEMENTED ;
}
NS_IMETHODIMP
TabChild : : GetChromeFlags ( PRUint32 * aChromeFlags )
{
2010-07-19 18:33:33 +00:00
* aChromeFlags = mChromeFlags ;
return NS_OK ;
2009-11-05 18:14:22 +00:00
}
NS_IMETHODIMP
TabChild : : SetChromeFlags ( PRUint32 aChromeFlags )
{
2010-11-03 13:00:49 +00:00
NS_NOTREACHED ( " trying to SetChromeFlags from content process? " ) ;
2009-11-05 18:14:22 +00:00
return NS_ERROR_NOT_IMPLEMENTED ;
}
NS_IMETHODIMP
TabChild : : DestroyBrowserWindow ( )
{
2010-11-03 13:00:49 +00:00
NS_NOTREACHED ( " TabChild::SetWebBrowser not supported in TabChild " ) ;
2009-11-05 18:14:22 +00:00
return NS_ERROR_NOT_IMPLEMENTED ;
}
NS_IMETHODIMP
TabChild : : SizeBrowserTo ( PRInt32 aCX , PRInt32 aCY )
{
2010-11-03 13:00:49 +00:00
NS_NOTREACHED ( " TabChild::SizeBrowserTo not supported in TabChild " ) ;
2009-11-05 18:14:22 +00:00
return NS_ERROR_NOT_IMPLEMENTED ;
}
NS_IMETHODIMP
TabChild : : ShowAsModal ( )
{
2010-11-03 13:00:49 +00:00
NS_NOTREACHED ( " TabChild::ShowAsModal not supported in TabChild " ) ;
2009-11-05 18:14:22 +00:00
return NS_ERROR_NOT_IMPLEMENTED ;
}
NS_IMETHODIMP
2011-09-29 06:19:26 +00:00
TabChild : : IsWindowModal ( bool * aRetVal )
2009-11-05 18:14:22 +00:00
{
2011-10-17 14:59:28 +00:00
* aRetVal = false ;
2009-11-05 18:14:22 +00:00
return NS_OK ;
}
NS_IMETHODIMP
TabChild : : ExitModalEventLoop ( nsresult aStatus )
{
2010-11-03 13:00:49 +00:00
NS_NOTREACHED ( " TabChild::ExitModalEventLoop not supported in TabChild " ) ;
2009-11-05 18:14:22 +00:00
return NS_ERROR_NOT_IMPLEMENTED ;
}
2009-06-30 20:39:22 +00:00
2009-11-05 18:14:22 +00:00
NS_IMETHODIMP
TabChild : : SetStatusWithContext ( PRUint32 aStatusType ,
const nsAString & aStatusText ,
nsISupports * aStatusContext )
{
2011-07-07 15:11:58 +00:00
// FIXME/bug 617804: should the platform support this?
return NS_OK ;
2009-11-05 18:14:22 +00:00
}
NS_IMETHODIMP
TabChild : : SetDimensions ( PRUint32 aFlags , PRInt32 aX , PRInt32 aY ,
PRInt32 aCx , PRInt32 aCy )
{
2010-11-03 13:00:49 +00:00
NS_NOTREACHED ( " TabChild::SetDimensions not supported in TabChild " ) ;
2009-11-05 18:14:22 +00:00
return NS_ERROR_NOT_IMPLEMENTED ;
}
NS_IMETHODIMP
TabChild : : GetDimensions ( PRUint32 aFlags , PRInt32 * aX ,
PRInt32 * aY , PRInt32 * aCx , PRInt32 * aCy )
{
2011-07-15 21:46:56 +00:00
if ( aX ) {
* aX = mOuterRect . x ;
}
if ( aY ) {
* aY = mOuterRect . y ;
}
if ( aCx ) {
* aCx = mOuterRect . width ;
}
if ( aCy ) {
* aCy = mOuterRect . height ;
}
2010-11-03 13:00:49 +00:00
2011-07-15 21:46:56 +00:00
return NS_OK ;
2009-11-05 18:14:22 +00:00
}
NS_IMETHODIMP
TabChild : : SetFocus ( )
{
2010-11-03 13:00:49 +00:00
NS_NOTREACHED ( " TabChild::SetFocus not supported in TabChild " ) ;
2009-11-05 18:14:22 +00:00
return NS_ERROR_NOT_IMPLEMENTED ;
}
NS_IMETHODIMP
2011-09-29 06:19:26 +00:00
TabChild : : GetVisibility ( bool * aVisibility )
2009-11-05 18:14:22 +00:00
{
2011-10-17 14:59:28 +00:00
* aVisibility = true ;
2009-11-05 18:14:22 +00:00
return NS_OK ;
}
NS_IMETHODIMP
2011-09-29 06:19:26 +00:00
TabChild : : SetVisibility ( bool aVisibility )
2009-11-05 18:14:22 +00:00
{
2011-06-22 20:43:05 +00:00
// should the platform support this? Bug 666365
return NS_OK ;
2009-11-05 18:14:22 +00:00
}
NS_IMETHODIMP
TabChild : : GetTitle ( PRUnichar * * aTitle )
{
2010-11-03 13:00:49 +00:00
NS_NOTREACHED ( " TabChild::GetTitle not supported in TabChild " ) ;
2009-11-05 18:14:22 +00:00
return NS_ERROR_NOT_IMPLEMENTED ;
}
NS_IMETHODIMP
TabChild : : SetTitle ( const PRUnichar * aTitle )
{
2011-01-04 16:40:54 +00:00
// FIXME/bug 617804: should the platform support this?
return NS_OK ;
2009-11-05 18:14:22 +00:00
}
NS_IMETHODIMP
TabChild : : GetSiteWindow ( void * * aSiteWindow )
{
2010-11-03 13:00:49 +00:00
NS_NOTREACHED ( " TabChild::GetSiteWindow not supported in TabChild " ) ;
2009-11-05 18:14:22 +00:00
return NS_ERROR_NOT_IMPLEMENTED ;
}
NS_IMETHODIMP
TabChild : : Blur ( )
{
2010-11-03 13:00:49 +00:00
NS_NOTREACHED ( " TabChild::Blur not supported in TabChild " ) ;
2009-11-05 18:14:22 +00:00
return NS_ERROR_NOT_IMPLEMENTED ;
}
NS_IMETHODIMP
TabChild : : FocusNextElement ( )
{
2011-10-17 14:59:28 +00:00
SendMoveFocus ( true ) ;
2009-11-05 18:14:22 +00:00
return NS_OK ;
}
NS_IMETHODIMP
TabChild : : FocusPrevElement ( )
{
2011-10-17 14:59:28 +00:00
SendMoveFocus ( false ) ;
2009-11-05 18:14:22 +00:00
return NS_OK ;
2009-10-28 20:41:46 +00:00
}
2009-06-30 20:39:22 +00:00
2010-01-01 01:34:06 +00:00
NS_IMETHODIMP
TabChild : : GetInterface ( const nsIID & aIID , void * * aSink )
{
// XXXbz should we restrict the set of interfaces we hand out here?
// See bug 537429
return QueryInterface ( aIID , aSink ) ;
}
2010-01-01 01:35:55 +00:00
NS_IMETHODIMP
TabChild : : ProvideWindow ( nsIDOMWindow * aParent , PRUint32 aChromeFlags ,
2011-09-29 06:19:26 +00:00
bool aCalledFromJS ,
bool aPositionSpecified , bool aSizeSpecified ,
2010-01-01 01:35:55 +00:00
nsIURI * aURI , const nsAString & aName ,
2011-09-29 06:19:26 +00:00
const nsACString & aFeatures , bool * aWindowIsNew ,
2010-01-01 01:35:55 +00:00
nsIDOMWindow * * aReturn )
{
2012-07-30 14:20:58 +00:00
* aReturn = nullptr ;
2010-01-01 01:35:55 +00:00
2012-06-12 22:01:25 +00:00
// If aParent is inside an <iframe mozbrowser> and this isn't a request to
// open a modal-type window, we're going to create a new <iframe mozbrowser>
// and return its window here.
nsCOMPtr < nsIDocShell > docshell = do_GetInterface ( aParent ) ;
2012-07-19 05:26:21 +00:00
bool isInContentBoundary = false ;
2012-06-12 22:01:25 +00:00
if ( docshell ) {
2012-07-19 05:26:21 +00:00
docshell - > GetIsBelowContentBoundary ( & isInContentBoundary ) ;
2012-06-12 22:01:25 +00:00
}
2012-07-19 05:26:21 +00:00
if ( isInContentBoundary & &
2012-06-12 22:01:25 +00:00
! ( aChromeFlags & ( nsIWebBrowserChrome : : CHROME_MODAL |
nsIWebBrowserChrome : : CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome : : CHROME_OPENAS_CHROME ) ) ) {
// Note that BrowserFrameProvideWindow may return NS_ERROR_ABORT if the
// open window call was canceled. It's important that we pass this error
// code back to our caller.
return BrowserFrameProvideWindow ( aParent , aURI , aName , aFeatures ,
aWindowIsNew , aReturn ) ;
}
// Otherwise, create a new top-level window.
2010-07-19 18:33:33 +00:00
PBrowserChild * newChild ;
if ( ! CallCreateWindow ( & newChild ) ) {
2010-01-01 01:35:55 +00:00
return NS_ERROR_NOT_AVAILABLE ;
}
2011-10-17 14:59:28 +00:00
* aWindowIsNew = true ;
2010-01-01 01:35:55 +00:00
nsCOMPtr < nsIDOMWindow > win =
do_GetInterface ( static_cast < TabChild * > ( newChild ) - > mWebNav ) ;
win . forget ( aReturn ) ;
return NS_OK ;
}
2012-06-12 22:01:25 +00:00
nsresult
TabChild : : BrowserFrameProvideWindow ( nsIDOMWindow * aOpener ,
nsIURI * aURI ,
const nsAString & aName ,
const nsACString & aFeatures ,
bool * aWindowIsNew ,
nsIDOMWindow * * aReturn )
{
2012-07-30 14:20:58 +00:00
* aReturn = nullptr ;
2012-06-12 22:01:25 +00:00
2012-08-09 02:58:06 +00:00
PRUint32 chromeFlags = 0 ;
nsRefPtr < TabChild > newChild = new TabChild ( chromeFlags ,
mIsBrowserElement , mAppId ) ;
if ( ! NS_SUCCEEDED ( newChild - > Init ( ) ) ) {
return NS_ERROR_ABORT ;
}
unused < < Manager ( ) - > SendPBrowserConstructor (
// We release this ref in DeallocPBrowserChild
nsRefPtr < TabChild > ( newChild ) . forget ( ) . get ( ) ,
chromeFlags , mIsBrowserElement , this ) ;
2012-06-12 22:01:25 +00:00
nsCAutoString spec ;
2012-08-01 03:12:04 +00:00
if ( aURI ) {
aURI - > GetSpec ( spec ) ;
}
2012-06-12 22:01:25 +00:00
NS_ConvertUTF8toUTF16 url ( spec ) ;
nsString name ( aName ) ;
NS_ConvertUTF8toUTF16 features ( aFeatures ) ;
newChild - > SendBrowserFrameOpenWindow ( this , url , name ,
features , aWindowIsNew ) ;
if ( ! * aWindowIsNew ) {
PBrowserChild : : Send__delete__ ( newChild ) ;
return NS_ERROR_ABORT ;
}
// Unfortunately we don't get a window unless we've shown the frame. That's
// pretty bogus; see bug 763602.
newChild - > DoFakeShow ( ) ;
nsCOMPtr < nsIDOMWindow > win = do_GetInterface ( newChild - > mWebNav ) ;
win . forget ( aReturn ) ;
return NS_OK ;
}
2012-03-21 18:07:31 +00:00
static nsInterfaceHashtable < nsPtrHashKey < PContentDialogChild > , nsIDialogParamBlock > gActiveDialogs ;
2010-05-17 11:25:22 +00:00
NS_IMETHODIMP
TabChild : : OpenDialog ( PRUint32 aType , const nsACString & aName ,
const nsACString & aFeatures ,
nsIDialogParamBlock * aArguments ,
nsIDOMElement * aFrameElement )
{
if ( ! gActiveDialogs . IsInitialized ( ) ) {
2012-05-18 17:30:49 +00:00
gActiveDialogs . Init ( ) ;
2010-05-17 11:25:22 +00:00
}
2010-11-09 02:49:00 +00:00
InfallibleTArray < PRInt32 > intParams ;
InfallibleTArray < nsString > stringParams ;
2010-05-17 11:25:22 +00:00
ParamsToArrays ( aArguments , intParams , stringParams ) ;
PContentDialogChild * dialog =
SendPContentDialogConstructor ( aType , nsCString ( aName ) ,
nsCString ( aFeatures ) , intParams , stringParams ) ;
2012-05-18 17:30:49 +00:00
gActiveDialogs . Put ( dialog , aArguments ) ;
2010-05-17 11:25:22 +00:00
nsIThread * thread = NS_GetCurrentThread ( ) ;
while ( gActiveDialogs . GetWeak ( dialog ) ) {
if ( ! NS_ProcessNextEvent ( thread ) ) {
break ;
}
}
return NS_OK ;
}
bool
2010-11-09 02:49:00 +00:00
ContentDialogChild : : Recv__delete__ ( const InfallibleTArray < int > & aIntParams ,
const InfallibleTArray < nsString > & aStringParams )
2010-05-17 11:25:22 +00:00
{
nsCOMPtr < nsIDialogParamBlock > params ;
if ( gActiveDialogs . Get ( this , getter_AddRefs ( params ) ) ) {
TabChild : : ArraysToParams ( aIntParams , aStringParams , params ) ;
gActiveDialogs . Remove ( this ) ;
}
return true ;
}
void
TabChild : : ParamsToArrays ( nsIDialogParamBlock * aParams ,
2010-11-09 02:49:00 +00:00
InfallibleTArray < int > & aIntParams ,
InfallibleTArray < nsString > & aStringParams )
2010-05-17 11:25:22 +00:00
{
if ( aParams ) {
for ( PRInt32 i = 0 ; i < 8 ; + + i ) {
PRInt32 val = 0 ;
aParams - > GetInt ( i , & val ) ;
aIntParams . AppendElement ( val ) ;
}
PRInt32 j = 0 ;
2010-11-03 13:02:33 +00:00
nsXPIDLString strVal ;
while ( NS_SUCCEEDED ( aParams - > GetString ( j , getter_Copies ( strVal ) ) ) ) {
2010-05-17 11:25:22 +00:00
aStringParams . AppendElement ( strVal ) ;
+ + j ;
}
}
}
void
2010-11-09 02:49:00 +00:00
TabChild : : ArraysToParams ( const InfallibleTArray < int > & aIntParams ,
const InfallibleTArray < nsString > & aStringParams ,
2010-05-17 11:25:22 +00:00
nsIDialogParamBlock * aParams )
{
if ( aParams ) {
for ( PRInt32 i = 0 ; PRUint32 ( i ) < aIntParams . Length ( ) ; + + i ) {
aParams - > SetInt ( i , aIntParams [ i ] ) ;
}
for ( PRInt32 j = 0 ; PRUint32 ( j ) < aStringParams . Length ( ) ; + + j ) {
aParams - > SetString ( j , aStringParams [ j ] . get ( ) ) ;
}
}
}
2010-08-20 23:24:40 +00:00
void
TabChild : : DestroyWindow ( )
2009-10-28 20:41:46 +00:00
{
nsCOMPtr < nsIBaseWindow > baseWindow = do_QueryInterface ( mWebNav ) ;
if ( baseWindow )
baseWindow - > Destroy ( ) ;
2009-07-07 16:26:49 +00:00
2010-08-20 23:24:41 +00:00
// NB: the order of mWidget->Destroy() and mRemoteFrame->Destroy()
// is important: we want to kill off remote layers before their
// frames
if ( mWidget ) {
2010-08-20 23:24:41 +00:00
mWidget - > Destroy ( ) ;
2010-03-01 19:05:48 +00:00
}
2009-07-07 16:26:49 +00:00
2010-08-20 23:24:41 +00:00
if ( mRemoteFrame ) {
mRemoteFrame - > Destroy ( ) ;
2012-07-30 14:20:58 +00:00
mRemoteFrame = nullptr ;
2010-07-26 18:49:09 +00:00
}
2009-08-12 16:18:08 +00:00
}
2009-07-14 07:33:50 +00:00
2012-07-17 23:59:45 +00:00
bool
TabChild : : UseDirectCompositor ( )
{
return ! ! CompositorChild : : Get ( ) ;
}
2010-07-21 23:23:03 +00:00
void
TabChild : : ActorDestroy ( ActorDestroyReason why )
{
2011-08-09 19:38:26 +00:00
if ( mTabChildGlobal ) {
// The messageManager relays messages via the TabChild which
// no longer exists.
static_cast < nsFrameMessageManager * >
( mTabChildGlobal - > mMessageManager . get ( ) ) - > Disconnect ( ) ;
2012-07-30 14:20:58 +00:00
mTabChildGlobal - > mMessageManager = nullptr ;
2011-08-09 19:38:26 +00:00
}
2010-07-21 23:23:03 +00:00
}
2009-08-12 16:18:08 +00:00
TabChild : : ~ TabChild ( )
{
2009-11-05 18:14:22 +00:00
nsCOMPtr < nsIWebBrowser > webBrowser = do_QueryInterface ( mWebNav ) ;
if ( webBrowser ) {
2012-07-30 14:20:58 +00:00
webBrowser - > SetContainerWindow ( nullptr ) ;
2009-11-05 18:14:22 +00:00
}
2010-02-20 17:05:20 +00:00
if ( mCx ) {
2010-08-18 10:02:49 +00:00
DestroyCx ( ) ;
2010-02-20 17:05:20 +00:00
}
2010-08-23 08:44:43 +00:00
2011-08-09 19:38:26 +00:00
if ( mTabChildGlobal ) {
2011-10-17 14:59:28 +00:00
nsEventListenerManager * elm = mTabChildGlobal - > GetListenerManager ( false ) ;
2011-08-09 19:38:26 +00:00
if ( elm ) {
elm - > Disconnect ( ) ;
}
2012-07-30 14:20:58 +00:00
mTabChildGlobal - > mTabChild = nullptr ;
2010-08-23 08:44:43 +00:00
}
2009-06-30 20:39:22 +00:00
}
2009-09-17 23:09:20 +00:00
bool
2010-07-19 18:33:33 +00:00
TabChild : : RecvLoadURL ( const nsCString & uri )
2009-06-30 20:39:22 +00:00
{
2009-07-29 21:12:15 +00:00
printf ( " loading %s, %d \n " , uri . get ( ) , NS_IsMainThread ( ) ) ;
2009-06-30 20:39:22 +00:00
2009-10-28 02:01:38 +00:00
nsresult rv = mWebNav - > LoadURI ( NS_ConvertUTF8toUTF16 ( uri ) . get ( ) ,
nsIWebNavigation : : LOAD_FLAGS_NONE ,
NULL , NULL , NULL ) ;
2009-10-28 20:41:46 +00:00
if ( NS_FAILED ( rv ) ) {
NS_WARNING ( " mWebNav->LoadURI failed. Eating exception, what else can I do? " ) ;
}
2009-11-06 20:43:39 +00:00
2011-08-09 19:38:26 +00:00
return true ;
2009-06-30 20:39:22 +00:00
}
2012-06-12 22:01:25 +00:00
void
TabChild : : DoFakeShow ( )
{
RecvShow ( nsIntSize ( 0 , 0 ) ) ;
mDidFakeShow = true ;
}
2009-09-17 23:09:20 +00:00
bool
2010-08-20 23:24:40 +00:00
TabChild : : RecvShow ( const nsIntSize & size )
2009-06-30 20:39:22 +00:00
{
2012-06-12 22:01:25 +00:00
if ( mDidFakeShow ) {
return true ;
}
2010-08-20 23:24:40 +00:00
printf ( " [TabChild] SHOW (w,h)= (%d, %d) \n " , size . width , size . height ) ;
nsCOMPtr < nsIBaseWindow > baseWindow = do_QueryInterface ( mWebNav ) ;
if ( ! baseWindow ) {
NS_ERROR ( " mWebNav doesn't QI to nsIBaseWindow " ) ;
return false ;
}
2010-08-20 23:24:41 +00:00
if ( ! InitWidget ( size ) ) {
2011-08-09 19:38:26 +00:00
// We can fail to initialize our widget if the <browser
// remote> has already been destroyed, and we couldn't hook
// into the parent-process's layer system. That's not a fatal
// error.
return true ;
2010-08-20 23:24:40 +00:00
}
baseWindow - > InitWindow ( 0 , mWidget ,
0 , 0 , size . width , size . height ) ;
2010-08-20 23:24:40 +00:00
baseWindow - > Create ( ) ;
2012-07-22 00:16:11 +00:00
nsCOMPtr < nsIDocShell > docShell = do_GetInterface ( mWebNav ) ;
MOZ_ASSERT ( docShell ) ;
if ( docShell ) {
docShell - > SetAppId ( mAppId ) ;
if ( mIsBrowserElement ) {
docShell - > SetIsBrowserElement ( ) ;
}
}
2011-10-17 14:59:28 +00:00
baseWindow - > SetVisibility ( true ) ;
2010-08-20 23:24:40 +00:00
// IPC uses a WebBrowser object for which DNS prefetching is turned off
// by default. But here we really want it, so enable it explicitly
nsCOMPtr < nsIWebBrowserSetup > webBrowserSetup = do_QueryInterface ( baseWindow ) ;
if ( webBrowserSetup ) {
webBrowserSetup - > SetProperty ( nsIWebBrowserSetup : : SETUP_ALLOW_DNS_PREFETCH ,
2011-10-17 14:59:28 +00:00
true ) ;
2010-08-20 23:24:40 +00:00
} else {
NS_WARNING ( " baseWindow doesn't QI to nsIWebBrowserSetup, skipping "
" DNS prefetching enable step. " ) ;
}
return InitTabChildGlobal ( ) ;
2009-06-30 20:39:22 +00:00
}
2009-09-17 23:09:20 +00:00
bool
2011-07-15 21:46:56 +00:00
TabChild : : RecvUpdateDimensions ( const nsRect & rect , const nsIntSize & size )
2009-06-30 20:39:22 +00:00
{
2011-07-15 21:46:56 +00:00
# ifdef DEBUG
printf ( " [TabChild] Update Dimensions to (x,y,w,h)= (%ud, %ud, %ud, %ud) and move to (w,h)= (%ud, %ud) \n " , rect . x , rect . y , rect . width , rect . height , size . width , size . height ) ;
# endif
2011-08-09 19:38:26 +00:00
if ( ! mRemoteFrame ) {
return true ;
}
2011-07-15 21:46:56 +00:00
mOuterRect . x = rect . x ;
mOuterRect . y = rect . y ;
mOuterRect . width = rect . width ;
mOuterRect . height = rect . height ;
2009-06-30 20:39:22 +00:00
2010-08-20 23:24:40 +00:00
mWidget - > Resize ( 0 , 0 , size . width , size . height ,
2011-10-17 14:59:28 +00:00
true ) ;
2009-06-30 20:39:22 +00:00
nsCOMPtr < nsIBaseWindow > baseWin = do_QueryInterface ( mWebNav ) ;
2010-08-20 23:24:40 +00:00
baseWin - > SetPositionAndSize ( 0 , 0 , size . width , size . height ,
2011-10-17 14:59:28 +00:00
true ) ;
2011-07-15 21:46:56 +00:00
2009-09-17 23:09:20 +00:00
return true ;
2009-06-30 20:39:22 +00:00
}
2009-10-29 17:58:31 +00:00
2012-08-09 04:39:02 +00:00
void
TabChild : : DispatchMessageManagerMessage ( const nsAString & aMessageName ,
const nsACString & aJSONData )
2012-07-20 06:48:27 +00:00
{
2012-08-02 15:02:06 +00:00
JSAutoRequest ar ( mCx ) ;
2012-08-02 06:02:29 +00:00
jsval json = JSVAL_NULL ;
StructuredCloneData cloneData ;
JSAutoStructuredCloneBuffer buffer ;
if ( JS_ParseJSON ( mCx ,
2012-08-09 04:39:02 +00:00
static_cast < const jschar * > ( NS_ConvertUTF8toUTF16 ( aJSONData ) . get ( ) ) ,
aJSONData . Length ( ) ,
2012-08-02 06:02:29 +00:00
& json ) ) {
WriteStructuredClone ( mCx , json , buffer , cloneData . mClosure ) ;
2012-08-02 15:02:06 +00:00
cloneData . mData = buffer . data ( ) ;
cloneData . mDataLength = buffer . nbytes ( ) ;
2012-08-02 06:02:29 +00:00
}
nsFrameScriptCx cx ( static_cast < nsIWebBrowserChrome * > ( this ) , this ) ;
2012-07-20 06:48:27 +00:00
// Let the BrowserElementScrolling helper (if it exists) for this
// content manipulate the frame state.
2012-08-02 06:02:29 +00:00
nsRefPtr < nsFrameMessageManager > mm =
static_cast < nsFrameMessageManager * > ( mTabChildGlobal - > mMessageManager . get ( ) ) ;
mm - > ReceiveMessage ( static_cast < nsIDOMEventTarget * > ( mTabChildGlobal ) ,
2012-08-09 04:39:02 +00:00
aMessageName , false , & cloneData , nullptr , nullptr ) ;
}
bool
TabChild : : RecvUpdateFrame ( const FrameMetrics & aFrameMetrics )
{
if ( ! mCx | | ! mTabChildGlobal ) {
return true ;
}
nsCString data ;
data + = nsPrintfCString ( " { \" x \" : %d " , aFrameMetrics . mViewportScrollOffset . x ) ;
data + = nsPrintfCString ( " , \" y \" : %d " , aFrameMetrics . mViewportScrollOffset . y ) ;
// We don't treat the x and y scales any differently for this
// semi-platform-specific code.
data + = nsPrintfCString ( " , \" zoom \" : %f " , aFrameMetrics . mResolution . width ) ;
data + = nsPrintfCString ( " , \" displayPort \" : " ) ;
data + = nsPrintfCString ( " { \" left \" : %d " , aFrameMetrics . mDisplayPort . X ( ) ) ;
data + = nsPrintfCString ( " , \" top \" : %d " , aFrameMetrics . mDisplayPort . Y ( ) ) ;
data + = nsPrintfCString ( " , \" width \" : %d " , aFrameMetrics . mDisplayPort . Width ( ) ) ;
data + = nsPrintfCString ( " , \" height \" : %d " , aFrameMetrics . mDisplayPort . Height ( ) ) ;
data + = nsPrintfCString ( " , \" resolution \" : %f " , aFrameMetrics . mResolution . width ) ;
data + = nsPrintfCString ( " } " ) ;
data + = nsPrintfCString ( " , \" screenSize \" : " ) ;
data + = nsPrintfCString ( " { \" width \" : %d " , aFrameMetrics . mViewport . width ) ;
data + = nsPrintfCString ( " , \" height \" : %d " , aFrameMetrics . mViewport . height ) ;
data + = nsPrintfCString ( " } " ) ;
data + = nsPrintfCString ( " , \" cssPageRect \" : " ) ;
data + = nsPrintfCString ( " { \" x \" : %f " , aFrameMetrics . mCSSContentRect . x ) ;
data + = nsPrintfCString ( " , \" y \" : %f " , aFrameMetrics . mCSSContentRect . y ) ;
data + = nsPrintfCString ( " , \" width \" : %f " , aFrameMetrics . mCSSContentRect . width ) ;
data + = nsPrintfCString ( " , \" height \" : %f " , aFrameMetrics . mCSSContentRect . height ) ;
data + = nsPrintfCString ( " } " ) ;
data + = nsPrintfCString ( " } " ) ;
DispatchMessageManagerMessage ( NS_LITERAL_STRING ( " Viewport:Change " ) , data ) ;
return true ;
}
bool
TabChild : : RecvHandleDoubleTap ( const nsIntPoint & aPoint )
{
if ( ! mCx | | ! mTabChildGlobal ) {
return true ;
}
nsCString data ;
data + = nsPrintfCString ( " { \" x \" : %d " , aPoint . x ) ;
data + = nsPrintfCString ( " , \" y \" : %d " , aPoint . y ) ;
data + = nsPrintfCString ( " } " ) ;
DispatchMessageManagerMessage ( NS_LITERAL_STRING ( " Gesture:DoubleTap " ) , data ) ;
2012-08-02 06:02:29 +00:00
return true ;
2012-07-20 06:48:27 +00:00
}
2009-11-05 18:14:22 +00:00
bool
2010-07-19 18:33:33 +00:00
TabChild : : RecvActivate ( )
2009-11-05 18:14:22 +00:00
{
nsCOMPtr < nsIWebBrowserFocus > browser = do_QueryInterface ( mWebNav ) ;
browser - > Activate ( ) ;
return true ;
}
2011-06-18 00:08:32 +00:00
bool TabChild : : RecvDeactivate ( )
{
nsCOMPtr < nsIWebBrowserFocus > browser = do_QueryInterface ( mWebNav ) ;
browser - > Deactivate ( ) ;
return true ;
}
2009-11-05 18:21:09 +00:00
bool
2010-07-19 18:33:33 +00:00
TabChild : : RecvMouseEvent ( const nsString & aType ,
const float & aX ,
const float & aY ,
const PRInt32 & aButton ,
const PRInt32 & aClickCount ,
const PRInt32 & aModifiers ,
const bool & aIgnoreRootScrollFrame )
2009-11-05 18:21:09 +00:00
{
nsCOMPtr < nsPIDOMWindow > window = do_GetInterface ( mWebNav ) ;
nsCOMPtr < nsIDOMWindowUtils > utils = do_GetInterface ( window ) ;
NS_ENSURE_TRUE ( utils , true ) ;
utils - > SendMouseEvent ( aType , aX , aY , aButton , aClickCount , aModifiers ,
aIgnoreRootScrollFrame ) ;
return true ;
}
2011-06-22 00:32:43 +00:00
bool
TabChild : : RecvRealMouseEvent ( const nsMouseEvent & event )
{
nsMouseEvent localEvent ( event ) ;
DispatchWidgetEvent ( localEvent ) ;
return true ;
}
bool
2012-08-12 01:42:34 +00:00
TabChild : : RecvMouseWheelEvent ( const WheelEvent & event )
2011-06-22 00:32:43 +00:00
{
2012-08-12 01:42:34 +00:00
WheelEvent localEvent ( event ) ;
2011-06-22 00:32:43 +00:00
DispatchWidgetEvent ( localEvent ) ;
return true ;
}
2012-07-16 02:58:43 +00:00
bool
TabChild : : RecvRealTouchEvent ( const nsTouchEvent & aEvent )
{
nsTouchEvent localEvent ( aEvent ) ;
nsEventStatus status = DispatchWidgetEvent ( localEvent ) ;
if ( status = = nsEventStatus_eConsumeNoDefault ) {
return true ;
}
// Synthesize a phony mouse event.
PRUint32 msg ;
switch ( aEvent . message ) {
case NS_TOUCH_START :
msg = NS_MOUSE_BUTTON_DOWN ;
break ;
case NS_TOUCH_MOVE :
msg = NS_MOUSE_MOVE ;
break ;
case NS_TOUCH_END :
case NS_TOUCH_CANCEL :
msg = NS_MOUSE_BUTTON_UP ;
break ;
default :
MOZ_NOT_REACHED ( " Unknown touch event message " ) ;
}
nsIntPoint refPoint ( 0 , 0 ) ;
if ( aEvent . touches . Length ( ) ) {
refPoint = aEvent . touches [ 0 ] - > mRefPoint ;
}
nsMouseEvent event ( true , msg , NULL ,
nsMouseEvent : : eReal , nsMouseEvent : : eNormal ) ;
event . refPoint = refPoint ;
event . time = aEvent . time ;
event . button = nsMouseEvent : : eLeftButton ;
if ( msg ! = NS_MOUSE_MOVE ) {
event . clickCount = 1 ;
}
DispatchWidgetEvent ( event ) ;
return true ;
}
2011-06-22 00:32:43 +00:00
bool
TabChild : : RecvRealKeyEvent ( const nsKeyEvent & event )
{
nsKeyEvent localEvent ( event ) ;
DispatchWidgetEvent ( localEvent ) ;
return true ;
}
2010-03-19 06:52:18 +00:00
bool
2010-07-19 18:33:33 +00:00
TabChild : : RecvKeyEvent ( const nsString & aType ,
const PRInt32 & aKeyCode ,
const PRInt32 & aCharCode ,
const PRInt32 & aModifiers ,
const bool & aPreventDefault )
2010-03-19 06:52:18 +00:00
{
nsCOMPtr < nsPIDOMWindow > window = do_GetInterface ( mWebNav ) ;
nsCOMPtr < nsIDOMWindowUtils > utils = do_GetInterface ( window ) ;
NS_ENSURE_TRUE ( utils , true ) ;
2011-09-29 06:19:26 +00:00
bool ignored = false ;
2010-03-19 06:52:18 +00:00
utils - > SendKeyEvent ( aType , aKeyCode , aCharCode ,
aModifiers , aPreventDefault , & ignored ) ;
return true ;
}
2010-08-17 08:07:42 +00:00
bool
TabChild : : RecvCompositionEvent ( const nsCompositionEvent & event )
{
nsCompositionEvent localEvent ( event ) ;
DispatchWidgetEvent ( localEvent ) ;
return true ;
}
bool
TabChild : : RecvTextEvent ( const nsTextEvent & event )
{
nsTextEvent localEvent ( event ) ;
DispatchWidgetEvent ( localEvent ) ;
IPC : : ParamTraits < nsTextEvent > : : Free ( event ) ;
return true ;
}
bool
TabChild : : RecvSelectionEvent ( const nsSelectionEvent & event )
{
nsSelectionEvent localEvent ( event ) ;
DispatchWidgetEvent ( localEvent ) ;
return true ;
}
2012-07-16 02:58:43 +00:00
nsEventStatus
2010-08-17 08:07:42 +00:00
TabChild : : DispatchWidgetEvent ( nsGUIEvent & event )
{
2010-09-24 03:28:15 +00:00
if ( ! mWidget )
2012-07-16 02:58:43 +00:00
return nsEventStatus_eConsumeNoDefault ;
2010-08-17 08:07:42 +00:00
nsEventStatus status ;
2010-09-24 03:28:15 +00:00
event . widget = mWidget ;
2012-07-16 02:58:43 +00:00
NS_ENSURE_SUCCESS ( mWidget - > DispatchEvent ( & event , status ) ,
nsEventStatus_eConsumeNoDefault ) ;
return status ;
2010-08-17 08:07:42 +00:00
}
2010-10-26 22:20:53 +00:00
PDocumentRendererChild *
TabChild : : AllocPDocumentRenderer ( const nsRect & documentRect ,
2010-10-26 22:20:53 +00:00
const gfxMatrix & transform ,
2010-08-17 08:07:42 +00:00
const nsString & bgcolor ,
2010-10-26 22:20:53 +00:00
const PRUint32 & renderFlags ,
2010-10-26 22:20:53 +00:00
const bool & flushLayout ,
const nsIntSize & renderSize )
2009-10-29 17:58:31 +00:00
{
2010-10-26 22:20:53 +00:00
return new DocumentRendererChild ( ) ;
2009-10-29 17:58:31 +00:00
}
bool
2009-12-03 08:16:14 +00:00
TabChild : : DeallocPDocumentRenderer ( PDocumentRendererChild * actor )
2009-10-29 17:58:31 +00:00
{
2009-12-03 08:16:14 +00:00
delete actor ;
2009-10-29 17:58:31 +00:00
return true ;
}
bool
2010-10-26 22:20:53 +00:00
TabChild : : RecvPDocumentRendererConstructor ( PDocumentRendererChild * actor ,
const nsRect & documentRect ,
2010-10-26 22:20:53 +00:00
const gfxMatrix & transform ,
2010-10-26 22:20:53 +00:00
const nsString & bgcolor ,
const PRUint32 & renderFlags ,
2010-10-26 22:20:53 +00:00
const bool & flushLayout ,
const nsIntSize & renderSize )
2010-10-26 22:20:53 +00:00
{
DocumentRendererChild * render = static_cast < DocumentRendererChild * > ( actor ) ;
2009-10-29 17:58:31 +00:00
nsCOMPtr < nsIWebBrowser > browser = do_QueryInterface ( mWebNav ) ;
if ( ! browser )
return true ; // silently ignore
nsCOMPtr < nsIDOMWindow > window ;
if ( NS_FAILED ( browser - > GetContentDOMWindow ( getter_AddRefs ( window ) ) ) | |
! window )
{
return true ; // silently ignore
}
nsCString data ;
2010-10-26 22:20:53 +00:00
bool ret = render - > RenderDocument ( window ,
2010-10-26 22:20:53 +00:00
documentRect , transform ,
bgcolor ,
2010-10-26 22:20:53 +00:00
renderFlags , flushLayout ,
2010-10-26 22:20:53 +00:00
renderSize , data ) ;
2009-10-29 17:58:31 +00:00
if ( ! ret )
return true ; // silently ignore
2010-10-26 22:20:53 +00:00
return PDocumentRendererChild : : Send__delete__ ( actor , renderSize , data ) ;
2009-10-29 17:58:31 +00:00
}
2009-11-17 14:22:23 +00:00
2010-05-17 11:25:22 +00:00
PContentDialogChild *
TabChild : : AllocPContentDialog ( const PRUint32 & ,
const nsCString & ,
const nsCString & ,
2010-11-09 02:49:00 +00:00
const InfallibleTArray < int > & ,
const InfallibleTArray < nsString > & )
2010-05-17 11:25:22 +00:00
{
return new ContentDialogChild ( ) ;
}
bool
TabChild : : DeallocPContentDialog ( PContentDialogChild * aDialog )
{
delete aDialog ;
return true ;
}
2010-09-10 05:00:08 +00:00
PContentPermissionRequestChild *
2012-07-30 14:58:26 +00:00
TabChild : : AllocPContentPermissionRequest ( const nsCString & aType , const IPC : : Principal & )
2010-05-13 17:44:51 +00:00
{
NS_RUNTIMEABORT ( " unused " ) ;
2012-07-30 14:20:58 +00:00
return nullptr ;
2010-05-13 17:44:51 +00:00
}
bool
2010-09-10 05:00:08 +00:00
TabChild : : DeallocPContentPermissionRequest ( PContentPermissionRequestChild * actor )
2010-05-13 17:44:51 +00:00
{
2012-07-18 19:09:28 +00:00
PCOMContentPermissionRequestChild * child =
static_cast < PCOMContentPermissionRequestChild * > ( actor ) ;
# ifdef DEBUG
child - > mIPCOpen = false ;
# endif /* DEBUG */
child - > IPDLRelease ( ) ;
2010-09-10 05:00:08 +00:00
return true ;
2010-05-13 17:44:51 +00:00
}
2009-11-17 14:22:23 +00:00
bool
2010-07-19 18:33:33 +00:00
TabChild : : RecvActivateFrameEvent ( const nsString & aType , const bool & capture )
2009-11-17 14:22:23 +00:00
{
nsCOMPtr < nsPIDOMWindow > window = do_GetInterface ( mWebNav ) ;
NS_ENSURE_TRUE ( window , true ) ;
nsCOMPtr < nsIDOMEventTarget > chromeHandler =
do_QueryInterface ( window - > GetChromeEventHandler ( ) ) ;
NS_ENSURE_TRUE ( chromeHandler , true ) ;
nsRefPtr < ContentListener > listener = new ContentListener ( this ) ;
NS_ENSURE_TRUE ( listener , true ) ;
chromeHandler - > AddEventListener ( aType , listener , capture ) ;
return true ;
}
2010-02-20 17:05:20 +00:00
2010-10-20 17:12:32 +00:00
POfflineCacheUpdateChild *
TabChild : : AllocPOfflineCacheUpdate ( const URI & manifestURI ,
const URI & documentURI ,
const nsCString & clientID ,
const bool & stickDocument )
{
NS_RUNTIMEABORT ( " unused " ) ;
2012-07-30 14:20:58 +00:00
return nullptr ;
2010-10-20 17:12:32 +00:00
}
bool
TabChild : : DeallocPOfflineCacheUpdate ( POfflineCacheUpdateChild * actor )
{
OfflineCacheUpdateChild * offlineCacheUpdate = static_cast < OfflineCacheUpdateChild * > ( actor ) ;
delete offlineCacheUpdate ;
return true ;
}
2010-02-20 17:05:20 +00:00
bool
2010-07-19 18:33:33 +00:00
TabChild : : RecvLoadRemoteScript ( const nsString & aURL )
2010-02-20 17:05:20 +00:00
{
2010-08-24 17:01:28 +00:00
if ( ! mCx & & ! InitTabChildGlobal ( ) )
2011-08-09 19:38:26 +00:00
// This can happen if we're half-destroyed. It's not a fatal
// error.
return true ;
2010-08-24 17:01:28 +00:00
2010-08-18 10:02:49 +00:00
LoadFrameScriptInternal ( aURL ) ;
2010-02-20 17:05:20 +00:00
return true ;
}
bool
2010-07-19 18:33:33 +00:00
TabChild : : RecvAsyncMessage ( const nsString & aMessage ,
2012-08-02 06:02:29 +00:00
const ClonedMessageData & aData )
2010-02-20 17:05:20 +00:00
{
if ( mTabChildGlobal ) {
2011-06-16 18:21:08 +00:00
nsFrameScriptCx cx ( static_cast < nsIWebBrowserChrome * > ( this ) , this ) ;
2012-08-02 06:02:29 +00:00
const SerializedStructuredCloneBuffer & buffer = aData . data ( ) ;
const InfallibleTArray < PBlobChild * > & blobChildList = aData . blobsChild ( ) ;
StructuredCloneData cloneData ;
cloneData . mData = buffer . data ;
cloneData . mDataLength = buffer . dataLength ;
if ( ! blobChildList . IsEmpty ( ) ) {
PRUint32 length = blobChildList . Length ( ) ;
cloneData . mClosure . mBlobs . SetCapacity ( length ) ;
for ( PRUint32 i = 0 ; i < length ; + + i ) {
BlobChild * blobChild = static_cast < BlobChild * > ( blobChildList [ i ] ) ;
MOZ_ASSERT ( blobChild ) ;
nsCOMPtr < nsIDOMBlob > blob = blobChild - > GetBlob ( ) ;
MOZ_ASSERT ( blob ) ;
cloneData . mClosure . mBlobs . AppendElement ( blob ) ;
}
}
2011-06-16 18:21:08 +00:00
nsRefPtr < nsFrameMessageManager > mm =
static_cast < nsFrameMessageManager * > ( mTabChildGlobal - > mMessageManager . get ( ) ) ;
2011-06-24 02:18:00 +00:00
mm - > ReceiveMessage ( static_cast < nsIDOMEventTarget * > ( mTabChildGlobal ) ,
2012-08-02 06:02:29 +00:00
aMessage , false , & cloneData , nullptr , nullptr ) ;
2010-02-20 17:05:20 +00:00
}
return true ;
}
2010-08-12 16:47:22 +00:00
class UnloadScriptEvent : public nsRunnable
{
public :
UnloadScriptEvent ( TabChild * aTabChild , TabChildGlobal * aTabChildGlobal )
: mTabChild ( aTabChild ) , mTabChildGlobal ( aTabChildGlobal )
{ }
NS_IMETHOD Run ( )
{
nsCOMPtr < nsIDOMEvent > event ;
2012-07-30 14:20:58 +00:00
NS_NewDOMEvent ( getter_AddRefs ( event ) , nullptr , nullptr ) ;
2010-08-12 16:47:22 +00:00
if ( event ) {
2011-10-17 14:59:28 +00:00
event - > InitEvent ( NS_LITERAL_STRING ( " unload " ) , false , false ) ;
2012-06-10 23:44:50 +00:00
event - > SetTrusted ( true ) ;
2010-08-12 16:47:22 +00:00
2011-09-29 06:19:26 +00:00
bool dummy ;
2010-08-12 16:47:22 +00:00
mTabChildGlobal - > DispatchEvent ( event , & dummy ) ;
}
return NS_OK ;
}
nsRefPtr < TabChild > mTabChild ;
TabChildGlobal * mTabChildGlobal ;
} ;
2010-08-05 22:11:23 +00:00
bool
TabChild : : RecvDestroy ( )
{
2011-08-09 19:38:26 +00:00
if ( mTabChildGlobal ) {
// Let the frame scripts know the child is being closed
nsContentUtils : : AddScriptRunner (
new UnloadScriptEvent ( this , mTabChildGlobal )
) ;
}
2010-08-05 22:11:23 +00:00
2010-08-12 16:47:22 +00:00
// XXX what other code in ~TabChild() should we be running here?
2010-08-20 23:24:40 +00:00
DestroyWindow ( ) ;
2010-08-05 22:11:23 +00:00
2010-08-12 16:47:22 +00:00
return Send__delete__ ( this ) ;
2010-08-05 22:11:23 +00:00
}
2010-02-20 17:05:20 +00:00
2010-08-20 23:24:41 +00:00
PRenderFrameChild *
2012-07-20 06:48:27 +00:00
TabChild : : AllocPRenderFrame ( ScrollingBehavior * aScrolling ,
LayersBackend * aBackend ,
2012-07-17 23:59:45 +00:00
int32_t * aMaxTextureSize ,
uint64_t * aLayersId )
2010-08-20 23:24:41 +00:00
{
return new RenderFrameChild ( ) ;
}
bool
TabChild : : DeallocPRenderFrame ( PRenderFrameChild * aFrame )
{
delete aFrame ;
return true ;
}
2010-02-20 17:05:20 +00:00
bool
TabChild : : InitTabChildGlobal ( )
{
2010-08-24 17:01:28 +00:00
if ( mCx & & mTabChildGlobal )
return true ;
2010-02-20 17:05:20 +00:00
nsCOMPtr < nsPIDOMWindow > window = do_GetInterface ( mWebNav ) ;
NS_ENSURE_TRUE ( window , false ) ;
nsCOMPtr < nsIDOMEventTarget > chromeHandler =
do_QueryInterface ( window - > GetChromeEventHandler ( ) ) ;
NS_ENSURE_TRUE ( chromeHandler , false ) ;
nsRefPtr < TabChildGlobal > scope = new TabChildGlobal ( this ) ;
NS_ENSURE_TRUE ( scope , false ) ;
mTabChildGlobal = scope ;
nsISupports * scopeSupports =
2011-06-24 02:18:00 +00:00
NS_ISUPPORTS_CAST ( nsIDOMEventTarget * , scope ) ;
2011-11-30 15:51:40 +00:00
NS_ENSURE_TRUE ( InitTabChildGlobalInternal ( scopeSupports ) , false ) ;
2010-02-20 17:05:20 +00:00
2012-04-26 20:56:46 +00:00
scope - > Init ( ) ;
2010-02-20 17:05:20 +00:00
nsCOMPtr < nsPIWindowRoot > root = do_QueryInterface ( chromeHandler ) ;
NS_ENSURE_TRUE ( root , false ) ;
root - > SetParentTarget ( scope ) ;
2012-06-22 01:17:52 +00:00
// Initialize the child side of the browser element machinery, if appropriate.
2012-07-22 00:16:11 +00:00
if ( mIsBrowserElement | | mAppId ! = nsIScriptSecurityManager : : NO_APP_ID ) {
2012-06-22 01:17:52 +00:00
RecvLoadRemoteScript (
NS_LITERAL_STRING ( " chrome://global/content/BrowserElementChild.js " ) ) ;
}
2010-02-20 17:05:20 +00:00
return true ;
}
2010-08-20 23:24:41 +00:00
bool
TabChild : : InitWidget ( const nsIntSize & size )
{
NS_ABORT_IF_FALSE ( ! mWidget & & ! mRemoteFrame , " CreateWidget twice? " ) ;
2010-09-24 03:28:15 +00:00
mWidget = nsIWidget : : CreatePuppetWidget ( this ) ;
2010-08-20 23:24:41 +00:00
if ( ! mWidget ) {
NS_ERROR ( " couldn't create fake widget " ) ;
return false ;
}
mWidget - > Create (
2012-07-30 14:20:58 +00:00
nullptr , 0 , // no parents
2010-08-20 23:24:41 +00:00
nsIntRect ( nsIntPoint ( 0 , 0 ) , size ) ,
2012-07-30 14:20:58 +00:00
nullptr , // HandleWidgetEvent
nullptr // nsDeviceContext
2010-08-20 23:24:41 +00:00
) ;
2012-07-18 16:31:40 +00:00
LayersBackend be ;
2012-07-17 23:59:45 +00:00
uint64_t id ;
int32_t maxTextureSize ;
2010-08-20 23:24:41 +00:00
RenderFrameChild * remoteFrame =
2012-07-17 23:59:45 +00:00
static_cast < RenderFrameChild * > ( SendPRenderFrameConstructor (
2012-07-20 06:48:27 +00:00
& mScrolling , & be , & maxTextureSize , & id ) ) ;
2010-08-20 23:24:41 +00:00
if ( ! remoteFrame ) {
NS_WARNING ( " failed to construct RenderFrame " ) ;
return false ;
}
2012-07-30 14:20:58 +00:00
PLayersChild * shadowManager = nullptr ;
2012-07-17 23:59:45 +00:00
if ( id ! = 0 ) {
// Pushing layers transactions directly to a separate
// compositor context.
shadowManager =
CompositorChild : : Get ( ) - > SendPLayersConstructor ( be , id ,
& be ,
& maxTextureSize ) ;
} else {
// Pushing transactions to the parent content.
shadowManager = remoteFrame - > SendPLayersConstructor ( ) ;
}
2010-08-20 23:24:41 +00:00
if ( ! shadowManager ) {
NS_WARNING ( " failed to construct LayersChild " ) ;
// This results in |remoteFrame| being deleted.
PRenderFrameChild : : Send__delete__ ( remoteFrame ) ;
return false ;
}
2011-08-09 19:38:26 +00:00
ShadowLayerForwarder * lf =
mWidget - > GetLayerManager ( shadowManager , be ) - > AsShadowForwarder ( ) ;
NS_ABORT_IF_FALSE ( lf & & lf - > HasShadowManager ( ) ,
" PuppetWidget should have shadow manager " ) ;
lf - > SetParentBackendType ( be ) ;
2012-05-22 23:15:16 +00:00
lf - > SetMaxTextureSize ( maxTextureSize ) ;
2010-08-20 23:24:41 +00:00
mRemoteFrame = remoteFrame ;
return true ;
}
2011-10-20 22:17:09 +00:00
void
TabChild : : SetBackgroundColor ( const nscolor & aColor )
{
if ( mLastBackgroundColor ! = aColor ) {
mLastBackgroundColor = aColor ;
SendSetBackgroundColor ( mLastBackgroundColor ) ;
}
}
2012-07-17 23:59:45 +00:00
void
TabChild : : NotifyPainted ( )
{
if ( UseDirectCompositor ( ) ) {
// FIXME/bug XXXXXX: in theory, we should only have to push a
// txn to our remote frame once, and the
// display-list/FrameLayerBuilder code there will manage the
// tree from there on. But in practice, that doesn't work for
// some unknown reason. So for now, always notify the content
// thread in the parent process. It's wasteful but won't
// result in unnecessary repainting or even composites
// (usually, unless timing is unlucky), since they're
// throttled.
mRemoteFrame - > SendNotifyCompositorTransaction ( ) ;
}
}
2012-07-20 06:48:27 +00:00
bool
TabChild : : IsAsyncPanZoomEnabled ( )
{
return mScrolling = = ASYNC_PAN_ZOOM ;
}
2012-05-28 09:27:25 +00:00
NS_IMETHODIMP
TabChild : : GetMessageManager ( nsIContentFrameMessageManager * * aResult )
{
if ( mTabChildGlobal ) {
NS_ADDREF ( * aResult = mTabChildGlobal ) ;
return NS_OK ;
}
2012-07-30 14:20:58 +00:00
* aResult = nullptr ;
2012-05-28 09:27:25 +00:00
return NS_ERROR_FAILURE ;
}
2012-06-01 17:21:12 +00:00
PIndexedDBChild *
TabChild : : AllocPIndexedDB ( const nsCString & aASCIIOrigin , bool * /* aAllowed */ )
{
NS_NOTREACHED ( " Should never get here! " ) ;
return NULL ;
}
bool
TabChild : : DeallocPIndexedDB ( PIndexedDBChild * aActor )
{
delete aActor ;
return true ;
}
2010-07-19 18:33:33 +00:00
static bool
SendSyncMessageToParent ( void * aCallbackData ,
const nsAString & aMessage ,
2012-08-02 06:02:29 +00:00
const StructuredCloneData & aData ,
2010-11-09 02:49:00 +00:00
InfallibleTArray < nsString > * aJSONRetVal )
2010-02-20 17:05:20 +00:00
{
2012-08-02 06:02:29 +00:00
TabChild * tabChild = static_cast < TabChild * > ( aCallbackData ) ;
ContentChild * cc = static_cast < ContentChild * > ( tabChild - > Manager ( ) ) ;
ClonedMessageData data ;
SerializedStructuredCloneBuffer & buffer = data . data ( ) ;
buffer . data = aData . mData ;
buffer . dataLength = aData . mDataLength ;
const nsTArray < nsCOMPtr < nsIDOMBlob > > & blobs = aData . mClosure . mBlobs ;
if ( ! blobs . IsEmpty ( ) ) {
InfallibleTArray < PBlobChild * > & blobChildList = data . blobsChild ( ) ;
PRUint32 length = blobs . Length ( ) ;
blobChildList . SetCapacity ( length ) ;
for ( PRUint32 i = 0 ; i < length ; + + i ) {
BlobChild * blobChild = cc - > GetOrCreateActorForBlob ( blobs [ i ] ) ;
if ( ! blobChild ) {
return false ;
}
blobChildList . AppendElement ( blobChild ) ;
}
}
return tabChild - > SendSyncMessage ( nsString ( aMessage ) , data , aJSONRetVal ) ;
2010-02-20 17:05:20 +00:00
}
2010-07-19 18:33:33 +00:00
static bool
SendAsyncMessageToParent ( void * aCallbackData ,
const nsAString & aMessage ,
2012-08-02 06:02:29 +00:00
const StructuredCloneData & aData )
{
TabChild * tabChild = static_cast < TabChild * > ( aCallbackData ) ;
ContentChild * cc = static_cast < ContentChild * > ( tabChild - > Manager ( ) ) ;
ClonedMessageData data ;
SerializedStructuredCloneBuffer & buffer = data . data ( ) ;
buffer . data = aData . mData ;
buffer . dataLength = aData . mDataLength ;
const nsTArray < nsCOMPtr < nsIDOMBlob > > & blobs = aData . mClosure . mBlobs ;
if ( ! blobs . IsEmpty ( ) ) {
InfallibleTArray < PBlobChild * > & blobChildList = data . blobsChild ( ) ;
PRUint32 length = blobs . Length ( ) ;
blobChildList . SetCapacity ( length ) ;
for ( PRUint32 i = 0 ; i < length ; + + i ) {
BlobChild * blobChild = cc - > GetOrCreateActorForBlob ( blobs [ i ] ) ;
if ( ! blobChild ) {
return false ;
}
blobChildList . AppendElement ( blobChild ) ;
}
}
return tabChild - > SendAsyncMessage ( nsString ( aMessage ) , data ) ;
2010-02-20 17:05:20 +00:00
}
2012-08-02 06:02:29 +00:00
2010-02-20 17:05:20 +00:00
TabChildGlobal : : TabChildGlobal ( TabChild * aTabChild )
: mTabChild ( aTabChild )
{
2012-04-26 20:56:46 +00:00
}
void
TabChildGlobal : : Init ( )
{
NS_ASSERTION ( ! mMessageManager , " Re-initializing?!? " ) ;
2011-10-17 14:59:28 +00:00
mMessageManager = new nsFrameMessageManager ( false ,
2010-02-20 17:05:20 +00:00
SendSyncMessageToParent ,
SendAsyncMessageToParent ,
2012-07-30 14:20:58 +00:00
nullptr ,
2010-02-20 17:05:20 +00:00
mTabChild ,
2012-07-30 14:20:58 +00:00
nullptr ,
2012-04-26 20:56:46 +00:00
mTabChild - > GetJSContext ( ) ) ;
2010-02-20 17:05:20 +00:00
}
NS_IMPL_CYCLE_COLLECTION_CLASS ( TabChildGlobal )
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED ( TabChildGlobal ,
2012-02-08 02:53:33 +00:00
nsDOMEventTargetHelper )
2010-02-20 17:05:20 +00:00
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR ( mMessageManager )
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED ( TabChildGlobal ,
2012-02-08 02:53:33 +00:00
nsDOMEventTargetHelper )
2010-02-20 17:05:20 +00:00
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR ( mMessageManager )
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED ( TabChildGlobal )
NS_INTERFACE_MAP_ENTRY ( nsIFrameMessageManager )
2010-08-31 18:58:35 +00:00
NS_INTERFACE_MAP_ENTRY ( nsISyncMessageSender )
2010-02-20 17:05:20 +00:00
NS_INTERFACE_MAP_ENTRY ( nsIContentFrameMessageManager )
NS_INTERFACE_MAP_ENTRY ( nsIScriptContextPrincipal )
NS_INTERFACE_MAP_ENTRY ( nsIScriptObjectPrincipal )
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO ( ContentFrameMessageManager )
2012-02-08 02:53:33 +00:00
NS_INTERFACE_MAP_END_INHERITING ( nsDOMEventTargetHelper )
2010-02-20 17:05:20 +00:00
NS_IMPL_ADDREF_INHERITED ( TabChildGlobal , nsDOMEventTargetHelper )
NS_IMPL_RELEASE_INHERITED ( TabChildGlobal , nsDOMEventTargetHelper )
NS_IMETHODIMP
TabChildGlobal : : GetContent ( nsIDOMWindow * * aContent )
{
2012-07-30 14:20:58 +00:00
* aContent = nullptr ;
2010-07-21 23:23:03 +00:00
if ( ! mTabChild )
return NS_ERROR_NULL_POINTER ;
2010-02-20 17:05:20 +00:00
nsCOMPtr < nsIDOMWindow > window = do_GetInterface ( mTabChild - > WebNavigation ( ) ) ;
window . swap ( * aContent ) ;
return NS_OK ;
}
2010-11-24 13:58:21 +00:00
NS_IMETHODIMP
TabChildGlobal : : PrivateNoteIntentionalCrash ( )
{
mozilla : : NoteIntentionalCrash ( " tab " ) ;
return NS_OK ;
}
2010-03-03 20:30:25 +00:00
NS_IMETHODIMP
TabChildGlobal : : GetDocShell ( nsIDocShell * * aDocShell )
{
2012-07-30 14:20:58 +00:00
* aDocShell = nullptr ;
2010-05-12 09:52:15 +00:00
if ( ! mTabChild )
return NS_ERROR_NULL_POINTER ;
2010-03-03 20:30:25 +00:00
nsCOMPtr < nsIDocShell > docShell = do_GetInterface ( mTabChild - > WebNavigation ( ) ) ;
docShell . swap ( * aDocShell ) ;
return NS_OK ;
}
2011-06-25 09:52:00 +00:00
NS_IMETHODIMP
TabChildGlobal : : Btoa ( const nsAString & aBinaryData ,
nsAString & aAsciiBase64String )
{
return nsContentUtils : : Btoa ( aBinaryData , aAsciiBase64String ) ;
}
NS_IMETHODIMP
TabChildGlobal : : Atob ( const nsAString & aAsciiString ,
nsAString & aBinaryData )
{
return nsContentUtils : : Atob ( aAsciiString , aBinaryData ) ;
}
2010-02-20 17:05:20 +00:00
JSContext *
TabChildGlobal : : GetJSContextForEventHandlers ( )
{
2010-05-12 09:52:15 +00:00
if ( ! mTabChild )
2012-07-30 14:20:58 +00:00
return nullptr ;
2010-02-20 17:05:20 +00:00
return mTabChild - > GetJSContext ( ) ;
}
nsIPrincipal *
TabChildGlobal : : GetPrincipal ( )
{
2010-05-12 09:52:15 +00:00
if ( ! mTabChild )
2012-07-30 14:20:58 +00:00
return nullptr ;
2010-02-20 17:05:20 +00:00
return mTabChild - > GetPrincipal ( ) ;
2012-06-01 17:21:12 +00:00
}