1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Communicator client code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Pierre Phaneuf <pp@ludusdesign.com>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 :
40 : #include "nsXMLDocument.h"
41 : #include "nsParserCIID.h"
42 : #include "nsIParser.h"
43 : #include "nsIXMLContentSink.h"
44 : #include "nsPresContext.h"
45 : #include "nsIContent.h"
46 : #include "nsIContentViewerContainer.h"
47 : #include "nsIContentViewer.h"
48 : #include "nsIDocShell.h"
49 : #include "nsIMarkupDocumentViewer.h"
50 : #include "nsHTMLParts.h"
51 : #include "nsIComponentManager.h"
52 : #include "nsIDOMElement.h"
53 : #include "nsIBaseWindow.h"
54 : #include "nsIDOMWindow.h"
55 : #include "nsIDOMDocumentType.h"
56 : #include "nsINameSpaceManager.h"
57 : #include "nsCOMPtr.h"
58 : #include "nsXPIDLString.h"
59 : #include "nsIHttpChannel.h"
60 : #include "nsIURI.h"
61 : #include "nsIServiceManager.h"
62 : #include "nsNetUtil.h"
63 : #include "nsDOMError.h"
64 : #include "nsIScriptSecurityManager.h"
65 : #include "nsIPrincipal.h"
66 : #include "nsLayoutCID.h"
67 : #include "nsDOMAttribute.h"
68 : #include "nsGUIEvent.h"
69 : #include "nsCExternalHandlerService.h"
70 : #include "nsNetUtil.h"
71 : #include "nsMimeTypes.h"
72 : #include "nsEventListenerManager.h"
73 : #include "nsContentUtils.h"
74 : #include "nsThreadUtils.h"
75 : #include "nsJSUtils.h"
76 : #include "nsCRT.h"
77 : #include "nsIAuthPrompt.h"
78 : #include "nsIScriptGlobalObjectOwner.h"
79 : #include "nsIJSContextStack.h"
80 : #include "nsContentCreatorFunctions.h"
81 : #include "nsContentPolicyUtils.h"
82 : #include "nsContentErrors.h"
83 : #include "nsIDOMUserDataHandler.h"
84 : #include "nsEventDispatcher.h"
85 : #include "nsNodeUtils.h"
86 : #include "nsIConsoleService.h"
87 : #include "nsIScriptError.h"
88 : #include "nsIHTMLDocument.h"
89 : #include "nsGenericElement.h"
90 :
91 : // ==================================================================
92 : // =
93 : // ==================================================================
94 :
95 :
96 : nsresult
97 1273 : NS_NewDOMDocument(nsIDOMDocument** aInstancePtrResult,
98 : const nsAString& aNamespaceURI,
99 : const nsAString& aQualifiedName,
100 : nsIDOMDocumentType* aDoctype,
101 : nsIURI* aDocumentURI,
102 : nsIURI* aBaseURI,
103 : nsIPrincipal* aPrincipal,
104 : bool aLoadedAsData,
105 : nsIScriptGlobalObject* aEventObject,
106 : DocumentFlavor aFlavor)
107 : {
108 : // Note: can't require that aDocumentURI/aBaseURI/aPrincipal be non-null,
109 : // since at least one caller (XMLHttpRequest) doesn't have decent args to
110 : // pass in.
111 :
112 : nsresult rv;
113 :
114 1273 : *aInstancePtrResult = nsnull;
115 :
116 2546 : nsCOMPtr<nsIDocument> d;
117 1273 : bool isHTML = false;
118 1273 : bool isXHTML = false;
119 1273 : if (aFlavor == DocumentFlavorSVG) {
120 0 : rv = NS_NewSVGDocument(getter_AddRefs(d));
121 1273 : } else if (aFlavor == DocumentFlavorHTML) {
122 234 : rv = NS_NewHTMLDocument(getter_AddRefs(d));
123 234 : isHTML = true;
124 1039 : } else if (aDoctype) {
125 0 : nsAutoString publicId, name;
126 0 : aDoctype->GetPublicId(publicId);
127 0 : if (publicId.IsEmpty()) {
128 0 : aDoctype->GetName(name);
129 : }
130 0 : if (name.EqualsLiteral("html") ||
131 0 : publicId.EqualsLiteral("-//W3C//DTD HTML 4.01//EN") ||
132 0 : publicId.EqualsLiteral("-//W3C//DTD HTML 4.01 Frameset//EN") ||
133 0 : publicId.EqualsLiteral("-//W3C//DTD HTML 4.01 Transitional//EN") ||
134 0 : publicId.EqualsLiteral("-//W3C//DTD HTML 4.0//EN") ||
135 0 : publicId.EqualsLiteral("-//W3C//DTD HTML 4.0 Frameset//EN") ||
136 0 : publicId.EqualsLiteral("-//W3C//DTD HTML 4.0 Transitional//EN")) {
137 0 : rv = NS_NewHTMLDocument(getter_AddRefs(d));
138 0 : isHTML = true;
139 0 : } else if (publicId.EqualsLiteral("-//W3C//DTD XHTML 1.0 Strict//EN") ||
140 0 : publicId.EqualsLiteral("-//W3C//DTD XHTML 1.0 Transitional//EN") ||
141 0 : publicId.EqualsLiteral("-//W3C//DTD XHTML 1.0 Frameset//EN")) {
142 0 : rv = NS_NewHTMLDocument(getter_AddRefs(d));
143 0 : isHTML = true;
144 0 : isXHTML = true;
145 : }
146 0 : else if (publicId.EqualsLiteral("-//W3C//DTD SVG 1.1//EN")) {
147 0 : rv = NS_NewSVGDocument(getter_AddRefs(d));
148 : }
149 : // XXX Add support for XUL documents.
150 : else {
151 0 : rv = NS_NewXMLDocument(getter_AddRefs(d));
152 : }
153 : } else {
154 1039 : rv = NS_NewXMLDocument(getter_AddRefs(d));
155 : }
156 :
157 1273 : if (NS_FAILED(rv)) {
158 0 : return rv;
159 : }
160 :
161 1273 : d->SetScriptHandlingObject(aEventObject);
162 :
163 1273 : if (isHTML) {
164 468 : nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(d);
165 234 : NS_ASSERTION(htmlDoc, "HTML Document doesn't implement nsIHTMLDocument?");
166 234 : htmlDoc->SetCompatibilityMode(eCompatibility_FullStandards);
167 234 : htmlDoc->SetIsXHTML(isXHTML);
168 : }
169 1273 : nsDocument* doc = static_cast<nsDocument*>(d.get());
170 1273 : doc->SetLoadedAsData(aLoadedAsData);
171 1273 : doc->nsDocument::SetDocumentURI(aDocumentURI);
172 : // Must set the principal first, since SetBaseURI checks it.
173 1273 : doc->SetPrincipal(aPrincipal);
174 1273 : doc->SetBaseURI(aBaseURI);
175 :
176 : // XMLDocuments and documents "created in memory" get to be UTF-8 by default,
177 : // unlike the legacy HTML mess
178 1273 : doc->SetDocumentCharacterSet(NS_LITERAL_CSTRING("UTF-8"));
179 :
180 1273 : if (aDoctype) {
181 0 : nsCOMPtr<nsIDOMNode> tmpNode;
182 0 : rv = doc->AppendChild(aDoctype, getter_AddRefs(tmpNode));
183 0 : NS_ENSURE_SUCCESS(rv, rv);
184 : }
185 :
186 1273 : if (!aQualifiedName.IsEmpty()) {
187 2 : nsCOMPtr<nsIDOMElement> root;
188 : rv = doc->CreateElementNS(aNamespaceURI, aQualifiedName,
189 1 : getter_AddRefs(root));
190 1 : NS_ENSURE_SUCCESS(rv, rv);
191 :
192 2 : nsCOMPtr<nsIDOMNode> tmpNode;
193 :
194 1 : rv = doc->AppendChild(root, getter_AddRefs(tmpNode));
195 1 : NS_ENSURE_SUCCESS(rv, rv);
196 : }
197 :
198 1273 : *aInstancePtrResult = doc;
199 1273 : NS_ADDREF(*aInstancePtrResult);
200 :
201 1273 : return NS_OK;
202 : }
203 :
204 :
205 : nsresult
206 1039 : NS_NewXMLDocument(nsIDocument** aInstancePtrResult)
207 : {
208 1039 : nsXMLDocument* doc = new nsXMLDocument();
209 1039 : NS_ENSURE_TRUE(doc, NS_ERROR_OUT_OF_MEMORY);
210 :
211 1039 : NS_ADDREF(doc);
212 1039 : nsresult rv = doc->Init();
213 :
214 1039 : if (NS_FAILED(rv)) {
215 0 : NS_RELEASE(doc);
216 : }
217 :
218 1039 : *aInstancePtrResult = doc;
219 :
220 1039 : return rv;
221 : }
222 :
223 : nsresult
224 0 : NS_NewXBLDocument(nsIDOMDocument** aInstancePtrResult,
225 : nsIURI* aDocumentURI,
226 : nsIURI* aBaseURI,
227 : nsIPrincipal* aPrincipal)
228 : {
229 : nsresult rv = NS_NewDOMDocument(aInstancePtrResult,
230 0 : NS_LITERAL_STRING("http://www.mozilla.org/xbl"),
231 0 : NS_LITERAL_STRING("bindings"), nsnull,
232 : aDocumentURI, aBaseURI, aPrincipal, false,
233 0 : nsnull, DocumentFlavorLegacyGuess);
234 0 : NS_ENSURE_SUCCESS(rv, rv);
235 :
236 0 : nsCOMPtr<nsIDocument> idoc = do_QueryInterface(*aInstancePtrResult);
237 0 : nsDocument* doc = static_cast<nsDocument*>(idoc.get());
238 0 : doc->SetLoadedAsInteractiveData(true);
239 0 : doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
240 :
241 0 : return NS_OK;
242 : }
243 :
244 : // NOTE! nsDocument::operator new() zeroes out all members, so don't
245 : // bother initializing members to 0.
246 :
247 1039 : nsXMLDocument::nsXMLDocument(const char* aContentType)
248 : : nsDocument(aContentType),
249 1039 : mAsync(true)
250 : {
251 :
252 : // NOTE! nsDocument::operator new() zeroes out all members, so don't
253 : // bother initializing members to 0.
254 1039 : }
255 :
256 3111 : nsXMLDocument::~nsXMLDocument()
257 : {
258 : // XXX We rather crash than hang
259 1037 : mLoopingForSyncLoad = false;
260 2074 : }
261 :
262 393 : DOMCI_NODE_DATA(XMLDocument, nsXMLDocument)
263 :
264 : // QueryInterface implementation for nsXMLDocument
265 212308 : NS_INTERFACE_TABLE_HEAD(nsXMLDocument)
266 : NS_DOCUMENT_INTERFACE_TABLE_BEGIN(nsXMLDocument)
267 : NS_INTERFACE_TABLE_ENTRY(nsXMLDocument, nsIDOMXMLDocument)
268 212308 : NS_OFFSET_AND_INTERFACE_TABLE_END
269 212266 : NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
270 149356 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XMLDocument)
271 148787 : NS_INTERFACE_MAP_END_INHERITING(nsDocument)
272 :
273 :
274 160115 : NS_IMPL_ADDREF_INHERITED(nsXMLDocument, nsDocument)
275 160111 : NS_IMPL_RELEASE_INHERITED(nsXMLDocument, nsDocument)
276 :
277 :
278 : nsresult
279 1039 : nsXMLDocument::Init()
280 : {
281 1039 : nsresult rv = nsDocument::Init();
282 1039 : NS_ENSURE_SUCCESS(rv, rv);
283 :
284 1039 : return rv;
285 : }
286 :
287 : void
288 469 : nsXMLDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup)
289 : {
290 469 : nsDocument::Reset(aChannel, aLoadGroup);
291 469 : }
292 :
293 : void
294 469 : nsXMLDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
295 : nsIPrincipal* aPrincipal)
296 : {
297 469 : if (mChannelIsPending) {
298 0 : StopDocumentLoad();
299 0 : mChannel->Cancel(NS_BINDING_ABORTED);
300 0 : mChannelIsPending = nsnull;
301 : }
302 :
303 469 : nsDocument::ResetToURI(aURI, aLoadGroup, aPrincipal);
304 469 : }
305 :
306 : NS_IMETHODIMP
307 0 : nsXMLDocument::GetAsync(bool *aAsync)
308 : {
309 0 : NS_ENSURE_ARG_POINTER(aAsync);
310 0 : *aAsync = mAsync;
311 0 : return NS_OK;
312 : }
313 :
314 : NS_IMETHODIMP
315 0 : nsXMLDocument::SetAsync(bool aAsync)
316 : {
317 0 : mAsync = aAsync;
318 0 : return NS_OK;
319 : }
320 :
321 : static void
322 0 : ReportUseOfDeprecatedMethod(nsIDocument *aDoc, const char* aWarning)
323 : {
324 : nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
325 : "DOM3 Load", aDoc,
326 : nsContentUtils::eDOM_PROPERTIES,
327 0 : aWarning);
328 0 : }
329 :
330 : NS_IMETHODIMP
331 0 : nsXMLDocument::Load(const nsAString& aUrl, bool *aReturn)
332 : {
333 0 : bool hasHadScriptObject = true;
334 : nsIScriptGlobalObject* scriptObject =
335 0 : GetScriptHandlingObject(hasHadScriptObject);
336 0 : NS_ENSURE_STATE(scriptObject || !hasHadScriptObject);
337 :
338 0 : ReportUseOfDeprecatedMethod(this, "UseOfDOM3LoadMethodWarning");
339 :
340 0 : NS_ENSURE_ARG_POINTER(aReturn);
341 0 : *aReturn = false;
342 :
343 : nsCOMPtr<nsIDocument> callingDoc =
344 0 : do_QueryInterface(nsContentUtils::GetDocumentFromContext());
345 :
346 0 : nsIURI *baseURI = mDocumentURI;
347 0 : nsCAutoString charset;
348 :
349 0 : if (callingDoc) {
350 0 : baseURI = callingDoc->GetDocBaseURI();
351 0 : charset = callingDoc->GetDocumentCharacterSet();
352 : }
353 :
354 : // Create a new URI
355 0 : nsCOMPtr<nsIURI> uri;
356 0 : nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl, charset.get(), baseURI);
357 0 : if (NS_FAILED(rv)) {
358 0 : return rv;
359 : }
360 :
361 : // Check to see whether the current document is allowed to load this URI.
362 : // It's important to use the current document's principal for this check so
363 : // that we don't end up in a case where code with elevated privileges is
364 : // calling us and changing the principal of this document.
365 :
366 : // Enforce same-origin even for chrome loaders to avoid someone accidentally
367 : // using a document that content has a reference to and turn that into a
368 : // chrome document.
369 0 : nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
370 0 : if (!nsContentUtils::IsSystemPrincipal(principal)) {
371 0 : rv = principal->CheckMayLoad(uri, false);
372 0 : NS_ENSURE_SUCCESS(rv, rv);
373 :
374 0 : PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
375 : rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_XMLHTTPREQUEST,
376 : uri,
377 : principal,
378 : callingDoc ? callingDoc.get() :
379 0 : static_cast<nsIDocument*>(this),
380 0 : NS_LITERAL_CSTRING("application/xml"),
381 : nsnull,
382 : &shouldLoad,
383 : nsContentUtils::GetContentPolicy(),
384 0 : nsContentUtils::GetSecurityManager());
385 0 : NS_ENSURE_SUCCESS(rv, rv);
386 0 : if (NS_CP_REJECTED(shouldLoad)) {
387 0 : return NS_ERROR_CONTENT_BLOCKED;
388 : }
389 : } else {
390 : // We're called from chrome, check to make sure the URI we're
391 : // about to load is also chrome.
392 :
393 0 : bool isChrome = false;
394 0 : if (NS_FAILED(uri->SchemeIs("chrome", &isChrome)) || !isChrome) {
395 0 : nsCAutoString spec;
396 0 : if (mDocumentURI)
397 0 : mDocumentURI->GetSpec(spec);
398 :
399 0 : nsAutoString error;
400 : error.AssignLiteral("Cross site loading using document.load is no "
401 0 : "longer supported. Use XMLHttpRequest instead.");
402 : nsCOMPtr<nsIScriptError> errorObject =
403 0 : do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
404 0 : NS_ENSURE_SUCCESS(rv, rv);
405 :
406 0 : rv = errorObject->InitWithWindowID(error.get(), NS_ConvertUTF8toUTF16(spec).get(),
407 : nsnull, 0, 0, nsIScriptError::warningFlag,
408 : "DOM",
409 : callingDoc ?
410 0 : callingDoc->InnerWindowID() :
411 0 : this->InnerWindowID());
412 :
413 0 : NS_ENSURE_SUCCESS(rv, rv);
414 :
415 : nsCOMPtr<nsIConsoleService> consoleService =
416 0 : do_GetService(NS_CONSOLESERVICE_CONTRACTID);
417 0 : if (consoleService) {
418 0 : consoleService->LogMessage(errorObject);
419 : }
420 :
421 0 : return NS_ERROR_DOM_SECURITY_ERR;
422 : }
423 : }
424 :
425 : // Partial Reset, need to restore principal for security reasons and
426 : // event listener manager so that load listeners etc. will
427 : // remain. This should be done before the security check is done to
428 : // ensure that the document is reset even if the new document can't
429 : // be loaded. Note that we need to hold a strong ref to |principal|
430 : // here, because ResetToURI will null out our node principal before
431 : // setting the new one.
432 0 : nsRefPtr<nsEventListenerManager> elm(mListenerManager);
433 0 : mListenerManager = nsnull;
434 :
435 : // When we are called from JS we can find the load group for the page,
436 : // and add ourselves to it. This way any pending requests
437 : // will be automatically aborted if the user leaves the page.
438 :
439 0 : nsCOMPtr<nsILoadGroup> loadGroup;
440 0 : if (callingDoc) {
441 0 : loadGroup = callingDoc->GetDocumentLoadGroup();
442 : }
443 :
444 0 : ResetToURI(uri, loadGroup, principal);
445 :
446 0 : mListenerManager = elm;
447 :
448 : // Create a channel
449 0 : nsCOMPtr<nsIInterfaceRequestor> req = nsContentUtils::GetSameOriginChecker();
450 0 : NS_ENSURE_TRUE(req, NS_ERROR_OUT_OF_MEMORY);
451 :
452 0 : nsCOMPtr<nsIChannel> channel;
453 : // nsIRequest::LOAD_BACKGROUND prevents throbber from becoming active,
454 : // which in turn keeps STOP button from becoming active
455 0 : rv = NS_NewChannel(getter_AddRefs(channel), uri, nsnull, loadGroup, req,
456 0 : nsIRequest::LOAD_BACKGROUND);
457 0 : if (NS_FAILED(rv)) {
458 0 : return rv;
459 : }
460 :
461 : // Prepare for loading the XML document "into oneself"
462 0 : nsCOMPtr<nsIStreamListener> listener;
463 0 : if (NS_FAILED(rv = StartDocumentLoad(kLoadAsData, channel,
464 : loadGroup, nsnull,
465 : getter_AddRefs(listener),
466 : false))) {
467 0 : NS_ERROR("nsXMLDocument::Load: Failed to start the document load.");
468 0 : return rv;
469 : }
470 :
471 : // After this point, if we error out of this method we should clear
472 : // mChannelIsPending.
473 :
474 : // Start an asynchronous read of the XML document
475 0 : rv = channel->AsyncOpen(listener, nsnull);
476 0 : if (NS_FAILED(rv)) {
477 0 : mChannelIsPending = false;
478 0 : return rv;
479 : }
480 :
481 0 : if (!mAsync) {
482 0 : nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
483 :
484 0 : mLoopingForSyncLoad = true;
485 0 : while (mLoopingForSyncLoad) {
486 0 : if (!NS_ProcessNextEvent(thread))
487 0 : break;
488 : }
489 :
490 : // We set return to true unless there was a parsing error
491 0 : nsCOMPtr<nsIDOMNode> node = do_QueryInterface(GetRootElement());
492 0 : if (node) {
493 0 : nsAutoString name, ns;
494 0 : if (NS_SUCCEEDED(node->GetLocalName(name)) &&
495 0 : name.EqualsLiteral("parsererror") &&
496 0 : NS_SUCCEEDED(node->GetNamespaceURI(ns)) &&
497 0 : ns.EqualsLiteral("http://www.mozilla.org/newlayout/xml/parsererror.xml")) {
498 : //return is already false
499 : } else {
500 0 : *aReturn = true;
501 : }
502 : }
503 : } else {
504 0 : *aReturn = true;
505 : }
506 :
507 0 : return NS_OK;
508 : }
509 :
510 : nsresult
511 1038 : nsXMLDocument::StartDocumentLoad(const char* aCommand,
512 : nsIChannel* aChannel,
513 : nsILoadGroup* aLoadGroup,
514 : nsISupports* aContainer,
515 : nsIStreamListener **aDocListener,
516 : bool aReset,
517 : nsIContentSink* aSink)
518 : {
519 : nsresult rv = nsDocument::StartDocumentLoad(aCommand,
520 : aChannel, aLoadGroup,
521 : aContainer,
522 1038 : aDocListener, aReset, aSink);
523 1038 : if (NS_FAILED(rv)) return rv;
524 :
525 1038 : if (nsCRT::strcmp("loadAsInteractiveData", aCommand) == 0) {
526 0 : mLoadedAsInteractiveData = true;
527 0 : aCommand = kLoadAsData; // XBL, for example, needs scripts and styles
528 : }
529 :
530 :
531 1038 : PRInt32 charsetSource = kCharsetFromDocTypeDefault;
532 2076 : nsCAutoString charset(NS_LITERAL_CSTRING("UTF-8"));
533 1038 : TryChannelCharset(aChannel, charsetSource, charset);
534 :
535 2076 : nsCOMPtr<nsIURI> aUrl;
536 1038 : rv = aChannel->GetURI(getter_AddRefs(aUrl));
537 1038 : if (NS_FAILED(rv)) return rv;
538 :
539 : static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
540 :
541 1038 : mParser = do_CreateInstance(kCParserCID, &rv);
542 1038 : NS_ENSURE_SUCCESS(rv, rv);
543 :
544 2076 : nsCOMPtr<nsIXMLContentSink> sink;
545 :
546 1038 : if (aSink) {
547 0 : sink = do_QueryInterface(aSink);
548 : }
549 : else {
550 2076 : nsCOMPtr<nsIDocShell> docShell;
551 1038 : if (aContainer) {
552 0 : docShell = do_QueryInterface(aContainer);
553 0 : NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
554 : }
555 1038 : rv = NS_NewXMLContentSink(getter_AddRefs(sink), this, aUrl, docShell,
556 1038 : aChannel);
557 1038 : NS_ENSURE_SUCCESS(rv, rv);
558 : }
559 :
560 : // Set the parser as the stream listener for the document loader...
561 1038 : rv = CallQueryInterface(mParser, aDocListener);
562 1038 : NS_ENSURE_SUCCESS(rv, rv);
563 :
564 1038 : NS_ASSERTION(mChannel, "How can we not have a channel here?");
565 1038 : mChannelIsPending = true;
566 :
567 1038 : SetDocumentCharacterSet(charset);
568 1038 : mParser->SetDocumentCharset(charset, charsetSource);
569 1038 : mParser->SetCommand(aCommand);
570 1038 : mParser->SetContentSink(sink);
571 1038 : mParser->Parse(aUrl, nsnull, (void *)this);
572 :
573 1038 : return NS_OK;
574 : }
575 :
576 : void
577 1038 : nsXMLDocument::EndLoad()
578 : {
579 1038 : mChannelIsPending = false;
580 1038 : mLoopingForSyncLoad = false;
581 :
582 1038 : mSynchronousDOMContentLoaded = (mLoadedAsData || mLoadedAsInteractiveData);
583 1038 : nsDocument::EndLoad();
584 1038 : if (mSynchronousDOMContentLoaded) {
585 1038 : mSynchronousDOMContentLoaded = false;
586 1038 : nsDocument::SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
587 : // Generate a document load event for the case when an XML
588 : // document was loaded as pure data without any presentation
589 : // attached to it.
590 2076 : nsEvent event(true, NS_LOAD);
591 : nsEventDispatcher::Dispatch(static_cast<nsIDocument*>(this), nsnull,
592 1038 : &event);
593 : }
594 1038 : }
595 :
596 : /* virtual */ void
597 0 : nsXMLDocument::DocSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const
598 : {
599 0 : nsDocument::DocSizeOfExcludingThis(aWindowSizes);
600 0 : }
601 :
602 : // nsIDOMDocument interface
603 :
604 : nsresult
605 0 : nsXMLDocument::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
606 : {
607 0 : NS_ASSERTION(aNodeInfo->NodeInfoManager() == mNodeInfoManager,
608 : "Can't import this document into another document!");
609 :
610 0 : nsRefPtr<nsXMLDocument> clone = new nsXMLDocument();
611 0 : NS_ENSURE_TRUE(clone, NS_ERROR_OUT_OF_MEMORY);
612 0 : nsresult rv = CloneDocHelper(clone);
613 0 : NS_ENSURE_SUCCESS(rv, rv);
614 :
615 : // State from nsXMLDocument
616 0 : clone->mAsync = mAsync;
617 :
618 0 : return CallQueryInterface(clone.get(), aResult);
619 : }
|