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 : #include "nsDOMSerializer.h"
8 :
9 : #include "mozilla/Encoding.h"
10 : #include "nsIDocument.h"
11 : #include "nsIDocumentEncoder.h"
12 : #include "nsIDOMDocument.h"
13 : #include "nsComponentManagerUtils.h"
14 : #include "nsContentCID.h"
15 : #include "nsContentUtils.h"
16 : #include "nsError.h"
17 : #include "nsINode.h"
18 :
19 : using namespace mozilla;
20 :
21 0 : nsDOMSerializer::nsDOMSerializer()
22 : {
23 0 : }
24 :
25 0 : nsDOMSerializer::~nsDOMSerializer()
26 : {
27 0 : }
28 :
29 : // QueryInterface implementation for nsDOMSerializer
30 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMSerializer)
31 0 : NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
32 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
33 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMSerializer)
34 0 : NS_INTERFACE_MAP_END
35 :
36 0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsDOMSerializer, mOwner)
37 :
38 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMSerializer)
39 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMSerializer)
40 :
41 :
42 : static nsresult
43 0 : SetUpEncoder(nsIDOMNode *aRoot, const nsACString& aCharset,
44 : nsIDocumentEncoder **aEncoder)
45 : {
46 0 : *aEncoder = nullptr;
47 :
48 : nsresult rv;
49 : nsCOMPtr<nsIDocumentEncoder> encoder =
50 0 : do_CreateInstance(NS_DOC_ENCODER_CONTRACTID_BASE "application/xhtml+xml", &rv);
51 0 : if (NS_FAILED(rv))
52 0 : return rv;
53 :
54 0 : bool entireDocument = true;
55 0 : nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(aRoot));
56 0 : if (!domDoc) {
57 0 : entireDocument = false;
58 0 : rv = aRoot->GetOwnerDocument(getter_AddRefs(domDoc));
59 0 : if (NS_FAILED(rv))
60 0 : return rv;
61 : }
62 :
63 : // This method will fail if no document
64 0 : rv = encoder->Init(domDoc, NS_LITERAL_STRING("application/xhtml+xml"),
65 : nsIDocumentEncoder::OutputRaw |
66 0 : nsIDocumentEncoder::OutputDontRewriteEncodingDeclaration);
67 :
68 0 : if (NS_FAILED(rv))
69 0 : return rv;
70 :
71 0 : nsAutoCString charset(aCharset);
72 0 : if (charset.IsEmpty()) {
73 0 : nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
74 0 : NS_ASSERTION(doc, "Need a document");
75 0 : doc->GetDocumentCharacterSet()->Name(charset);
76 : }
77 0 : rv = encoder->SetCharset(charset);
78 0 : if (NS_FAILED(rv))
79 0 : return rv;
80 :
81 : // If we are working on the entire document we do not need to
82 : // specify which part to serialize
83 0 : if (!entireDocument) {
84 0 : rv = encoder->SetNode(aRoot);
85 : }
86 :
87 0 : if (NS_SUCCEEDED(rv)) {
88 0 : encoder.forget(aEncoder);
89 : }
90 :
91 0 : return rv;
92 : }
93 :
94 : void
95 0 : nsDOMSerializer::SerializeToString(nsINode& aRoot, nsAString& aStr,
96 : ErrorResult& rv)
97 : {
98 0 : rv = nsDOMSerializer::SerializeToString(aRoot.AsDOMNode(), aStr);
99 0 : }
100 :
101 : NS_IMETHODIMP
102 0 : nsDOMSerializer::SerializeToString(nsIDOMNode *aRoot, nsAString& _retval)
103 : {
104 0 : NS_ENSURE_ARG_POINTER(aRoot);
105 :
106 0 : _retval.Truncate();
107 :
108 0 : if (!nsContentUtils::CanCallerAccess(aRoot)) {
109 0 : return NS_ERROR_DOM_SECURITY_ERR;
110 : }
111 :
112 0 : nsCOMPtr<nsIDocumentEncoder> encoder;
113 0 : nsresult rv = SetUpEncoder(aRoot, EmptyCString(), getter_AddRefs(encoder));
114 0 : if (NS_FAILED(rv))
115 0 : return rv;
116 :
117 0 : return encoder->EncodeToString(_retval);
118 : }
119 :
120 : void
121 0 : nsDOMSerializer::SerializeToStream(nsINode& aRoot, nsIOutputStream* aStream,
122 : const nsAString& aCharset, ErrorResult& rv)
123 : {
124 0 : rv = nsDOMSerializer::SerializeToStream(aRoot.AsDOMNode(), aStream,
125 0 : NS_ConvertUTF16toUTF8(aCharset));
126 0 : }
127 :
128 : NS_IMETHODIMP
129 0 : nsDOMSerializer::SerializeToStream(nsIDOMNode *aRoot,
130 : nsIOutputStream *aStream,
131 : const nsACString& aCharset)
132 : {
133 0 : NS_ENSURE_ARG_POINTER(aRoot);
134 0 : NS_ENSURE_ARG_POINTER(aStream);
135 : // The charset arg can be empty, in which case we get the document's
136 : // charset and use that when serializing.
137 :
138 0 : if (!nsContentUtils::CanCallerAccess(aRoot)) {
139 0 : return NS_ERROR_DOM_SECURITY_ERR;
140 : }
141 :
142 0 : nsCOMPtr<nsIDocumentEncoder> encoder;
143 0 : nsresult rv = SetUpEncoder(aRoot, aCharset, getter_AddRefs(encoder));
144 0 : if (NS_FAILED(rv))
145 0 : return rv;
146 :
147 0 : return encoder->EncodeToStream(aStream);
148 : }
|