Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "txMozillaTextOutput.h"
7 : #include "nsContentCID.h"
8 : #include "nsIContent.h"
9 : #include "nsIDocument.h"
10 : #include "nsIDOMDocument.h"
11 : #include "nsIDOMDocumentFragment.h"
12 : #include "nsIDocumentTransformer.h"
13 : #include "nsCharsetSource.h"
14 : #include "nsIPrincipal.h"
15 : #include "txURIUtils.h"
16 : #include "nsContentCreatorFunctions.h"
17 : #include "nsContentUtils.h"
18 : #include "nsGkAtoms.h"
19 : #include "mozilla/Encoding.h"
20 : #include "nsTextNode.h"
21 : #include "nsNameSpaceManager.h"
22 :
23 : using namespace mozilla::dom;
24 :
25 0 : txMozillaTextOutput::txMozillaTextOutput(nsITransformObserver* aObserver)
26 : {
27 0 : MOZ_COUNT_CTOR(txMozillaTextOutput);
28 0 : mObserver = do_GetWeakReference(aObserver);
29 0 : }
30 :
31 0 : txMozillaTextOutput::txMozillaTextOutput(nsIDOMDocumentFragment* aDest)
32 : {
33 0 : MOZ_COUNT_CTOR(txMozillaTextOutput);
34 0 : mTextParent = do_QueryInterface(aDest);
35 0 : mDocument = mTextParent->OwnerDoc();
36 0 : }
37 :
38 0 : txMozillaTextOutput::~txMozillaTextOutput()
39 : {
40 0 : MOZ_COUNT_DTOR(txMozillaTextOutput);
41 0 : }
42 :
43 : nsresult
44 0 : txMozillaTextOutput::attribute(nsIAtom* aPrefix, nsIAtom* aLocalName,
45 : nsIAtom* aLowercaseLocalName,
46 : int32_t aNsID, const nsString& aValue)
47 : {
48 0 : return NS_OK;
49 : }
50 :
51 : nsresult
52 0 : txMozillaTextOutput::attribute(nsIAtom* aPrefix, const nsAString& aName,
53 : const int32_t aNsID,
54 : const nsString& aValue)
55 : {
56 0 : return NS_OK;
57 : }
58 :
59 : nsresult
60 0 : txMozillaTextOutput::characters(const nsAString& aData, bool aDOE)
61 : {
62 0 : mText.Append(aData);
63 :
64 0 : return NS_OK;
65 : }
66 :
67 : nsresult
68 0 : txMozillaTextOutput::comment(const nsString& aData)
69 : {
70 0 : return NS_OK;
71 : }
72 :
73 : nsresult
74 0 : txMozillaTextOutput::endDocument(nsresult aResult)
75 : {
76 0 : NS_ENSURE_TRUE(mDocument && mTextParent, NS_ERROR_FAILURE);
77 :
78 0 : RefPtr<nsTextNode> text = new nsTextNode(mDocument->NodeInfoManager());
79 :
80 0 : text->SetText(mText, false);
81 0 : nsresult rv = mTextParent->AppendChildTo(text, true);
82 0 : NS_ENSURE_SUCCESS(rv, rv);
83 :
84 : // This should really be handled by nsIDocument::EndLoad
85 0 : MOZ_ASSERT(mDocument->GetReadyStateEnum() ==
86 : nsIDocument::READYSTATE_LOADING, "Bad readyState");
87 0 : mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);
88 :
89 0 : if (NS_SUCCEEDED(aResult)) {
90 0 : nsCOMPtr<nsITransformObserver> observer = do_QueryReferent(mObserver);
91 0 : if (observer) {
92 0 : observer->OnTransformDone(aResult, mDocument);
93 : }
94 : }
95 :
96 0 : return NS_OK;
97 : }
98 :
99 : nsresult
100 0 : txMozillaTextOutput::endElement()
101 : {
102 0 : return NS_OK;
103 : }
104 :
105 : nsresult
106 0 : txMozillaTextOutput::processingInstruction(const nsString& aTarget,
107 : const nsString& aData)
108 : {
109 0 : return NS_OK;
110 : }
111 :
112 : nsresult
113 0 : txMozillaTextOutput::startDocument()
114 : {
115 0 : return NS_OK;
116 : }
117 :
118 : nsresult
119 0 : txMozillaTextOutput::createResultDocument(nsIDOMDocument* aSourceDocument,
120 : bool aLoadedAsData)
121 : {
122 : /*
123 : * Create an XHTML document to hold the text.
124 : *
125 : * <html>
126 : * <head />
127 : * <body>
128 : * <pre id="transformiixResult"> * The text comes here * </pre>
129 : * <body>
130 : * </html>
131 : *
132 : * Except if we are transforming into a non-displayed document we create
133 : * the following DOM
134 : *
135 : * <transformiix:result> * The text comes here * </transformiix:result>
136 : */
137 :
138 : // Create the document
139 0 : nsresult rv = NS_NewXMLDocument(getter_AddRefs(mDocument),
140 0 : aLoadedAsData);
141 0 : NS_ENSURE_SUCCESS(rv, rv);
142 : // This should really be handled by nsIDocument::BeginLoad
143 0 : MOZ_ASSERT(mDocument->GetReadyStateEnum() ==
144 : nsIDocument::READYSTATE_UNINITIALIZED, "Bad readyState");
145 0 : mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_LOADING);
146 0 : nsCOMPtr<nsIDocument> source = do_QueryInterface(aSourceDocument);
147 0 : NS_ENSURE_STATE(source);
148 0 : bool hasHadScriptObject = false;
149 : nsIScriptGlobalObject* sgo =
150 0 : source->GetScriptHandlingObject(hasHadScriptObject);
151 0 : NS_ENSURE_STATE(sgo || !hasHadScriptObject);
152 :
153 0 : NS_ASSERTION(mDocument, "Need document");
154 :
155 : // Reset and set up document
156 0 : URIUtils::ResetWithSource(mDocument, aSourceDocument);
157 : // Only do this after resetting the document to ensure we have the
158 : // correct principal.
159 0 : mDocument->SetScriptHandlingObject(sgo);
160 :
161 : // Set the charset
162 0 : if (!mOutputFormat.mEncoding.IsEmpty()) {
163 0 : const Encoding* encoding = Encoding::ForLabel(mOutputFormat.mEncoding);
164 0 : if (encoding) {
165 0 : mDocument->SetDocumentCharacterSetSource(kCharsetFromOtherComponent);
166 0 : mDocument->SetDocumentCharacterSet(WrapNotNull(encoding));
167 : }
168 : }
169 :
170 : // Notify the contentsink that the document is created
171 0 : nsCOMPtr<nsITransformObserver> observer = do_QueryReferent(mObserver);
172 0 : if (observer) {
173 0 : rv = observer->OnDocumentCreated(mDocument);
174 0 : NS_ENSURE_SUCCESS(rv, rv);
175 : }
176 :
177 : // Create the content
178 :
179 : // When transforming into a non-displayed document (i.e. when there is no
180 : // observer) we only create a transformiix:result root element.
181 0 : if (!observer) {
182 : int32_t namespaceID;
183 : rv = nsContentUtils::NameSpaceManager()->
184 0 : RegisterNameSpace(NS_LITERAL_STRING(kTXNameSpaceURI), namespaceID);
185 0 : NS_ENSURE_SUCCESS(rv, rv);
186 :
187 : mTextParent =
188 0 : mDocument->CreateElem(nsDependentAtomString(nsGkAtoms::result),
189 0 : nsGkAtoms::transformiix, namespaceID);
190 :
191 :
192 0 : rv = mDocument->AppendChildTo(mTextParent, true);
193 0 : NS_ENSURE_SUCCESS(rv, rv);
194 : }
195 : else {
196 0 : nsCOMPtr<nsIContent> html, head, body;
197 0 : rv = createXHTMLElement(nsGkAtoms::html, getter_AddRefs(html));
198 0 : NS_ENSURE_SUCCESS(rv, rv);
199 :
200 0 : rv = createXHTMLElement(nsGkAtoms::head, getter_AddRefs(head));
201 0 : NS_ENSURE_SUCCESS(rv, rv);
202 :
203 0 : rv = html->AppendChildTo(head, false);
204 0 : NS_ENSURE_SUCCESS(rv, rv);
205 :
206 0 : rv = createXHTMLElement(nsGkAtoms::body, getter_AddRefs(body));
207 0 : NS_ENSURE_SUCCESS(rv, rv);
208 :
209 0 : rv = html->AppendChildTo(body, false);
210 0 : NS_ENSURE_SUCCESS(rv, rv);
211 :
212 0 : rv = createXHTMLElement(nsGkAtoms::pre, getter_AddRefs(mTextParent));
213 0 : NS_ENSURE_SUCCESS(rv, rv);
214 :
215 0 : rv = mTextParent->SetAttr(kNameSpaceID_None, nsGkAtoms::id,
216 0 : NS_LITERAL_STRING("transformiixResult"),
217 0 : false);
218 0 : NS_ENSURE_SUCCESS(rv, rv);
219 :
220 0 : rv = body->AppendChildTo(mTextParent, false);
221 0 : NS_ENSURE_SUCCESS(rv, rv);
222 :
223 0 : rv = mDocument->AppendChildTo(html, true);
224 0 : NS_ENSURE_SUCCESS(rv, rv);
225 : }
226 :
227 0 : return NS_OK;
228 : }
229 :
230 : nsresult
231 0 : txMozillaTextOutput::startElement(nsIAtom* aPrefix, nsIAtom* aLocalName,
232 : nsIAtom* aLowercaseLocalName, int32_t aNsID)
233 : {
234 0 : return NS_OK;
235 : }
236 :
237 : nsresult
238 0 : txMozillaTextOutput::startElement(nsIAtom* aPrefix, const nsAString& aName,
239 : const int32_t aNsID)
240 : {
241 0 : return NS_OK;
242 : }
243 :
244 0 : void txMozillaTextOutput::getOutputDocument(nsIDOMDocument** aDocument)
245 : {
246 0 : CallQueryInterface(mDocument, aDocument);
247 0 : }
248 :
249 : nsresult
250 0 : txMozillaTextOutput::createXHTMLElement(nsIAtom* aName,
251 : nsIContent** aResult)
252 : {
253 0 : nsCOMPtr<Element> element = mDocument->CreateHTMLElement(aName);
254 0 : element.forget(aResult);
255 0 : return NS_OK;
256 : }
|