Coverage Report

Created: 2018-09-25 14:53

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