Bug 1874684 - Part 4: Prefer const references instead of copying Instant values....
[gecko.git] / dom / xslt / xslt / txUnknownHandler.cpp
blob7f13418941fb3234f81ea7ba490c42fdce72fea4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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/. */
6 #include "txUnknownHandler.h"
8 #include <utility>
10 #include "mozilla/UniquePtrExtensions.h"
11 #include "nsGkAtoms.h"
12 #include "txExecutionState.h"
13 #include "txStringUtils.h"
14 #include "txStylesheet.h"
16 using mozilla::UniquePtr;
17 using mozilla::WrapUnique;
19 txUnknownHandler::txUnknownHandler(txExecutionState* aEs)
20 : mEs(aEs), mFlushed(false) {
21 MOZ_COUNT_CTOR_INHERITED(txUnknownHandler, txBufferingHandler);
24 txUnknownHandler::~txUnknownHandler() {
25 MOZ_COUNT_DTOR_INHERITED(txUnknownHandler, txBufferingHandler);
28 nsresult txUnknownHandler::attribute(nsAtom* aPrefix, nsAtom* aLocalName,
29 nsAtom* aLowercaseLocalName, int32_t aNsID,
30 const nsString& aValue) {
31 return mFlushed
32 ? mEs->mResultHandler->attribute(
33 aPrefix, aLocalName, aLowercaseLocalName, aNsID, aValue)
34 : txBufferingHandler::attribute(
35 aPrefix, aLocalName, aLowercaseLocalName, aNsID, aValue);
38 nsresult txUnknownHandler::attribute(nsAtom* aPrefix,
39 const nsAString& aLocalName,
40 const int32_t aNsID,
41 const nsString& aValue) {
42 return mFlushed ? mEs->mResultHandler->attribute(aPrefix, aLocalName, aNsID,
43 aValue)
44 : txBufferingHandler::attribute(aPrefix, aLocalName, aNsID,
45 aValue);
48 nsresult txUnknownHandler::characters(const nsAString& aData, bool aDOE) {
49 return mFlushed ? mEs->mResultHandler->characters(aData, aDOE)
50 : txBufferingHandler::characters(aData, aDOE);
53 nsresult txUnknownHandler::comment(const nsString& aData) {
54 return mFlushed ? mEs->mResultHandler->comment(aData)
55 : txBufferingHandler::comment(aData);
58 nsresult txUnknownHandler::endDocument(nsresult aResult) {
59 if (!mFlushed) {
60 if (NS_FAILED(aResult)) {
61 return NS_OK;
64 // This is an unusual case, no output method has been set and we
65 // didn't create a document element. Switching to XML output mode
66 // anyway.
68 // Make sure that mEs->mResultHandler == this is true, otherwise we'll
69 // leak mEs->mResultHandler in createHandlerAndFlush.
70 NS_ASSERTION(mEs->mResultHandler == this,
71 "We're leaking mEs->mResultHandler.");
73 nsresult rv = createHandlerAndFlush(false, u""_ns, kNameSpaceID_None);
74 NS_ENSURE_SUCCESS(rv, rv);
77 return mEs->mResultHandler->endDocument(aResult);
80 nsresult txUnknownHandler::endElement() {
81 return mFlushed ? mEs->mResultHandler->endElement()
82 : txBufferingHandler::endElement();
85 nsresult txUnknownHandler::processingInstruction(const nsString& aTarget,
86 const nsString& aData) {
87 return mFlushed ? mEs->mResultHandler->processingInstruction(aTarget, aData)
88 : txBufferingHandler::processingInstruction(aTarget, aData);
91 nsresult txUnknownHandler::startDocument() {
92 return mFlushed ? mEs->mResultHandler->startDocument()
93 : txBufferingHandler::startDocument();
96 nsresult txUnknownHandler::startElement(nsAtom* aPrefix, nsAtom* aLocalName,
97 nsAtom* aLowercaseLocalName,
98 int32_t aNsID) {
99 if (!mFlushed) {
100 // Make sure that mEs->mResultHandler == this is true, otherwise we'll
101 // leak mEs->mResultHandler in createHandlerAndFlush.
102 NS_ASSERTION(mEs->mResultHandler == this,
103 "We're leaking mEs->mResultHandler.");
105 RefPtr<nsAtom> owner;
106 if (!aLowercaseLocalName) {
107 owner = TX_ToLowerCaseAtom(aLocalName);
108 NS_ENSURE_TRUE(owner, NS_ERROR_OUT_OF_MEMORY);
110 aLowercaseLocalName = owner;
113 bool htmlRoot = aNsID == kNameSpaceID_None && !aPrefix &&
114 aLowercaseLocalName == nsGkAtoms::html;
116 // Use aLocalName and not aLowercaseLocalName in case the output
117 // handler cares about case. For eHTMLOutput the handler will hardcode
118 // to 'html' anyway.
119 nsresult rv = createHandlerAndFlush(
120 htmlRoot, nsDependentAtomString(aLocalName), aNsID);
121 NS_ENSURE_SUCCESS(rv, rv);
124 return mEs->mResultHandler->startElement(aPrefix, aLocalName,
125 aLowercaseLocalName, aNsID);
128 nsresult txUnknownHandler::startElement(nsAtom* aPrefix,
129 const nsAString& aLocalName,
130 const int32_t aNsID) {
131 if (!mFlushed) {
132 // Make sure that mEs->mResultHandler == this is true, otherwise we'll
133 // leak mEs->mResultHandler in createHandlerAndFlush.
134 NS_ASSERTION(mEs->mResultHandler == this,
135 "We're leaking mEs->mResultHandler.");
137 bool htmlRoot =
138 aNsID == kNameSpaceID_None && !aPrefix &&
139 aLocalName.Equals(u"html"_ns, nsCaseInsensitiveStringComparator);
140 nsresult rv = createHandlerAndFlush(htmlRoot, aLocalName, aNsID);
141 NS_ENSURE_SUCCESS(rv, rv);
144 return mEs->mResultHandler->startElement(aPrefix, aLocalName, aNsID);
147 nsresult txUnknownHandler::createHandlerAndFlush(bool aHTMLRoot,
148 const nsAString& aName,
149 const int32_t aNsID) {
150 NS_ENSURE_TRUE(mBuffer, NS_ERROR_NOT_INITIALIZED);
152 txOutputFormat format;
153 format.merge(*(mEs->mStylesheet->getOutputFormat()));
154 if (format.mMethod == eMethodNotSet) {
155 format.mMethod = aHTMLRoot ? eHTMLOutput : eXMLOutput;
158 UniquePtr<txAXMLEventHandler> handler;
159 nsresult rv = mEs->mOutputHandlerFactory->createHandlerWith(
160 &format, aName, aNsID, getter_Transfers(handler));
161 NS_ENSURE_SUCCESS(rv, rv);
163 mEs->mOutputHandler = handler.get();
164 mEs->mResultHandler = handler.release();
165 // Let the executionstate delete us. We need to stay alive because we might
166 // need to forward hooks to mEs->mResultHandler if someone is currently
167 // flushing a buffer to mEs->mResultHandler.
168 mEs->mObsoleteHandler = WrapUnique(this);
170 mFlushed = true;
172 // Let go of out buffer as soon as we're done flushing it, we're not going
173 // to need it anymore from this point on (all hooks get forwarded to
174 // mEs->mResultHandler.
175 UniquePtr<txResultBuffer> buffer(std::move(mBuffer));
176 return buffer->flushToHandler(mEs->mResultHandler);