diff --git a/content/xml/document/src/XMLDocument.cpp b/content/xml/document/src/XMLDocument.cpp index d47f0e5c5beb..4ec0408c71ff 100644 --- a/content/xml/document/src/XMLDocument.cpp +++ b/content/xml/document/src/XMLDocument.cpp @@ -298,17 +298,25 @@ ReportUseOfDeprecatedMethod(nsIDocument *aDoc, const char* aWarning) NS_IMETHODIMP XMLDocument::Load(const nsAString& aUrl, bool *aReturn) +{ + ErrorResult rv; + *aReturn = Load(aUrl, rv); + return rv.ErrorCode(); +} + +bool +XMLDocument::Load(const nsAString& aUrl, ErrorResult& aRv) { bool hasHadScriptObject = true; nsIScriptGlobalObject* scriptObject = GetScriptHandlingObject(hasHadScriptObject); - NS_ENSURE_STATE(scriptObject || !hasHadScriptObject); + if (!scriptObject && hasHadScriptObject) { + aRv.Throw(NS_ERROR_UNEXPECTED); + return false; + } ReportUseOfDeprecatedMethod(this, "UseOfDOM3LoadMethodWarning"); - NS_ENSURE_ARG_POINTER(aReturn); - *aReturn = false; - nsCOMPtr callingDoc = do_QueryInterface(nsContentUtils::GetDocumentFromContext()); @@ -324,7 +332,8 @@ XMLDocument::Load(const nsAString& aUrl, bool *aReturn) nsCOMPtr uri; nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl, charset.get(), baseURI); if (NS_FAILED(rv)) { - return rv; + aRv.Throw(rv); + return false; } // Check to see whether the current document is allowed to load this URI. @@ -338,7 +347,10 @@ XMLDocument::Load(const nsAString& aUrl, bool *aReturn) nsCOMPtr principal = NodePrincipal(); if (!nsContentUtils::IsSystemPrincipal(principal)) { rv = principal->CheckMayLoad(uri, false, false); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + return false; + } int16_t shouldLoad = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_XMLHTTPREQUEST, @@ -351,9 +363,13 @@ XMLDocument::Load(const nsAString& aUrl, bool *aReturn) &shouldLoad, nsContentUtils::GetContentPolicy(), nsContentUtils::GetSecurityManager()); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + return false; + } if (NS_CP_REJECTED(shouldLoad)) { - return NS_ERROR_CONTENT_BLOCKED; + aRv.Throw(NS_ERROR_CONTENT_BLOCKED); + return false; } } else { // We're called from chrome, check to make sure the URI we're @@ -370,7 +386,10 @@ XMLDocument::Load(const nsAString& aUrl, bool *aReturn) "longer supported. Use XMLHttpRequest instead."); nsCOMPtr errorObject = do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + return false; + } rv = errorObject->InitWithWindowID(error, NS_ConvertUTF8toUTF16(spec), @@ -381,7 +400,10 @@ XMLDocument::Load(const nsAString& aUrl, bool *aReturn) callingDoc->InnerWindowID() : this->InnerWindowID()); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + return false; + } nsCOMPtr consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID); @@ -389,7 +411,8 @@ XMLDocument::Load(const nsAString& aUrl, bool *aReturn) consoleService->LogMessage(errorObject); } - return NS_ERROR_DOM_SECURITY_ERR; + aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); + return false; } } @@ -418,7 +441,10 @@ XMLDocument::Load(const nsAString& aUrl, bool *aReturn) // Create a channel nsCOMPtr req = nsContentUtils::GetSameOriginChecker(); - NS_ENSURE_TRUE(req, NS_ERROR_OUT_OF_MEMORY); + if (!req) { + aRv.Throw(NS_ERROR_OUT_OF_MEMORY); + return false; + } nsCOMPtr channel; // nsIRequest::LOAD_BACKGROUND prevents throbber from becoming active, @@ -426,7 +452,8 @@ XMLDocument::Load(const nsAString& aUrl, bool *aReturn) rv = NS_NewChannel(getter_AddRefs(channel), uri, nullptr, loadGroup, req, nsIRequest::LOAD_BACKGROUND); if (NS_FAILED(rv)) { - return rv; + aRv.Throw(rv); + return false; } // StartDocumentLoad asserts that readyState is uninitialized, so @@ -444,7 +471,8 @@ XMLDocument::Load(const nsAString& aUrl, bool *aReturn) getter_AddRefs(listener), false))) { NS_ERROR("XMLDocument::Load: Failed to start the document load."); - return rv; + aRv.Throw(rv); + return false; } // After this point, if we error out of this method we should clear @@ -454,7 +482,8 @@ XMLDocument::Load(const nsAString& aUrl, bool *aReturn) rv = channel->AsyncOpen(listener, nullptr); if (NS_FAILED(rv)) { mChannelIsPending = false; - return rv; + aRv.Throw(rv); + return false; } if (!mAsync) { @@ -468,23 +497,21 @@ XMLDocument::Load(const nsAString& aUrl, bool *aReturn) } // We set return to true unless there was a parsing error - nsCOMPtr node = do_QueryInterface(GetRootElement()); - if (node) { - nsAutoString name, ns; - if (NS_SUCCEEDED(node->GetLocalName(name)) && - name.EqualsLiteral("parsererror") && - NS_SUCCEEDED(node->GetNamespaceURI(ns)) && - ns.EqualsLiteral("http://www.mozilla.org/newlayout/xml/parsererror.xml")) { - //return is already false - } else { - *aReturn = true; + Element* rootElement = GetRootElement(); + if (!rootElement) { + return false; + } + + if (rootElement->LocalName().EqualsLiteral("parsererror")) { + nsAutoString ns; + rootElement->GetNamespaceURI(ns); + if (ns.EqualsLiteral("http://www.mozilla.org/newlayout/xml/parsererror.xml")) { + return false; } } - } else { - *aReturn = true; } - return NS_OK; + return true; } nsresult diff --git a/content/xml/document/src/XMLDocument.h b/content/xml/document/src/XMLDocument.h index e05184a3b70d..d163af46f62c 100644 --- a/content/xml/document/src/XMLDocument.h +++ b/content/xml/document/src/XMLDocument.h @@ -51,6 +51,23 @@ public: virtual void DocSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const; // DocSizeOfIncludingThis is inherited from nsIDocument. + + // WebIDL API + bool Load(const nsAString& aUrl, mozilla::ErrorResult& aRv); + bool Async() const + { + return mAsync; + } + // The XPCOM SetAsync is ok for us + + // .location is [Unforgeable], so we have to make it clear that the + // nsIDocument version applies to us (it's shadowed by the XPCOM thing on + // nsDocument). + using nsIDocument::GetLocation; + // But then we need to also pull in the nsDocument XPCOM version + // because nsXULDocument tries to forward to it. + using nsDocument::GetLocation; + protected: // mChannelIsPending indicates whether we're currently asynchronously loading // data from mChannel (via document.load() or normal load). It's set to true diff --git a/dom/webidl/XMLDocument.webidl b/dom/webidl/XMLDocument.webidl new file mode 100644 index 000000000000..0f503c9f5ceb --- /dev/null +++ b/dom/webidl/XMLDocument.webidl @@ -0,0 +1,23 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. + * + * The origin of this IDL file is: + * http://dom.spec.whatwg.org/#xmldocument + * http://www.whatwg.org/specs/web-apps/current-work/#xmldocument + */ + +// http://dom.spec.whatwg.org/#xmldocument +interface XMLDocument : Document {}; + +// http://www.whatwg.org/specs/web-apps/current-work/#xmldocument +partial interface XMLDocument { + [Throws] + boolean load(DOMString url); +}; + +// Gecko extensions? +partial interface XMLDocument { + attribute boolean async; +};