Bug 1108887 - Backout part 2 of bug 949435 (SVG iframe). r=bzbarsky

This commit is contained in:
Robert Longson 2015-02-11 11:20:50 +00:00
parent de111093a1
commit f532cc5f04
5 changed files with 178 additions and 276 deletions

View File

@ -71,7 +71,6 @@ EXPORTS += [
'nsDOMJSUtils.h', 'nsDOMJSUtils.h',
'nsDOMNavigationTiming.h', 'nsDOMNavigationTiming.h',
'nsDOMString.h', 'nsDOMString.h',
'nsElementFrameLoaderOwner.h',
'nsFocusManager.h', 'nsFocusManager.h',
'nsFrameMessageManager.h', 'nsFrameMessageManager.h',
'nsGenericDOMDataNode.h', 'nsGenericDOMDataNode.h',
@ -260,7 +259,6 @@ UNIFIED_SOURCES += [
'nsDOMSettableTokenList.cpp', 'nsDOMSettableTokenList.cpp',
'nsDOMTokenList.cpp', 'nsDOMTokenList.cpp',
'nsDOMWindowList.cpp', 'nsDOMWindowList.cpp',
'nsElementFrameLoaderOwner.cpp',
'nsFocusManager.cpp', 'nsFocusManager.cpp',
'nsFormData.cpp', 'nsFormData.cpp',
'nsFrameLoader.cpp', 'nsFrameLoader.cpp',

View File

@ -1,172 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */
/* 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 "nsElementFrameLoaderOwner.h"
#include "nsIDOMDocument.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsContentUtils.h"
#include "mozilla/Preferences.h"
#include "mozilla/ErrorResult.h"
#include "nsIAppsService.h"
#include "nsServiceManagerUtils.h"
#include "mozIApplication.h"
#include "nsIPermissionManager.h"
#include "GeckoProfiler.h"
#include "nsIDocument.h"
#include "nsPIDOMWindow.h"
using namespace mozilla;
using namespace mozilla::dom;
nsElementFrameLoaderOwner::~nsElementFrameLoaderOwner()
{
if (mFrameLoader) {
mFrameLoader->Destroy();
}
}
nsresult
nsElementFrameLoaderOwner::GetContentDocument(nsIDOMDocument** aContentDocument)
{
NS_PRECONDITION(aContentDocument, "Null out param");
nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(GetContentDocument());
document.forget(aContentDocument);
return NS_OK;
}
nsIDocument*
nsElementFrameLoaderOwner::GetContentDocument()
{
nsCOMPtr<nsPIDOMWindow> win = GetContentWindow();
if (!win) {
return nullptr;
}
nsIDocument *doc = win->GetDoc();
// Return null for cross-origin contentDocument.
if (!nsContentUtils::SubjectPrincipal()->
SubsumesConsideringDomain(doc->NodePrincipal())) {
return nullptr;
}
return doc;
}
nsresult
nsElementFrameLoaderOwner::GetContentWindow(nsIDOMWindow** aContentWindow)
{
NS_PRECONDITION(aContentWindow, "Null out param");
nsCOMPtr<nsPIDOMWindow> window = GetContentWindow();
window.forget(aContentWindow);
return NS_OK;
}
already_AddRefed<nsPIDOMWindow>
nsElementFrameLoaderOwner::GetContentWindow()
{
EnsureFrameLoader();
if (!mFrameLoader) {
return nullptr;
}
bool depthTooGreat = false;
mFrameLoader->GetDepthTooGreat(&depthTooGreat);
if (depthTooGreat) {
// Claim to have no contentWindow
return nullptr;
}
nsCOMPtr<nsIDocShell> doc_shell;
mFrameLoader->GetDocShell(getter_AddRefs(doc_shell));
nsCOMPtr<nsPIDOMWindow> win = do_GetInterface(doc_shell);
if (!win) {
return nullptr;
}
NS_ASSERTION(win->IsOuterWindow(),
"Uh, this window should always be an outer window!");
return win.forget();
}
void
nsElementFrameLoaderOwner::EnsureFrameLoader()
{
Element* thisElement = ThisFrameElement();
if (!thisElement->IsInDoc() ||
mFrameLoader ||
mFrameLoaderCreationDisallowed) {
// If frame loader is there, we just keep it around, cached
return;
}
// Strangely enough, this method doesn't actually ensure that the
// frameloader exists. It's more of a best-effort kind of thing.
mFrameLoader = nsFrameLoader::Create(thisElement, mNetworkCreated);
if (mIsPrerendered) {
mFrameLoader->SetIsPrerendered();
}
}
NS_IMETHODIMP
nsElementFrameLoaderOwner::GetFrameLoader(nsIFrameLoader **aFrameLoader)
{
NS_IF_ADDREF(*aFrameLoader = mFrameLoader);
return NS_OK;
}
NS_IMETHODIMP_(already_AddRefed<nsFrameLoader>)
nsElementFrameLoaderOwner::GetFrameLoader()
{
nsRefPtr<nsFrameLoader> loader = mFrameLoader;
return loader.forget();
}
NS_IMETHODIMP
nsElementFrameLoaderOwner::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner)
{
// We don't support this yet
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsElementFrameLoaderOwner::SetIsPrerendered()
{
MOZ_ASSERT(!mFrameLoader, "Please call SetIsPrerendered before frameLoader is created");
mIsPrerendered = true;
return NS_OK;
}
nsresult
nsElementFrameLoaderOwner::LoadSrc()
{
EnsureFrameLoader();
if (!mFrameLoader) {
return NS_OK;
}
nsresult rv = mFrameLoader->LoadFrame();
#ifdef DEBUG
if (NS_FAILED(rv)) {
NS_WARNING("failed to load URL");
}
#endif
return rv;
}
void
nsElementFrameLoaderOwner::SwapFrameLoaders(nsXULElement& aOtherOwner,
ErrorResult& aError)
{
aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
}

View File

@ -1,79 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */
/* 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/. */
#ifndef nsElementFrameLoaderOwner_h
#define nsElementFrameLoaderOwner_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/Element.h"
#include "nsIFrameLoader.h"
#include "nsIDOMEventListener.h"
#include "mozilla/dom/FromParser.h"
#include "mozilla/ErrorResult.h"
#include "nsFrameLoader.h"
namespace mozilla {
namespace dom {
class Element;
} // namespace dom
} // namespace mozilla
class nsXULElement;
/**
* A helper class for frame elements
*/
class nsElementFrameLoaderOwner : public nsIFrameLoaderOwner
{
public:
explicit nsElementFrameLoaderOwner(mozilla::dom::FromParser aFromParser)
: mNetworkCreated(aFromParser == mozilla::dom::FROM_PARSER_NETWORK)
, mIsPrerendered(false)
, mBrowserFrameListenersRegistered(false)
, mFrameLoaderCreationDisallowed(false)
{
}
virtual ~nsElementFrameLoaderOwner();
NS_DECL_NSIFRAMELOADEROWNER
// nsIContent
void SwapFrameLoaders(nsXULElement& aOtherOwner, mozilla::ErrorResult& aError);
protected:
// This doesn't really ensure a frame loader in all cases, only when
// it makes sense.
void EnsureFrameLoader();
nsresult LoadSrc();
nsIDocument* GetContentDocument();
nsresult GetContentDocument(nsIDOMDocument** aContentDocument);
already_AddRefed<nsPIDOMWindow> GetContentWindow();
nsresult GetContentWindow(nsIDOMWindow** aContentWindow);
/**
* Get element for this frame. Avoids diamond inheritance problem.
* @return Element for this node
*/
virtual mozilla::dom::Element* ThisFrameElement() = 0;
nsRefPtr<nsFrameLoader> mFrameLoader;
/**
* True when the element is created by the parser using the
* NS_FROM_PARSER_NETWORK flag.
* If the element is modified, it may lose the flag.
*/
bool mNetworkCreated;
bool mIsPrerendered;
bool mBrowserFrameListenersRegistered;
bool mFrameLoaderCreationDisallowed;
};
#endif // nsElementFrameLoaderOwner_h

View File

@ -42,9 +42,9 @@ NS_IMPL_RELEASE_INHERITED(nsGenericHTMLFrameElement, nsGenericHTMLElement)
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsGenericHTMLFrameElement) NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsGenericHTMLFrameElement)
NS_INTERFACE_TABLE_INHERITED(nsGenericHTMLFrameElement, NS_INTERFACE_TABLE_INHERITED(nsGenericHTMLFrameElement,
nsIFrameLoaderOwner,
nsIDOMMozBrowserFrame, nsIDOMMozBrowserFrame,
nsIMozBrowserFrame, nsIMozBrowserFrame)
nsIFrameLoaderOwner)
NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement) NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
NS_IMPL_BOOL_ATTR(nsGenericHTMLFrameElement, Mozbrowser, mozbrowser) NS_IMPL_BOOL_ATTR(nsGenericHTMLFrameElement, Mozbrowser, mozbrowser)
@ -54,6 +54,96 @@ nsGenericHTMLFrameElement::TabIndexDefault()
return 0; return 0;
} }
nsGenericHTMLFrameElement::~nsGenericHTMLFrameElement()
{
if (mFrameLoader) {
mFrameLoader->Destroy();
}
}
nsresult
nsGenericHTMLFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
{
NS_PRECONDITION(aContentDocument, "Null out param");
nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(GetContentDocument());
document.forget(aContentDocument);
return NS_OK;
}
nsIDocument*
nsGenericHTMLFrameElement::GetContentDocument()
{
nsCOMPtr<nsPIDOMWindow> win = GetContentWindow();
if (!win) {
return nullptr;
}
nsIDocument *doc = win->GetDoc();
// Return null for cross-origin contentDocument.
if (!nsContentUtils::SubjectPrincipal()->
SubsumesConsideringDomain(doc->NodePrincipal())) {
return nullptr;
}
return doc;
}
nsresult
nsGenericHTMLFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow)
{
NS_PRECONDITION(aContentWindow, "Null out param");
nsCOMPtr<nsPIDOMWindow> window = GetContentWindow();
window.forget(aContentWindow);
return NS_OK;
}
already_AddRefed<nsPIDOMWindow>
nsGenericHTMLFrameElement::GetContentWindow()
{
EnsureFrameLoader();
if (!mFrameLoader) {
return nullptr;
}
bool depthTooGreat = false;
mFrameLoader->GetDepthTooGreat(&depthTooGreat);
if (depthTooGreat) {
// Claim to have no contentWindow
return nullptr;
}
nsCOMPtr<nsIDocShell> doc_shell;
mFrameLoader->GetDocShell(getter_AddRefs(doc_shell));
nsCOMPtr<nsPIDOMWindow> win = do_GetInterface(doc_shell);
if (!win) {
return nullptr;
}
NS_ASSERTION(win->IsOuterWindow(),
"Uh, this window should always be an outer window!");
return win.forget();
}
void
nsGenericHTMLFrameElement::EnsureFrameLoader()
{
if (!IsInDoc() || mFrameLoader || mFrameLoaderCreationDisallowed) {
// If frame loader is there, we just keep it around, cached
return;
}
// Strangely enough, this method doesn't actually ensure that the
// frameloader exists. It's more of a best-effort kind of thing.
mFrameLoader = nsFrameLoader::Create(this, mNetworkCreated);
if (mIsPrerendered) {
mFrameLoader->SetIsPrerendered();
}
}
nsresult nsresult
nsGenericHTMLFrameElement::CreateRemoteFrameLoader(nsITabParent* aTabParent) nsGenericHTMLFrameElement::CreateRemoteFrameLoader(nsITabParent* aTabParent)
{ {
@ -72,6 +162,54 @@ nsGenericHTMLFrameElement::CreateRemoteFrameLoader(nsITabParent* aTabParent)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsGenericHTMLFrameElement::GetFrameLoader(nsIFrameLoader **aFrameLoader)
{
NS_IF_ADDREF(*aFrameLoader = mFrameLoader);
return NS_OK;
}
NS_IMETHODIMP_(already_AddRefed<nsFrameLoader>)
nsGenericHTMLFrameElement::GetFrameLoader()
{
nsRefPtr<nsFrameLoader> loader = mFrameLoader;
return loader.forget();
}
NS_IMETHODIMP
nsGenericHTMLFrameElement::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner)
{
// We don't support this yet
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsGenericHTMLFrameElement::SetIsPrerendered()
{
MOZ_ASSERT(!mFrameLoader, "Please call SetIsPrerendered before frameLoader is created");
mIsPrerendered = true;
return NS_OK;
}
nsresult
nsGenericHTMLFrameElement::LoadSrc()
{
EnsureFrameLoader();
if (!mFrameLoader) {
return NS_OK;
}
nsresult rv = mFrameLoader->LoadFrame();
#ifdef DEBUG
if (NS_FAILED(rv)) {
NS_WARNING("failed to load URL");
}
#endif
return rv;
}
nsresult nsresult
nsGenericHTMLFrameElement::BindToTree(nsIDocument* aDocument, nsGenericHTMLFrameElement::BindToTree(nsIDocument* aDocument,
nsIContent* aParent, nsIContent* aParent,
@ -507,3 +645,11 @@ nsGenericHTMLFrameElement::InitializeBrowserAPI()
InitBrowserElementAPI(); InitBrowserElementAPI();
return NS_OK; return NS_OK;
} }
void
nsGenericHTMLFrameElement::SwapFrameLoaders(nsXULElement& aOtherOwner,
ErrorResult& aError)
{
aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
}

View File

@ -12,7 +12,6 @@
#include "mozilla/ErrorResult.h" #include "mozilla/ErrorResult.h"
#include "mozilla/dom/nsBrowserElement.h" #include "mozilla/dom/nsBrowserElement.h"
#include "nsElementFrameLoaderOwner.h"
#include "nsFrameLoader.h" #include "nsFrameLoader.h"
#include "nsGenericHTMLElement.h" #include "nsGenericHTMLElement.h"
#include "nsIDOMEventListener.h" #include "nsIDOMEventListener.h"
@ -25,7 +24,7 @@ class nsXULElement;
* A helper class for frame elements * A helper class for frame elements
*/ */
class nsGenericHTMLFrameElement : public nsGenericHTMLElement, class nsGenericHTMLFrameElement : public nsGenericHTMLElement,
public nsElementFrameLoaderOwner, public nsIFrameLoaderOwner,
public mozilla::nsBrowserElement, public mozilla::nsBrowserElement,
public nsIMozBrowserFrame public nsIMozBrowserFrame
{ {
@ -33,13 +32,17 @@ public:
nsGenericHTMLFrameElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo, nsGenericHTMLFrameElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
mozilla::dom::FromParser aFromParser) mozilla::dom::FromParser aFromParser)
: nsGenericHTMLElement(aNodeInfo) : nsGenericHTMLElement(aNodeInfo)
, nsElementFrameLoaderOwner(aFromParser)
, nsBrowserElement() , nsBrowserElement()
, mNetworkCreated(aFromParser == mozilla::dom::FROM_PARSER_NETWORK)
, mIsPrerendered(false)
, mBrowserFrameListenersRegistered(false)
, mFrameLoaderCreationDisallowed(false)
{ {
} }
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIFRAMELOADEROWNER
NS_DECL_NSIDOMMOZBROWSERFRAME NS_DECL_NSIDOMMOZBROWSERFRAME
NS_DECL_NSIMOZBROWSERFRAME NS_DECL_NSIMOZBROWSERFRAME
@ -72,20 +75,9 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsGenericHTMLFrameElement, NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsGenericHTMLFrameElement,
nsGenericHTMLElement) nsGenericHTMLElement)
static bool BrowserFramesEnabled(); void SwapFrameLoaders(nsXULElement& aOtherOwner, mozilla::ErrorResult& aError);
/** static bool BrowserFramesEnabled();
* nsIFrameLoaderOwner defines two GetFrameLoader() overloads. One
* is XPCOM style interface, the other one is C++ only. "using" pulls
* them both in, now GetFrameLoader() is ambiguous because
* nsBrowserElement also has GetFrameLoader(). Explicit redefine
* GetFrameLoader() to choose nsElementFrameLoaderOwner::GetFrameLoader()
*/
using nsElementFrameLoaderOwner::GetFrameLoader;
NS_IMETHOD_(already_AddRefed<nsFrameLoader>) GetFrameLoader() MOZ_OVERRIDE
{
return nsElementFrameLoaderOwner::GetFrameLoader();
}
/** /**
* Helper method to map a HTML 'scrolling' attribute value to a nsIScrollable * Helper method to map a HTML 'scrolling' attribute value to a nsIScrollable
@ -98,12 +90,29 @@ public:
static int32_t MapScrollingAttribute(const nsAttrValue* aValue); static int32_t MapScrollingAttribute(const nsAttrValue* aValue);
protected: protected:
virtual ~nsGenericHTMLFrameElement() {} virtual ~nsGenericHTMLFrameElement();
virtual mozilla::dom::Element* ThisFrameElement() MOZ_OVERRIDE // This doesn't really ensure a frame loader in all cases, only when
{ // it makes sense.
return this; void EnsureFrameLoader();
} nsresult LoadSrc();
nsIDocument* GetContentDocument();
nsresult GetContentDocument(nsIDOMDocument** aContentDocument);
already_AddRefed<nsPIDOMWindow> GetContentWindow();
nsresult GetContentWindow(nsIDOMWindow** aContentWindow);
nsRefPtr<nsFrameLoader> mFrameLoader;
/**
* True when the element is created by the parser using the
* NS_FROM_PARSER_NETWORK flag.
* If the element is modified, it may lose the flag.
*/
bool mNetworkCreated;
bool mIsPrerendered;
bool mBrowserFrameListenersRegistered;
bool mFrameLoaderCreationDisallowed;
private: private:
void GetManifestURLByType(nsIAtom *aAppType, nsAString& aOut); void GetManifestURLByType(nsIAtom *aAppType, nsAString& aOut);