Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 :
8 : #include "mozilla/dom/XMLDocument.h"
9 : #include "nsParserCIID.h"
10 : #include "nsCharsetSource.h"
11 : #include "nsIXMLContentSink.h"
12 : #include "nsPresContext.h"
13 : #include "nsIContent.h"
14 : #include "nsIContentViewerContainer.h"
15 : #include "nsIContentViewer.h"
16 : #include "nsIDocShell.h"
17 : #include "nsHTMLParts.h"
18 : #include "nsIComponentManager.h"
19 : #include "nsIDOMElement.h"
20 : #include "nsIBaseWindow.h"
21 : #include "nsIDOMWindow.h"
22 : #include "nsIDOMDocumentType.h"
23 : #include "nsCOMPtr.h"
24 : #include "nsXPIDLString.h"
25 : #include "nsIHttpChannelInternal.h"
26 : #include "nsIURI.h"
27 : #include "nsIServiceManager.h"
28 : #include "nsNetUtil.h"
29 : #include "nsError.h"
30 : #include "nsIScriptSecurityManager.h"
31 : #include "nsIPrincipal.h"
32 : #include "nsLayoutCID.h"
33 : #include "mozilla/dom/Attr.h"
34 : #include "nsCExternalHandlerService.h"
35 : #include "nsMimeTypes.h"
36 : #include "mozilla/EventListenerManager.h"
37 : #include "nsContentUtils.h"
38 : #include "nsThreadUtils.h"
39 : #include "nsJSUtils.h"
40 : #include "nsCRT.h"
41 : #include "nsIAuthPrompt.h"
42 : #include "nsContentCreatorFunctions.h"
43 : #include "nsContentPolicyUtils.h"
44 : #include "nsNodeUtils.h"
45 : #include "nsIConsoleService.h"
46 : #include "nsIScriptError.h"
47 : #include "nsIHTMLDocument.h"
48 : #include "mozilla/BasicEvents.h"
49 : #include "mozilla/EventDispatcher.h"
50 : #include "mozilla/dom/Element.h"
51 : #include "mozilla/dom/XMLDocumentBinding.h"
52 : #include "mozilla/dom/DocumentBinding.h"
53 :
54 : using namespace mozilla;
55 : using namespace mozilla::dom;
56 :
57 : // ==================================================================
58 : // =
59 : // ==================================================================
60 :
61 :
62 : nsresult
63 25 : NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult,
64 : const nsAString& aNamespaceURI,
65 : const nsAString& aQualifiedName,
66 : nsIDOMDocumentType* aDoctype,
67 : nsIURI* aDocumentURI,
68 : nsIURI* aBaseURI,
69 : nsIPrincipal* aPrincipal,
70 : bool aLoadedAsData,
71 : nsIGlobalObject* aEventObject,
72 : DocumentFlavor aFlavor)
73 : {
74 : // Note: can't require that aDocumentURI/aBaseURI/aPrincipal be non-null,
75 : // since at least one caller (XMLHttpRequest) doesn't have decent args to
76 : // pass in.
77 :
78 : nsresult rv;
79 :
80 25 : *aInstancePtrResult = nullptr;
81 :
82 50 : nsCOMPtr<nsIDocument> d;
83 25 : bool isHTML = false;
84 25 : bool isXHTML = false;
85 25 : if (aFlavor == DocumentFlavorSVG) {
86 0 : rv = NS_NewSVGDocument(getter_AddRefs(d));
87 25 : } else if (aFlavor == DocumentFlavorHTML) {
88 0 : rv = NS_NewHTMLDocument(getter_AddRefs(d));
89 0 : isHTML = true;
90 25 : } else if (aFlavor == DocumentFlavorPlain) {
91 0 : rv = NS_NewXMLDocument(getter_AddRefs(d), aLoadedAsData, true);
92 25 : } else if (aDoctype) {
93 0 : MOZ_ASSERT(aFlavor == DocumentFlavorLegacyGuess);
94 0 : nsAutoString publicId, name;
95 0 : aDoctype->GetPublicId(publicId);
96 0 : if (publicId.IsEmpty()) {
97 0 : aDoctype->GetName(name);
98 : }
99 0 : if (name.EqualsLiteral("html") ||
100 0 : publicId.EqualsLiteral("-//W3C//DTD HTML 4.01//EN") ||
101 0 : publicId.EqualsLiteral("-//W3C//DTD HTML 4.01 Frameset//EN") ||
102 0 : publicId.EqualsLiteral("-//W3C//DTD HTML 4.01 Transitional//EN") ||
103 0 : publicId.EqualsLiteral("-//W3C//DTD HTML 4.0//EN") ||
104 0 : publicId.EqualsLiteral("-//W3C//DTD HTML 4.0 Frameset//EN") ||
105 0 : publicId.EqualsLiteral("-//W3C//DTD HTML 4.0 Transitional//EN")) {
106 0 : rv = NS_NewHTMLDocument(getter_AddRefs(d));
107 0 : isHTML = true;
108 0 : } else if (publicId.EqualsLiteral("-//W3C//DTD XHTML 1.0 Strict//EN") ||
109 0 : publicId.EqualsLiteral("-//W3C//DTD XHTML 1.0 Transitional//EN") ||
110 0 : publicId.EqualsLiteral("-//W3C//DTD XHTML 1.0 Frameset//EN")) {
111 0 : rv = NS_NewHTMLDocument(getter_AddRefs(d));
112 0 : isHTML = true;
113 0 : isXHTML = true;
114 : }
115 0 : else if (publicId.EqualsLiteral("-//W3C//DTD SVG 1.1//EN")) {
116 0 : rv = NS_NewSVGDocument(getter_AddRefs(d));
117 : }
118 : // XXX Add support for XUL documents.
119 : else {
120 0 : rv = NS_NewXMLDocument(getter_AddRefs(d));
121 : }
122 : } else {
123 25 : MOZ_ASSERT(aFlavor == DocumentFlavorLegacyGuess);
124 25 : rv = NS_NewXMLDocument(getter_AddRefs(d));
125 : }
126 :
127 25 : if (NS_FAILED(rv)) {
128 0 : return rv;
129 : }
130 :
131 25 : if (isHTML) {
132 0 : nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(d);
133 0 : NS_ASSERTION(htmlDoc, "HTML Document doesn't implement nsIHTMLDocument?");
134 0 : htmlDoc->SetCompatibilityMode(eCompatibility_FullStandards);
135 0 : htmlDoc->SetIsXHTML(isXHTML);
136 : }
137 25 : nsDocument* doc = static_cast<nsDocument*>(d.get());
138 25 : doc->SetLoadedAsData(aLoadedAsData);
139 25 : doc->nsDocument::SetDocumentURI(aDocumentURI);
140 : // Must set the principal first, since SetBaseURI checks it.
141 25 : doc->SetPrincipal(aPrincipal);
142 25 : doc->SetBaseURI(aBaseURI);
143 :
144 : // We need to set the script handling object after we set the principal such
145 : // that the doc group is assigned correctly.
146 50 : if (nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aEventObject)) {
147 0 : d->SetScriptHandlingObject(sgo);
148 25 : } else if (aEventObject){
149 0 : d->SetScopeObject(aEventObject);
150 : }
151 :
152 : // XMLDocuments and documents "created in memory" get to be UTF-8 by default,
153 : // unlike the legacy HTML mess
154 25 : doc->SetDocumentCharacterSet(UTF_8_ENCODING);
155 :
156 25 : if (aDoctype) {
157 0 : nsCOMPtr<nsINode> doctypeAsNode = do_QueryInterface(aDoctype);
158 0 : ErrorResult result;
159 0 : d->AppendChild(*doctypeAsNode, result);
160 0 : if (NS_WARN_IF(result.Failed())) {
161 0 : return result.StealNSResult();
162 : }
163 : }
164 :
165 25 : if (!aQualifiedName.IsEmpty()) {
166 50 : ErrorResult result;
167 50 : ElementCreationOptionsOrString options;
168 25 : options.SetAsString();
169 :
170 : nsCOMPtr<Element> root =
171 50 : doc->CreateElementNS(aNamespaceURI, aQualifiedName, options, result);
172 25 : if (NS_WARN_IF(result.Failed())) {
173 0 : return result.StealNSResult();
174 : }
175 :
176 25 : d->AppendChild(*root, result);
177 25 : if (NS_WARN_IF(result.Failed())) {
178 0 : return result.StealNSResult();
179 : }
180 : }
181 :
182 25 : *aInstancePtrResult = doc;
183 25 : NS_ADDREF(*aInstancePtrResult);
184 :
185 25 : return NS_OK;
186 : }
187 :
188 : nsresult
189 26 : NS_NewXMLDocument(nsIDocument** aInstancePtrResult, bool aLoadedAsData,
190 : bool aIsPlainDocument)
191 : {
192 52 : RefPtr<XMLDocument> doc = new XMLDocument();
193 :
194 26 : nsresult rv = doc->Init();
195 :
196 26 : if (NS_FAILED(rv)) {
197 0 : *aInstancePtrResult = nullptr;
198 0 : return rv;
199 : }
200 :
201 26 : doc->SetLoadedAsData(aLoadedAsData);
202 26 : doc->mIsPlainDocument = aIsPlainDocument;
203 26 : doc.forget(aInstancePtrResult);
204 :
205 26 : return NS_OK;
206 : }
207 :
208 : nsresult
209 25 : NS_NewXBLDocument(nsIDOMDocument** aInstancePtrResult,
210 : nsIURI* aDocumentURI,
211 : nsIURI* aBaseURI,
212 : nsIPrincipal* aPrincipal)
213 : {
214 50 : nsresult rv = NS_NewDOMDocument(aInstancePtrResult,
215 50 : NS_LITERAL_STRING("http://www.mozilla.org/xbl"),
216 50 : NS_LITERAL_STRING("bindings"), nullptr,
217 : aDocumentURI, aBaseURI, aPrincipal, false,
218 75 : nullptr, DocumentFlavorLegacyGuess);
219 25 : NS_ENSURE_SUCCESS(rv, rv);
220 :
221 50 : nsCOMPtr<nsIDocument> idoc = do_QueryInterface(*aInstancePtrResult);
222 25 : nsDocument* doc = static_cast<nsDocument*>(idoc.get());
223 25 : doc->SetLoadedAsInteractiveData(true);
224 25 : doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
225 :
226 25 : return NS_OK;
227 : }
228 :
229 : namespace mozilla {
230 : namespace dom {
231 :
232 48 : XMLDocument::XMLDocument(const char* aContentType)
233 : : nsDocument(aContentType),
234 : mChannelIsPending(false),
235 : mAsync(true),
236 : mLoopingForSyncLoad(false),
237 : mIsPlainDocument(false),
238 : mSuppressParserErrorElement(false),
239 48 : mSuppressParserErrorConsoleMessages(false)
240 : {
241 48 : mType = eGenericXML;
242 48 : }
243 :
244 0 : XMLDocument::~XMLDocument()
245 : {
246 : // XXX We rather crash than hang
247 0 : mLoopingForSyncLoad = false;
248 0 : }
249 :
250 : // QueryInterface implementation for XMLDocument
251 39175 : NS_IMPL_ISUPPORTS_INHERITED(XMLDocument, nsDocument, nsIDOMXMLDocument)
252 :
253 : nsresult
254 48 : XMLDocument::Init()
255 : {
256 48 : nsresult rv = nsDocument::Init();
257 48 : NS_ENSURE_SUCCESS(rv, rv);
258 :
259 48 : return rv;
260 : }
261 :
262 : void
263 22 : XMLDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup)
264 : {
265 22 : nsDocument::Reset(aChannel, aLoadGroup);
266 22 : }
267 :
268 : void
269 22 : XMLDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
270 : nsIPrincipal* aPrincipal)
271 : {
272 22 : if (mChannelIsPending) {
273 0 : StopDocumentLoad();
274 0 : mChannel->Cancel(NS_BINDING_ABORTED);
275 0 : mChannelIsPending = false;
276 : }
277 :
278 22 : nsDocument::ResetToURI(aURI, aLoadGroup, aPrincipal);
279 22 : }
280 :
281 : bool
282 0 : XMLDocument::Load(const nsAString& aUrl, CallerType aCallerType,
283 : ErrorResult& aRv)
284 : {
285 0 : bool hasHadScriptObject = true;
286 : nsIScriptGlobalObject* scriptObject =
287 0 : GetScriptHandlingObject(hasHadScriptObject);
288 0 : if (!scriptObject && hasHadScriptObject) {
289 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
290 0 : return false;
291 : }
292 :
293 0 : nsCOMPtr<nsIDocument> callingDoc = GetEntryDocument();
294 0 : nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
295 :
296 : // The callingDoc's Principal and doc's Principal should be the same
297 0 : if (callingDoc && (callingDoc->NodePrincipal() != principal)) {
298 0 : nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
299 0 : NS_LITERAL_CSTRING("DOM"),
300 : callingDoc,
301 : nsContentUtils::eDOM_PROPERTIES,
302 0 : "XMLDocumentLoadPrincipalMismatch");
303 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
304 0 : return false;
305 : }
306 :
307 : // Reporting a warning on ourselves is rather pointless, because we probably
308 : // have no window id (and hence the warning won't show up in any web console)
309 : // and probably aren't considered a "content document" because we're not
310 : // loaded in a docshell, so won't accumulate telemetry for use counters. Try
311 : // warning on our entry document, if any, since that should have things like
312 : // window ids and associated docshells.
313 0 : nsIDocument* docForWarning = callingDoc ? callingDoc.get() : this;
314 0 : if (aCallerType == CallerType::System) {
315 0 : docForWarning->WarnOnceAbout(nsIDocument::eChromeUseOfDOM3LoadMethod);
316 : } else {
317 0 : docForWarning->WarnOnceAbout(nsIDocument::eUseOfDOM3LoadMethod);
318 : }
319 :
320 0 : nsIURI *baseURI = mDocumentURI;
321 0 : nsAutoCString charset;
322 :
323 0 : if (callingDoc) {
324 0 : baseURI = callingDoc->GetDocBaseURI();
325 0 : callingDoc->GetDocumentCharacterSet()->Name(charset);
326 : }
327 :
328 : // Create a new URI
329 0 : nsCOMPtr<nsIURI> uri;
330 0 : nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl, charset.get(), baseURI);
331 0 : if (NS_FAILED(rv)) {
332 0 : aRv.Throw(rv);
333 0 : return false;
334 : }
335 :
336 0 : if (nsContentUtils::IsSystemPrincipal(principal)) {
337 : // We're called from chrome, check to make sure the URI we're
338 : // about to load is also chrome.
339 :
340 0 : bool isChrome = false;
341 0 : if (NS_FAILED(uri->SchemeIs("chrome", &isChrome)) || !isChrome) {
342 0 : nsAutoCString spec;
343 0 : if (mDocumentURI)
344 0 : mDocumentURI->GetSpec(spec);
345 :
346 0 : nsAutoString error;
347 : error.AssignLiteral("Cross site loading using document.load is no "
348 0 : "longer supported. Use XMLHttpRequest instead.");
349 : nsCOMPtr<nsIScriptError> errorObject =
350 0 : do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
351 0 : if (NS_FAILED(rv)) {
352 0 : aRv.Throw(rv);
353 0 : return false;
354 : }
355 :
356 0 : rv = errorObject->InitWithWindowID(error,
357 0 : NS_ConvertUTF8toUTF16(spec),
358 0 : EmptyString(),
359 : 0, 0, nsIScriptError::warningFlag,
360 : "DOM",
361 : callingDoc ?
362 0 : callingDoc->InnerWindowID() :
363 0 : this->InnerWindowID());
364 :
365 0 : if (NS_FAILED(rv)) {
366 0 : aRv.Throw(rv);
367 0 : return false;
368 : }
369 :
370 : nsCOMPtr<nsIConsoleService> consoleService =
371 0 : do_GetService(NS_CONSOLESERVICE_CONTRACTID);
372 0 : if (consoleService) {
373 0 : consoleService->LogMessage(errorObject);
374 : }
375 :
376 0 : aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
377 0 : return false;
378 : }
379 : }
380 :
381 : // Partial Reset, need to restore principal for security reasons and
382 : // event listener manager so that load listeners etc. will
383 : // remain. This should be done before the security check is done to
384 : // ensure that the document is reset even if the new document can't
385 : // be loaded. Note that we need to hold a strong ref to |principal|
386 : // here, because ResetToURI will null out our node principal before
387 : // setting the new one.
388 0 : RefPtr<EventListenerManager> elm(mListenerManager);
389 0 : mListenerManager = nullptr;
390 :
391 : // When we are called from JS we can find the load group for the page,
392 : // and add ourselves to it. This way any pending requests
393 : // will be automatically aborted if the user leaves the page.
394 :
395 0 : nsCOMPtr<nsILoadGroup> loadGroup;
396 0 : if (callingDoc) {
397 0 : loadGroup = callingDoc->GetDocumentLoadGroup();
398 : }
399 :
400 0 : ResetToURI(uri, loadGroup, principal);
401 :
402 0 : mListenerManager = elm;
403 :
404 : // Create a channel
405 0 : nsCOMPtr<nsIInterfaceRequestor> req = nsContentUtils::SameOriginChecker();
406 :
407 0 : nsCOMPtr<nsIChannel> channel;
408 : // nsIRequest::LOAD_BACKGROUND prevents throbber from becoming active,
409 : // which in turn keeps STOP button from becoming active
410 0 : rv = NS_NewChannel(getter_AddRefs(channel),
411 : uri,
412 : callingDoc ? callingDoc.get() :
413 0 : static_cast<nsIDocument*>(this),
414 : nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
415 : nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST,
416 : loadGroup,
417 : req,
418 : nsIRequest::LOAD_BACKGROUND);
419 :
420 0 : if (NS_FAILED(rv)) {
421 0 : aRv.Throw(rv);
422 0 : return false;
423 : }
424 :
425 : // TODO Bug 1189945: Remove nsIChannel CorsMode flag and set Request.mode
426 : // based on nsILoadInfo securityFlags instead. This block will be removed
427 : // when Request.mode set correctly.
428 0 : nsCOMPtr<nsIHttpChannelInternal> httpChannel = do_QueryInterface(channel);
429 0 : if (httpChannel) {
430 0 : rv = httpChannel->SetCorsMode(nsIHttpChannelInternal::CORS_MODE_SAME_ORIGIN);
431 0 : MOZ_ASSERT(NS_SUCCEEDED(rv));
432 : }
433 :
434 : // StartDocumentLoad asserts that readyState is uninitialized, so
435 : // uninitialize it. SetReadyStateInternal make this transition invisible to
436 : // Web content. But before doing that, assert that the current readyState
437 : // is complete as it should be after the call to ResetToURI() above.
438 0 : MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE,
439 : "Bad readyState");
440 0 : SetReadyStateInternal(nsIDocument::READYSTATE_UNINITIALIZED);
441 :
442 : // Prepare for loading the XML document "into oneself"
443 0 : nsCOMPtr<nsIStreamListener> listener;
444 0 : if (NS_FAILED(rv = StartDocumentLoad(kLoadAsData, channel,
445 : loadGroup, nullptr,
446 : getter_AddRefs(listener),
447 : false))) {
448 0 : NS_ERROR("XMLDocument::Load: Failed to start the document load.");
449 0 : aRv.Throw(rv);
450 0 : return false;
451 : }
452 :
453 : // After this point, if we error out of this method we should clear
454 : // mChannelIsPending.
455 :
456 : // Start an asynchronous read of the XML document
457 0 : rv = channel->AsyncOpen2(listener);
458 0 : if (NS_FAILED(rv)) {
459 0 : mChannelIsPending = false;
460 0 : aRv.Throw(rv);
461 0 : return false;
462 : }
463 :
464 0 : if (!mAsync) {
465 0 : nsAutoSyncOperation sync(this);
466 0 : mLoopingForSyncLoad = true;
467 0 : SpinEventLoopUntil([&]() { return !mLoopingForSyncLoad; });
468 :
469 : // We set return to true unless there was a parsing error
470 0 : Element* rootElement = GetRootElement();
471 0 : if (!rootElement) {
472 0 : return false;
473 : }
474 :
475 0 : if (rootElement->LocalName().EqualsLiteral("parsererror")) {
476 0 : nsAutoString ns;
477 0 : rootElement->GetNamespaceURI(ns);
478 0 : if (ns.EqualsLiteral("http://www.mozilla.org/newlayout/xml/parsererror.xml")) {
479 0 : return false;
480 : }
481 : }
482 : }
483 :
484 0 : return true;
485 : }
486 :
487 : void
488 0 : XMLDocument::SetSuppressParserErrorElement(bool aSuppress)
489 : {
490 0 : mSuppressParserErrorElement = aSuppress;
491 0 : }
492 :
493 : bool
494 0 : XMLDocument::SuppressParserErrorElement()
495 : {
496 0 : return mSuppressParserErrorElement;
497 : }
498 :
499 : void
500 0 : XMLDocument::SetSuppressParserErrorConsoleMessages(bool aSuppress)
501 : {
502 0 : mSuppressParserErrorConsoleMessages = aSuppress;
503 0 : }
504 :
505 : bool
506 0 : XMLDocument::SuppressParserErrorConsoleMessages()
507 : {
508 0 : return mSuppressParserErrorConsoleMessages;
509 : }
510 :
511 : nsresult
512 22 : XMLDocument::StartDocumentLoad(const char* aCommand,
513 : nsIChannel* aChannel,
514 : nsILoadGroup* aLoadGroup,
515 : nsISupports* aContainer,
516 : nsIStreamListener **aDocListener,
517 : bool aReset,
518 : nsIContentSink* aSink)
519 : {
520 22 : nsresult rv = nsDocument::StartDocumentLoad(aCommand,
521 : aChannel, aLoadGroup,
522 : aContainer,
523 22 : aDocListener, aReset, aSink);
524 22 : if (NS_FAILED(rv)) return rv;
525 :
526 22 : if (nsCRT::strcmp("loadAsInteractiveData", aCommand) == 0) {
527 1 : mLoadedAsInteractiveData = true;
528 1 : aCommand = kLoadAsData; // XBL, for example, needs scripts and styles
529 : }
530 :
531 :
532 22 : int32_t charsetSource = kCharsetFromDocTypeDefault;
533 22 : NotNull<const Encoding*> encoding = UTF_8_ENCODING;
534 22 : TryChannelCharset(aChannel, charsetSource, encoding, nullptr);
535 :
536 44 : nsCOMPtr<nsIURI> aUrl;
537 22 : rv = aChannel->GetURI(getter_AddRefs(aUrl));
538 22 : if (NS_FAILED(rv)) return rv;
539 :
540 : static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
541 :
542 22 : mParser = do_CreateInstance(kCParserCID, &rv);
543 22 : NS_ENSURE_SUCCESS(rv, rv);
544 :
545 44 : nsCOMPtr<nsIXMLContentSink> sink;
546 :
547 22 : if (aSink) {
548 1 : sink = do_QueryInterface(aSink);
549 : }
550 : else {
551 42 : nsCOMPtr<nsIDocShell> docShell;
552 21 : if (aContainer) {
553 0 : docShell = do_QueryInterface(aContainer);
554 0 : NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
555 : }
556 21 : rv = NS_NewXMLContentSink(getter_AddRefs(sink), this, aUrl, docShell,
557 21 : aChannel);
558 21 : NS_ENSURE_SUCCESS(rv, rv);
559 : }
560 :
561 : // Set the parser as the stream listener for the document loader...
562 22 : rv = CallQueryInterface(mParser, aDocListener);
563 22 : NS_ENSURE_SUCCESS(rv, rv);
564 :
565 22 : NS_ASSERTION(mChannel, "How can we not have a channel here?");
566 22 : mChannelIsPending = true;
567 :
568 22 : SetDocumentCharacterSet(encoding);
569 22 : mParser->SetDocumentCharset(encoding, charsetSource);
570 22 : mParser->SetCommand(aCommand);
571 22 : mParser->SetContentSink(sink);
572 22 : mParser->Parse(aUrl, nullptr, (void *)this);
573 :
574 22 : return NS_OK;
575 : }
576 :
577 : void
578 22 : XMLDocument::EndLoad()
579 : {
580 22 : mChannelIsPending = false;
581 22 : mLoopingForSyncLoad = false;
582 :
583 22 : mSynchronousDOMContentLoaded = (mLoadedAsData || mLoadedAsInteractiveData);
584 22 : nsDocument::EndLoad();
585 22 : if (mSynchronousDOMContentLoaded) {
586 1 : mSynchronousDOMContentLoaded = false;
587 1 : nsDocument::SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
588 : // Generate a document load event for the case when an XML
589 : // document was loaded as pure data without any presentation
590 : // attached to it.
591 2 : WidgetEvent event(true, eLoad);
592 1 : EventDispatcher::Dispatch(static_cast<nsIDocument*>(this), nullptr, &event);
593 : }
594 22 : }
595 :
596 : /* virtual */ void
597 21 : XMLDocument::DocAddSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const
598 : {
599 21 : nsDocument::DocAddSizeOfExcludingThis(aWindowSizes);
600 21 : }
601 :
602 : // nsIDOMDocument interface
603 :
604 : nsresult
605 0 : XMLDocument::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
606 : bool aPreallocateChildren) const
607 : {
608 0 : NS_ASSERTION(aNodeInfo->NodeInfoManager() == mNodeInfoManager,
609 : "Can't import this document into another document!");
610 :
611 0 : RefPtr<XMLDocument> clone = new XMLDocument();
612 0 : nsresult rv = CloneDocHelper(clone, aPreallocateChildren);
613 0 : NS_ENSURE_SUCCESS(rv, rv);
614 :
615 : // State from XMLDocument
616 0 : clone->mAsync = mAsync;
617 0 : clone->mIsPlainDocument = mIsPlainDocument;
618 :
619 0 : return CallQueryInterface(clone.get(), aResult);
620 : }
621 :
622 : JSObject*
623 0 : XMLDocument::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
624 : {
625 0 : if (mIsPlainDocument) {
626 0 : return DocumentBinding::Wrap(aCx, this, aGivenProto);
627 : }
628 :
629 0 : return XMLDocumentBinding::Wrap(aCx, this, aGivenProto);
630 : }
631 :
632 : } // namespace dom
633 : } // namespace mozilla
|