1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/xml/document/src/XMLDocument.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,609 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 + 1.10 +#include "mozilla/dom/XMLDocument.h" 1.11 +#include "nsParserCIID.h" 1.12 +#include "nsCharsetSource.h" 1.13 +#include "nsIXMLContentSink.h" 1.14 +#include "nsPresContext.h" 1.15 +#include "nsIContent.h" 1.16 +#include "nsIContentViewerContainer.h" 1.17 +#include "nsIContentViewer.h" 1.18 +#include "nsIDocShell.h" 1.19 +#include "nsIMarkupDocumentViewer.h" 1.20 +#include "nsHTMLParts.h" 1.21 +#include "nsIComponentManager.h" 1.22 +#include "nsIDOMElement.h" 1.23 +#include "nsIBaseWindow.h" 1.24 +#include "nsIDOMWindow.h" 1.25 +#include "nsIDOMDocumentType.h" 1.26 +#include "nsCOMPtr.h" 1.27 +#include "nsXPIDLString.h" 1.28 +#include "nsIHttpChannel.h" 1.29 +#include "nsIURI.h" 1.30 +#include "nsIServiceManager.h" 1.31 +#include "nsNetUtil.h" 1.32 +#include "nsError.h" 1.33 +#include "nsIScriptSecurityManager.h" 1.34 +#include "nsIPrincipal.h" 1.35 +#include "nsLayoutCID.h" 1.36 +#include "mozilla/dom/Attr.h" 1.37 +#include "nsCExternalHandlerService.h" 1.38 +#include "nsMimeTypes.h" 1.39 +#include "mozilla/EventListenerManager.h" 1.40 +#include "nsContentUtils.h" 1.41 +#include "nsThreadUtils.h" 1.42 +#include "nsJSUtils.h" 1.43 +#include "nsCRT.h" 1.44 +#include "nsIAuthPrompt.h" 1.45 +#include "nsContentCreatorFunctions.h" 1.46 +#include "nsContentPolicyUtils.h" 1.47 +#include "nsIDOMUserDataHandler.h" 1.48 +#include "nsNodeUtils.h" 1.49 +#include "nsIConsoleService.h" 1.50 +#include "nsIScriptError.h" 1.51 +#include "nsIHTMLDocument.h" 1.52 +#include "mozilla/BasicEvents.h" 1.53 +#include "mozilla/EventDispatcher.h" 1.54 +#include "mozilla/dom/Element.h" 1.55 +#include "mozilla/dom/XMLDocumentBinding.h" 1.56 + 1.57 +using namespace mozilla; 1.58 +using namespace mozilla::dom; 1.59 + 1.60 +// ================================================================== 1.61 +// = 1.62 +// ================================================================== 1.63 + 1.64 + 1.65 +nsresult 1.66 +NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult, 1.67 + const nsAString& aNamespaceURI, 1.68 + const nsAString& aQualifiedName, 1.69 + nsIDOMDocumentType* aDoctype, 1.70 + nsIURI* aDocumentURI, 1.71 + nsIURI* aBaseURI, 1.72 + nsIPrincipal* aPrincipal, 1.73 + bool aLoadedAsData, 1.74 + nsIGlobalObject* aEventObject, 1.75 + DocumentFlavor aFlavor) 1.76 +{ 1.77 + // Note: can't require that aDocumentURI/aBaseURI/aPrincipal be non-null, 1.78 + // since at least one caller (XMLHttpRequest) doesn't have decent args to 1.79 + // pass in. 1.80 + 1.81 + nsresult rv; 1.82 + 1.83 + *aInstancePtrResult = nullptr; 1.84 + 1.85 + nsCOMPtr<nsIDocument> d; 1.86 + bool isHTML = false; 1.87 + bool isXHTML = false; 1.88 + if (aFlavor == DocumentFlavorSVG) { 1.89 + rv = NS_NewSVGDocument(getter_AddRefs(d)); 1.90 + } else if (aFlavor == DocumentFlavorHTML) { 1.91 + rv = NS_NewHTMLDocument(getter_AddRefs(d)); 1.92 + isHTML = true; 1.93 + } else if (aDoctype) { 1.94 + nsAutoString publicId, name; 1.95 + aDoctype->GetPublicId(publicId); 1.96 + if (publicId.IsEmpty()) { 1.97 + aDoctype->GetName(name); 1.98 + } 1.99 + if (name.EqualsLiteral("html") || 1.100 + publicId.EqualsLiteral("-//W3C//DTD HTML 4.01//EN") || 1.101 + publicId.EqualsLiteral("-//W3C//DTD HTML 4.01 Frameset//EN") || 1.102 + publicId.EqualsLiteral("-//W3C//DTD HTML 4.01 Transitional//EN") || 1.103 + publicId.EqualsLiteral("-//W3C//DTD HTML 4.0//EN") || 1.104 + publicId.EqualsLiteral("-//W3C//DTD HTML 4.0 Frameset//EN") || 1.105 + publicId.EqualsLiteral("-//W3C//DTD HTML 4.0 Transitional//EN")) { 1.106 + rv = NS_NewHTMLDocument(getter_AddRefs(d)); 1.107 + isHTML = true; 1.108 + } else if (publicId.EqualsLiteral("-//W3C//DTD XHTML 1.0 Strict//EN") || 1.109 + publicId.EqualsLiteral("-//W3C//DTD XHTML 1.0 Transitional//EN") || 1.110 + publicId.EqualsLiteral("-//W3C//DTD XHTML 1.0 Frameset//EN")) { 1.111 + rv = NS_NewHTMLDocument(getter_AddRefs(d)); 1.112 + isHTML = true; 1.113 + isXHTML = true; 1.114 + } 1.115 + else if (publicId.EqualsLiteral("-//W3C//DTD SVG 1.1//EN")) { 1.116 + rv = NS_NewSVGDocument(getter_AddRefs(d)); 1.117 + } 1.118 + // XXX Add support for XUL documents. 1.119 + else { 1.120 + rv = NS_NewXMLDocument(getter_AddRefs(d)); 1.121 + } 1.122 + } else { 1.123 + rv = NS_NewXMLDocument(getter_AddRefs(d)); 1.124 + } 1.125 + 1.126 + if (NS_FAILED(rv)) { 1.127 + return rv; 1.128 + } 1.129 + 1.130 + if (nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aEventObject)) { 1.131 + d->SetScriptHandlingObject(sgo); 1.132 + } else if (aEventObject){ 1.133 + d->SetScopeObject(aEventObject); 1.134 + } 1.135 + 1.136 + if (isHTML) { 1.137 + nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(d); 1.138 + NS_ASSERTION(htmlDoc, "HTML Document doesn't implement nsIHTMLDocument?"); 1.139 + htmlDoc->SetCompatibilityMode(eCompatibility_FullStandards); 1.140 + htmlDoc->SetIsXHTML(isXHTML); 1.141 + } 1.142 + nsDocument* doc = static_cast<nsDocument*>(d.get()); 1.143 + doc->SetLoadedAsData(aLoadedAsData); 1.144 + doc->nsDocument::SetDocumentURI(aDocumentURI); 1.145 + // Must set the principal first, since SetBaseURI checks it. 1.146 + doc->SetPrincipal(aPrincipal); 1.147 + doc->SetBaseURI(aBaseURI); 1.148 + 1.149 + // XMLDocuments and documents "created in memory" get to be UTF-8 by default, 1.150 + // unlike the legacy HTML mess 1.151 + doc->SetDocumentCharacterSet(NS_LITERAL_CSTRING("UTF-8")); 1.152 + 1.153 + if (aDoctype) { 1.154 + nsCOMPtr<nsIDOMNode> tmpNode; 1.155 + rv = doc->AppendChild(aDoctype, getter_AddRefs(tmpNode)); 1.156 + NS_ENSURE_SUCCESS(rv, rv); 1.157 + } 1.158 + 1.159 + if (!aQualifiedName.IsEmpty()) { 1.160 + nsCOMPtr<nsIDOMElement> root; 1.161 + rv = doc->CreateElementNS(aNamespaceURI, aQualifiedName, 1.162 + getter_AddRefs(root)); 1.163 + NS_ENSURE_SUCCESS(rv, rv); 1.164 + 1.165 + nsCOMPtr<nsIDOMNode> tmpNode; 1.166 + 1.167 + rv = doc->AppendChild(root, getter_AddRefs(tmpNode)); 1.168 + NS_ENSURE_SUCCESS(rv, rv); 1.169 + } 1.170 + 1.171 + *aInstancePtrResult = doc; 1.172 + NS_ADDREF(*aInstancePtrResult); 1.173 + 1.174 + return NS_OK; 1.175 +} 1.176 + 1.177 +nsresult 1.178 +NS_NewXMLDocument(nsIDocument** aInstancePtrResult, bool aLoadedAsData) 1.179 +{ 1.180 + nsRefPtr<XMLDocument> doc = new XMLDocument(); 1.181 + 1.182 + nsresult rv = doc->Init(); 1.183 + 1.184 + if (NS_FAILED(rv)) { 1.185 + *aInstancePtrResult = nullptr; 1.186 + return rv; 1.187 + } 1.188 + 1.189 + doc->SetLoadedAsData(aLoadedAsData); 1.190 + doc.forget(aInstancePtrResult); 1.191 + 1.192 + return NS_OK; 1.193 +} 1.194 + 1.195 +nsresult 1.196 +NS_NewXBLDocument(nsIDOMDocument** aInstancePtrResult, 1.197 + nsIURI* aDocumentURI, 1.198 + nsIURI* aBaseURI, 1.199 + nsIPrincipal* aPrincipal) 1.200 +{ 1.201 + nsresult rv = NS_NewDOMDocument(aInstancePtrResult, 1.202 + NS_LITERAL_STRING("http://www.mozilla.org/xbl"), 1.203 + NS_LITERAL_STRING("bindings"), nullptr, 1.204 + aDocumentURI, aBaseURI, aPrincipal, false, 1.205 + nullptr, DocumentFlavorLegacyGuess); 1.206 + NS_ENSURE_SUCCESS(rv, rv); 1.207 + 1.208 + nsCOMPtr<nsIDocument> idoc = do_QueryInterface(*aInstancePtrResult); 1.209 + nsDocument* doc = static_cast<nsDocument*>(idoc.get()); 1.210 + doc->SetLoadedAsInteractiveData(true); 1.211 + doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE); 1.212 + 1.213 + return NS_OK; 1.214 +} 1.215 + 1.216 +namespace mozilla { 1.217 +namespace dom { 1.218 + 1.219 +XMLDocument::XMLDocument(const char* aContentType) 1.220 + : nsDocument(aContentType), 1.221 + mAsync(true) 1.222 +{ 1.223 + // NOTE! nsDocument::operator new() zeroes out all members, so don't 1.224 + // bother initializing members to 0. 1.225 +} 1.226 + 1.227 +XMLDocument::~XMLDocument() 1.228 +{ 1.229 + // XXX We rather crash than hang 1.230 + mLoopingForSyncLoad = false; 1.231 +} 1.232 + 1.233 +// QueryInterface implementation for XMLDocument 1.234 +NS_IMPL_ISUPPORTS_INHERITED(XMLDocument, nsDocument, nsIDOMXMLDocument) 1.235 + 1.236 +nsresult 1.237 +XMLDocument::Init() 1.238 +{ 1.239 + nsresult rv = nsDocument::Init(); 1.240 + NS_ENSURE_SUCCESS(rv, rv); 1.241 + 1.242 + return rv; 1.243 +} 1.244 + 1.245 +void 1.246 +XMLDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) 1.247 +{ 1.248 + nsDocument::Reset(aChannel, aLoadGroup); 1.249 +} 1.250 + 1.251 +void 1.252 +XMLDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup, 1.253 + nsIPrincipal* aPrincipal) 1.254 +{ 1.255 + if (mChannelIsPending) { 1.256 + StopDocumentLoad(); 1.257 + mChannel->Cancel(NS_BINDING_ABORTED); 1.258 + mChannelIsPending = false; 1.259 + } 1.260 + 1.261 + nsDocument::ResetToURI(aURI, aLoadGroup, aPrincipal); 1.262 +} 1.263 + 1.264 +NS_IMETHODIMP 1.265 +XMLDocument::GetAsync(bool *aAsync) 1.266 +{ 1.267 + NS_ENSURE_ARG_POINTER(aAsync); 1.268 + *aAsync = mAsync; 1.269 + return NS_OK; 1.270 +} 1.271 + 1.272 +NS_IMETHODIMP 1.273 +XMLDocument::SetAsync(bool aAsync) 1.274 +{ 1.275 + mAsync = aAsync; 1.276 + return NS_OK; 1.277 +} 1.278 + 1.279 +NS_IMETHODIMP 1.280 +XMLDocument::Load(const nsAString& aUrl, bool *aReturn) 1.281 +{ 1.282 + ErrorResult rv; 1.283 + *aReturn = Load(aUrl, rv); 1.284 + return rv.ErrorCode(); 1.285 +} 1.286 + 1.287 +bool 1.288 +XMLDocument::Load(const nsAString& aUrl, ErrorResult& aRv) 1.289 +{ 1.290 + bool hasHadScriptObject = true; 1.291 + nsIScriptGlobalObject* scriptObject = 1.292 + GetScriptHandlingObject(hasHadScriptObject); 1.293 + if (!scriptObject && hasHadScriptObject) { 1.294 + aRv.Throw(NS_ERROR_UNEXPECTED); 1.295 + return false; 1.296 + } 1.297 + 1.298 + WarnOnceAbout(nsIDocument::eUseOfDOM3LoadMethod); 1.299 + 1.300 + nsCOMPtr<nsIDocument> callingDoc = nsContentUtils::GetDocumentFromContext(); 1.301 + 1.302 + nsIURI *baseURI = mDocumentURI; 1.303 + nsAutoCString charset; 1.304 + 1.305 + if (callingDoc) { 1.306 + baseURI = callingDoc->GetDocBaseURI(); 1.307 + charset = callingDoc->GetDocumentCharacterSet(); 1.308 + } 1.309 + 1.310 + // Create a new URI 1.311 + nsCOMPtr<nsIURI> uri; 1.312 + nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl, charset.get(), baseURI); 1.313 + if (NS_FAILED(rv)) { 1.314 + aRv.Throw(rv); 1.315 + return false; 1.316 + } 1.317 + 1.318 + // Check to see whether the current document is allowed to load this URI. 1.319 + // It's important to use the current document's principal for this check so 1.320 + // that we don't end up in a case where code with elevated privileges is 1.321 + // calling us and changing the principal of this document. 1.322 + 1.323 + // Enforce same-origin even for chrome loaders to avoid someone accidentally 1.324 + // using a document that content has a reference to and turn that into a 1.325 + // chrome document. 1.326 + nsCOMPtr<nsIPrincipal> principal = NodePrincipal(); 1.327 + if (!nsContentUtils::IsSystemPrincipal(principal)) { 1.328 + rv = principal->CheckMayLoad(uri, false, false); 1.329 + if (NS_FAILED(rv)) { 1.330 + aRv.Throw(rv); 1.331 + return false; 1.332 + } 1.333 + 1.334 + int16_t shouldLoad = nsIContentPolicy::ACCEPT; 1.335 + rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_XMLHTTPREQUEST, 1.336 + uri, 1.337 + principal, 1.338 + callingDoc ? callingDoc.get() : 1.339 + static_cast<nsIDocument*>(this), 1.340 + NS_LITERAL_CSTRING("application/xml"), 1.341 + nullptr, 1.342 + &shouldLoad, 1.343 + nsContentUtils::GetContentPolicy(), 1.344 + nsContentUtils::GetSecurityManager()); 1.345 + if (NS_FAILED(rv)) { 1.346 + aRv.Throw(rv); 1.347 + return false; 1.348 + } 1.349 + if (NS_CP_REJECTED(shouldLoad)) { 1.350 + aRv.Throw(NS_ERROR_CONTENT_BLOCKED); 1.351 + return false; 1.352 + } 1.353 + } else { 1.354 + // We're called from chrome, check to make sure the URI we're 1.355 + // about to load is also chrome. 1.356 + 1.357 + bool isChrome = false; 1.358 + if (NS_FAILED(uri->SchemeIs("chrome", &isChrome)) || !isChrome) { 1.359 + nsAutoCString spec; 1.360 + if (mDocumentURI) 1.361 + mDocumentURI->GetSpec(spec); 1.362 + 1.363 + nsAutoString error; 1.364 + error.AssignLiteral("Cross site loading using document.load is no " 1.365 + "longer supported. Use XMLHttpRequest instead."); 1.366 + nsCOMPtr<nsIScriptError> errorObject = 1.367 + do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv); 1.368 + if (NS_FAILED(rv)) { 1.369 + aRv.Throw(rv); 1.370 + return false; 1.371 + } 1.372 + 1.373 + rv = errorObject->InitWithWindowID(error, 1.374 + NS_ConvertUTF8toUTF16(spec), 1.375 + EmptyString(), 1.376 + 0, 0, nsIScriptError::warningFlag, 1.377 + "DOM", 1.378 + callingDoc ? 1.379 + callingDoc->InnerWindowID() : 1.380 + this->InnerWindowID()); 1.381 + 1.382 + if (NS_FAILED(rv)) { 1.383 + aRv.Throw(rv); 1.384 + return false; 1.385 + } 1.386 + 1.387 + nsCOMPtr<nsIConsoleService> consoleService = 1.388 + do_GetService(NS_CONSOLESERVICE_CONTRACTID); 1.389 + if (consoleService) { 1.390 + consoleService->LogMessage(errorObject); 1.391 + } 1.392 + 1.393 + aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); 1.394 + return false; 1.395 + } 1.396 + } 1.397 + 1.398 + // Partial Reset, need to restore principal for security reasons and 1.399 + // event listener manager so that load listeners etc. will 1.400 + // remain. This should be done before the security check is done to 1.401 + // ensure that the document is reset even if the new document can't 1.402 + // be loaded. Note that we need to hold a strong ref to |principal| 1.403 + // here, because ResetToURI will null out our node principal before 1.404 + // setting the new one. 1.405 + nsRefPtr<EventListenerManager> elm(mListenerManager); 1.406 + mListenerManager = nullptr; 1.407 + 1.408 + // When we are called from JS we can find the load group for the page, 1.409 + // and add ourselves to it. This way any pending requests 1.410 + // will be automatically aborted if the user leaves the page. 1.411 + 1.412 + nsCOMPtr<nsILoadGroup> loadGroup; 1.413 + if (callingDoc) { 1.414 + loadGroup = callingDoc->GetDocumentLoadGroup(); 1.415 + } 1.416 + 1.417 + ResetToURI(uri, loadGroup, principal); 1.418 + 1.419 + mListenerManager = elm; 1.420 + 1.421 + // Create a channel 1.422 + nsCOMPtr<nsIInterfaceRequestor> req = nsContentUtils::GetSameOriginChecker(); 1.423 + if (!req) { 1.424 + aRv.Throw(NS_ERROR_OUT_OF_MEMORY); 1.425 + return false; 1.426 + } 1.427 + 1.428 + nsCOMPtr<nsIChannel> channel; 1.429 + // nsIRequest::LOAD_BACKGROUND prevents throbber from becoming active, 1.430 + // which in turn keeps STOP button from becoming active 1.431 + rv = NS_NewChannel(getter_AddRefs(channel), uri, nullptr, loadGroup, req, 1.432 + nsIRequest::LOAD_BACKGROUND); 1.433 + if (NS_FAILED(rv)) { 1.434 + aRv.Throw(rv); 1.435 + return false; 1.436 + } 1.437 + 1.438 + // StartDocumentLoad asserts that readyState is uninitialized, so 1.439 + // uninitialize it. SetReadyStateInternal make this transition invisible to 1.440 + // Web content. But before doing that, assert that the current readyState 1.441 + // is complete as it should be after the call to ResetToURI() above. 1.442 + MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE, 1.443 + "Bad readyState"); 1.444 + SetReadyStateInternal(nsIDocument::READYSTATE_UNINITIALIZED); 1.445 + 1.446 + // Prepare for loading the XML document "into oneself" 1.447 + nsCOMPtr<nsIStreamListener> listener; 1.448 + if (NS_FAILED(rv = StartDocumentLoad(kLoadAsData, channel, 1.449 + loadGroup, nullptr, 1.450 + getter_AddRefs(listener), 1.451 + false))) { 1.452 + NS_ERROR("XMLDocument::Load: Failed to start the document load."); 1.453 + aRv.Throw(rv); 1.454 + return false; 1.455 + } 1.456 + 1.457 + // After this point, if we error out of this method we should clear 1.458 + // mChannelIsPending. 1.459 + 1.460 + // Start an asynchronous read of the XML document 1.461 + rv = channel->AsyncOpen(listener, nullptr); 1.462 + if (NS_FAILED(rv)) { 1.463 + mChannelIsPending = false; 1.464 + aRv.Throw(rv); 1.465 + return false; 1.466 + } 1.467 + 1.468 + if (!mAsync) { 1.469 + nsCOMPtr<nsIThread> thread = do_GetCurrentThread(); 1.470 + 1.471 + nsAutoSyncOperation sync(this); 1.472 + mLoopingForSyncLoad = true; 1.473 + while (mLoopingForSyncLoad) { 1.474 + if (!NS_ProcessNextEvent(thread)) 1.475 + break; 1.476 + } 1.477 + 1.478 + // We set return to true unless there was a parsing error 1.479 + Element* rootElement = GetRootElement(); 1.480 + if (!rootElement) { 1.481 + return false; 1.482 + } 1.483 + 1.484 + if (rootElement->LocalName().EqualsLiteral("parsererror")) { 1.485 + nsAutoString ns; 1.486 + rootElement->GetNamespaceURI(ns); 1.487 + if (ns.EqualsLiteral("http://www.mozilla.org/newlayout/xml/parsererror.xml")) { 1.488 + return false; 1.489 + } 1.490 + } 1.491 + } 1.492 + 1.493 + return true; 1.494 +} 1.495 + 1.496 +nsresult 1.497 +XMLDocument::StartDocumentLoad(const char* aCommand, 1.498 + nsIChannel* aChannel, 1.499 + nsILoadGroup* aLoadGroup, 1.500 + nsISupports* aContainer, 1.501 + nsIStreamListener **aDocListener, 1.502 + bool aReset, 1.503 + nsIContentSink* aSink) 1.504 +{ 1.505 + nsresult rv = nsDocument::StartDocumentLoad(aCommand, 1.506 + aChannel, aLoadGroup, 1.507 + aContainer, 1.508 + aDocListener, aReset, aSink); 1.509 + if (NS_FAILED(rv)) return rv; 1.510 + 1.511 + if (nsCRT::strcmp("loadAsInteractiveData", aCommand) == 0) { 1.512 + mLoadedAsInteractiveData = true; 1.513 + aCommand = kLoadAsData; // XBL, for example, needs scripts and styles 1.514 + } 1.515 + 1.516 + 1.517 + int32_t charsetSource = kCharsetFromDocTypeDefault; 1.518 + nsAutoCString charset(NS_LITERAL_CSTRING("UTF-8")); 1.519 + TryChannelCharset(aChannel, charsetSource, charset, nullptr); 1.520 + 1.521 + nsCOMPtr<nsIURI> aUrl; 1.522 + rv = aChannel->GetURI(getter_AddRefs(aUrl)); 1.523 + if (NS_FAILED(rv)) return rv; 1.524 + 1.525 + static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID); 1.526 + 1.527 + mParser = do_CreateInstance(kCParserCID, &rv); 1.528 + NS_ENSURE_SUCCESS(rv, rv); 1.529 + 1.530 + nsCOMPtr<nsIXMLContentSink> sink; 1.531 + 1.532 + if (aSink) { 1.533 + sink = do_QueryInterface(aSink); 1.534 + } 1.535 + else { 1.536 + nsCOMPtr<nsIDocShell> docShell; 1.537 + if (aContainer) { 1.538 + docShell = do_QueryInterface(aContainer); 1.539 + NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); 1.540 + } 1.541 + rv = NS_NewXMLContentSink(getter_AddRefs(sink), this, aUrl, docShell, 1.542 + aChannel); 1.543 + NS_ENSURE_SUCCESS(rv, rv); 1.544 + } 1.545 + 1.546 + // Set the parser as the stream listener for the document loader... 1.547 + rv = CallQueryInterface(mParser, aDocListener); 1.548 + NS_ENSURE_SUCCESS(rv, rv); 1.549 + 1.550 + NS_ASSERTION(mChannel, "How can we not have a channel here?"); 1.551 + mChannelIsPending = true; 1.552 + 1.553 + SetDocumentCharacterSet(charset); 1.554 + mParser->SetDocumentCharset(charset, charsetSource); 1.555 + mParser->SetCommand(aCommand); 1.556 + mParser->SetContentSink(sink); 1.557 + mParser->Parse(aUrl, nullptr, (void *)this); 1.558 + 1.559 + return NS_OK; 1.560 +} 1.561 + 1.562 +void 1.563 +XMLDocument::EndLoad() 1.564 +{ 1.565 + mChannelIsPending = false; 1.566 + mLoopingForSyncLoad = false; 1.567 + 1.568 + mSynchronousDOMContentLoaded = (mLoadedAsData || mLoadedAsInteractiveData); 1.569 + nsDocument::EndLoad(); 1.570 + if (mSynchronousDOMContentLoaded) { 1.571 + mSynchronousDOMContentLoaded = false; 1.572 + nsDocument::SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE); 1.573 + // Generate a document load event for the case when an XML 1.574 + // document was loaded as pure data without any presentation 1.575 + // attached to it. 1.576 + WidgetEvent event(true, NS_LOAD); 1.577 + EventDispatcher::Dispatch(static_cast<nsIDocument*>(this), nullptr, &event); 1.578 + } 1.579 +} 1.580 + 1.581 +/* virtual */ void 1.582 +XMLDocument::DocAddSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const 1.583 +{ 1.584 + nsDocument::DocAddSizeOfExcludingThis(aWindowSizes); 1.585 +} 1.586 + 1.587 +// nsIDOMDocument interface 1.588 + 1.589 +nsresult 1.590 +XMLDocument::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const 1.591 +{ 1.592 + NS_ASSERTION(aNodeInfo->NodeInfoManager() == mNodeInfoManager, 1.593 + "Can't import this document into another document!"); 1.594 + 1.595 + nsRefPtr<XMLDocument> clone = new XMLDocument(); 1.596 + nsresult rv = CloneDocHelper(clone); 1.597 + NS_ENSURE_SUCCESS(rv, rv); 1.598 + 1.599 + // State from XMLDocument 1.600 + clone->mAsync = mAsync; 1.601 + 1.602 + return CallQueryInterface(clone.get(), aResult); 1.603 +} 1.604 + 1.605 +JSObject* 1.606 +XMLDocument::WrapNode(JSContext *aCx) 1.607 +{ 1.608 + return XMLDocumentBinding::Wrap(aCx, this); 1.609 +} 1.610 + 1.611 +} // namespace dom 1.612 +} // namespace mozilla