/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */ /* vim: set sw=2 sts=2 ts=8 et tw=80 : */ /* 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/. */ #include "base/basictypes.h" #include "TabChild.h" #include "BasicLayers.h" #include "Blob.h" #include "ContentChild.h" #include "IndexedDBChild.h" #include "mozilla/IntentionalCrash.h" #include "mozilla/docshell/OfflineCacheUpdateChild.h" #include "mozilla/dom/PContentChild.h" #include "mozilla/dom/PContentDialogChild.h" #include "mozilla/ipc/DocumentRendererChild.h" #include "mozilla/layers/CompositorChild.h" #include "mozilla/layers/PLayersChild.h" #include "mozilla/layout/RenderFrameChild.h" #include "mozilla/unused.h" #include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h" #include "nsContentUtils.h" #include "nsEmbedCID.h" #include "nsEventListenerManager.h" #include "nsIBaseWindow.h" #include "nsIComponentManager.h" #include "nsIDOMClassInfo.h" #include "nsIDOMEvent.h" #include "nsIDOMWindow.h" #include "nsIDOMWindowUtils.h" #include "nsIDocShell.h" #include "nsIDocShellTreeItem.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIJSContextStack.h" #include "nsIJSRuntimeService.h" #include "nsISSLStatusProvider.h" #include "nsIScriptContext.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptSecurityManager.h" #include "nsISecureBrowserUI.h" #include "nsIServiceManager.h" #include "nsISupportsImpl.h" #include "nsIURI.h" #include "nsIView.h" #include "nsIWebBrowser.h" #include "nsIWebBrowserFocus.h" #include "nsIWebBrowserSetup.h" #include "nsIWebProgress.h" #include "nsIXPCSecurityManager.h" #include "nsInterfaceHashtable.h" #include "nsPIDOMWindow.h" #include "nsPIWindowRoot.h" #include "nsPresContext.h" #include "nsPrintfCString.h" #include "nsScriptLoader.h" #include "nsSerializationHelper.h" #include "nsThreadUtils.h" #include "nsWeakReference.h" #include "PCOMContentPermissionRequestChild.h" #include "StructuredCloneUtils.h" #include "xpcpublic.h" using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::ipc; using namespace mozilla::layers; using namespace mozilla::layout; using namespace mozilla::docshell; using namespace mozilla::dom::indexedDB; using namespace mozilla::widget; NS_IMPL_ISUPPORTS1(ContentListener, nsIDOMEventListener) NS_IMETHODIMP ContentListener::HandleEvent(nsIDOMEvent* aEvent) { RemoteDOMEvent remoteEvent; remoteEvent.mEvent = do_QueryInterface(aEvent); NS_ENSURE_STATE(remoteEvent.mEvent); mTabChild->SendEvent(remoteEvent); return NS_OK; } class ContentDialogChild : public PContentDialogChild { public: virtual bool Recv__delete__(const InfallibleTArray& aIntParams, const InfallibleTArray& aStringParams); }; TabChild::TabChild(PRUint32 aChromeFlags, bool aIsBrowserElement, PRUint32 aAppId) : mRemoteFrame(nullptr) , mTabChildGlobal(nullptr) , mChromeFlags(aChromeFlags) , mOuterRect(0, 0, 0, 0) , mLastBackgroundColor(NS_RGB(255, 255, 255)) , mDidFakeShow(false) , mIsBrowserElement(aIsBrowserElement) , mAppId(aAppId) { printf("creating %d!\n", NS_IsMainThread()); } nsresult TabChild::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) { if (!strcmp(aTopic, "dom-touch-listener-added")) { nsCOMPtr subject(do_QueryInterface(aSubject)); nsCOMPtr win(do_GetInterface(mWebNav)); nsCOMPtr topSubject; subject->GetTop(getter_AddRefs(topSubject)); if (win == topSubject) { SendNotifyDOMTouchListenerAdded(); } } else if (!strcmp(aTopic, "cancel-default-pan-zoom")) { nsCOMPtr docShell(do_QueryInterface(aSubject)); nsCOMPtr tabChild(GetTabChildFrom(docShell)); if (tabChild == this) { mRemoteFrame->CancelDefaultPanZoom(); } } else if (!strcmp(aTopic, "browser-zoom-to-rect")) { nsCOMPtr docShell(do_QueryInterface(aSubject)); nsCOMPtr 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); } } return NS_OK; } nsresult TabChild::Init() { nsCOMPtr 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 docShellItem(do_QueryInterface(mWebNav)); docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper); nsCOMPtr observerService = do_GetService(NS_OBSERVERSERVICE_CONTRACTID); if (observerService) { observerService->AddObserver(this, "dom-touch-listener-added", false); observerService->AddObserver(this, "cancel-default-pan-zoom", false); observerService->AddObserver(this, "browser-zoom-to-rect", false); } return NS_OK; } NS_INTERFACE_MAP_BEGIN(TabChild) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome) 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) NS_INTERFACE_MAP_ENTRY(nsSupportsWeakReference) NS_INTERFACE_MAP_END NS_IMPL_ADDREF(TabChild) NS_IMPL_RELEASE(TabChild) NS_IMETHODIMP TabChild::SetStatus(PRUint32 aStatusType, const PRUnichar* aStatus) { // FIXME/bug 617804: should the platform support this? return NS_OK; } NS_IMETHODIMP TabChild::GetWebBrowser(nsIWebBrowser** aWebBrowser) { NS_NOTREACHED("TabChild::GetWebBrowser not supported in TabChild"); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::SetWebBrowser(nsIWebBrowser* aWebBrowser) { NS_NOTREACHED("TabChild::SetWebBrowser not supported in TabChild"); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::GetChromeFlags(PRUint32* aChromeFlags) { *aChromeFlags = mChromeFlags; return NS_OK; } NS_IMETHODIMP TabChild::SetChromeFlags(PRUint32 aChromeFlags) { NS_NOTREACHED("trying to SetChromeFlags from content process?"); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::DestroyBrowserWindow() { NS_NOTREACHED("TabChild::SetWebBrowser not supported in TabChild"); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY) { NS_NOTREACHED("TabChild::SizeBrowserTo not supported in TabChild"); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::ShowAsModal() { NS_NOTREACHED("TabChild::ShowAsModal not supported in TabChild"); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::IsWindowModal(bool* aRetVal) { *aRetVal = false; return NS_OK; } NS_IMETHODIMP TabChild::ExitModalEventLoop(nsresult aStatus) { NS_NOTREACHED("TabChild::ExitModalEventLoop not supported in TabChild"); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::SetStatusWithContext(PRUint32 aStatusType, const nsAString& aStatusText, nsISupports* aStatusContext) { // FIXME/bug 617804: should the platform support this? return NS_OK; } NS_IMETHODIMP TabChild::SetDimensions(PRUint32 aFlags, PRInt32 aX, PRInt32 aY, PRInt32 aCx, PRInt32 aCy) { NS_NOTREACHED("TabChild::SetDimensions not supported in TabChild"); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::GetDimensions(PRUint32 aFlags, PRInt32* aX, PRInt32* aY, PRInt32* aCx, PRInt32* aCy) { if (aX) { *aX = mOuterRect.x; } if (aY) { *aY = mOuterRect.y; } if (aCx) { *aCx = mOuterRect.width; } if (aCy) { *aCy = mOuterRect.height; } return NS_OK; } NS_IMETHODIMP TabChild::SetFocus() { NS_NOTREACHED("TabChild::SetFocus not supported in TabChild"); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::GetVisibility(bool* aVisibility) { *aVisibility = true; return NS_OK; } NS_IMETHODIMP TabChild::SetVisibility(bool aVisibility) { // should the platform support this? Bug 666365 return NS_OK; } NS_IMETHODIMP TabChild::GetTitle(PRUnichar** aTitle) { NS_NOTREACHED("TabChild::GetTitle not supported in TabChild"); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::SetTitle(const PRUnichar* aTitle) { // FIXME/bug 617804: should the platform support this? return NS_OK; } NS_IMETHODIMP TabChild::GetSiteWindow(void** aSiteWindow) { NS_NOTREACHED("TabChild::GetSiteWindow not supported in TabChild"); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::Blur() { NS_NOTREACHED("TabChild::Blur not supported in TabChild"); return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP TabChild::FocusNextElement() { SendMoveFocus(true); return NS_OK; } NS_IMETHODIMP TabChild::FocusPrevElement() { SendMoveFocus(false); return NS_OK; } 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); } NS_IMETHODIMP TabChild::ProvideWindow(nsIDOMWindow* aParent, PRUint32 aChromeFlags, bool aCalledFromJS, bool aPositionSpecified, bool aSizeSpecified, nsIURI* aURI, const nsAString& aName, const nsACString& aFeatures, bool* aWindowIsNew, nsIDOMWindow** aReturn) { *aReturn = nullptr; // If aParent is inside an