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 "txInstructions.h"
11 #include "nsGkAtoms.h"
12 #include "nsIConsoleService.h"
13 #include "nsServiceManagerUtils.h"
14 #include "txExecutionState.h"
16 #include "txNodeSetContext.h"
17 #include "txNodeSorter.h"
18 #include "txRtfHandler.h"
19 #include "txStringUtils.h"
20 #include "txStylesheet.h"
21 #include "txTextHandler.h"
22 #include "txXSLTNumber.h"
24 using mozilla::MakeUnique
;
25 using mozilla::UniquePtr
;
27 nsresult
txApplyDefaultElementTemplate::execute(txExecutionState
& aEs
) {
28 txExecutionState::TemplateRule
* rule
= aEs
.getCurrentTemplateRule();
29 txExpandedName
mode(rule
->mModeNsId
, rule
->mModeLocalName
);
30 txStylesheet::ImportFrame
* frame
= 0;
33 aEs
.mStylesheet
->findTemplate(aEs
.getEvalContext()->getContextNode(),
34 mode
, &aEs
, nullptr, &templ
, &frame
);
35 NS_ENSURE_SUCCESS(rv
, rv
);
37 aEs
.pushTemplateRule(frame
, mode
, aEs
.mTemplateParams
);
39 return aEs
.runTemplate(templ
);
42 nsresult
txApplyImportsEnd::execute(txExecutionState
& aEs
) {
43 aEs
.popTemplateRule();
44 RefPtr
<txParameterMap
> paramMap
= aEs
.popParamMap();
49 nsresult
txApplyImportsStart::execute(txExecutionState
& aEs
) {
50 txExecutionState::TemplateRule
* rule
= aEs
.getCurrentTemplateRule();
51 // The frame is set to null when there is no current template rule, or
52 // when the current template rule is a default template. However this
53 // instruction isn't used in default templates.
55 // XXX ErrorReport: apply-imports instantiated without a current rule
56 return NS_ERROR_XSLT_EXECUTION_FAILURE
;
59 aEs
.pushParamMap(rule
->mParams
);
61 txStylesheet::ImportFrame
* frame
= 0;
62 txExpandedName
mode(rule
->mModeNsId
, rule
->mModeLocalName
);
65 aEs
.mStylesheet
->findTemplate(aEs
.getEvalContext()->getContextNode(),
66 mode
, &aEs
, rule
->mFrame
, &templ
, &frame
);
67 NS_ENSURE_SUCCESS(rv
, rv
);
69 aEs
.pushTemplateRule(frame
, mode
, rule
->mParams
);
71 rv
= aEs
.runTemplate(templ
);
73 aEs
.popTemplateRule();
79 txApplyTemplates::txApplyTemplates(const txExpandedName
& aMode
)
82 nsresult
txApplyTemplates::execute(txExecutionState
& aEs
) {
83 txStylesheet::ImportFrame
* frame
= 0;
86 aEs
.mStylesheet
->findTemplate(aEs
.getEvalContext()->getContextNode(),
87 mMode
, &aEs
, nullptr, &templ
, &frame
);
88 NS_ENSURE_SUCCESS(rv
, rv
);
90 aEs
.pushTemplateRule(frame
, mMode
, aEs
.mTemplateParams
);
92 return aEs
.runTemplate(templ
);
95 txAttribute::txAttribute(UniquePtr
<Expr
>&& aName
, UniquePtr
<Expr
>&& aNamespace
,
96 txNamespaceMap
* aMappings
)
97 : mName(std::move(aName
)),
98 mNamespace(std::move(aNamespace
)),
99 mMappings(aMappings
) {}
101 nsresult
txAttribute::execute(txExecutionState
& aEs
) {
102 UniquePtr
<txTextHandler
> handler(
103 static_cast<txTextHandler
*>(aEs
.popResultHandler()));
106 nsresult rv
= mName
->evaluateToString(aEs
.getEvalContext(), name
);
107 NS_ENSURE_SUCCESS(rv
, rv
);
109 const char16_t
* colon
;
110 if (!XMLUtils::isValidQName(name
, &colon
) ||
111 TX_StringEqualsAtom(name
, nsGkAtoms::xmlns
)) {
115 RefPtr
<nsAtom
> prefix
;
116 uint32_t lnameStart
= 0;
118 prefix
= NS_Atomize(Substring(name
.get(), colon
));
119 lnameStart
= colon
- name
.get() + 1;
122 int32_t nsId
= kNameSpaceID_None
;
125 rv
= mNamespace
->evaluateToString(aEs
.getEvalContext(), nspace
);
126 NS_ENSURE_SUCCESS(rv
, rv
);
128 if (!nspace
.IsEmpty()) {
129 nsId
= txNamespaceManager::getNamespaceID(nspace
);
132 nsId
= mMappings
->lookupNamespace(prefix
);
135 // add attribute if everything was ok
136 return nsId
!= kNameSpaceID_Unknown
137 ? aEs
.mResultHandler
->attribute(
138 prefix
, Substring(name
, lnameStart
), nsId
, handler
->mValue
)
142 txCallTemplate::txCallTemplate(const txExpandedName
& aName
) : mName(aName
) {}
144 nsresult
txCallTemplate::execute(txExecutionState
& aEs
) {
145 txInstruction
* instr
= aEs
.mStylesheet
->getNamedTemplate(mName
);
146 NS_ENSURE_TRUE(instr
, NS_ERROR_XSLT_EXECUTION_FAILURE
);
148 nsresult rv
= aEs
.runTemplate(instr
);
149 NS_ENSURE_SUCCESS(rv
, rv
);
154 txCheckParam::txCheckParam(const txExpandedName
& aName
)
155 : mName(aName
), mBailTarget(nullptr) {}
157 nsresult
txCheckParam::execute(txExecutionState
& aEs
) {
159 if (aEs
.mTemplateParams
) {
160 RefPtr
<txAExprResult
> exprRes
;
161 aEs
.mTemplateParams
->getVariable(mName
, getter_AddRefs(exprRes
));
163 rv
= aEs
.bindVariable(mName
, exprRes
);
164 NS_ENSURE_SUCCESS(rv
, rv
);
166 aEs
.gotoInstruction(mBailTarget
);
173 txConditionalGoto::txConditionalGoto(UniquePtr
<Expr
>&& aCondition
,
174 txInstruction
* aTarget
)
175 : mCondition(std::move(aCondition
)), mTarget(aTarget
) {}
177 nsresult
txConditionalGoto::execute(txExecutionState
& aEs
) {
179 nsresult rv
= mCondition
->evaluateToBool(aEs
.getEvalContext(), exprRes
);
180 NS_ENSURE_SUCCESS(rv
, rv
);
183 aEs
.gotoInstruction(mTarget
);
189 nsresult
txComment::execute(txExecutionState
& aEs
) {
190 UniquePtr
<txTextHandler
> handler(
191 static_cast<txTextHandler
*>(aEs
.popResultHandler()));
192 uint32_t length
= handler
->mValue
.Length();
194 while ((pos
= handler
->mValue
.FindChar('-', (uint32_t)pos
)) != kNotFound
) {
196 if ((uint32_t)pos
== length
|| handler
->mValue
.CharAt(pos
) == '-') {
197 handler
->mValue
.Insert(char16_t(' '), pos
++);
202 return aEs
.mResultHandler
->comment(handler
->mValue
);
205 nsresult
txCopyBase::copyNode(const txXPathNode
& aNode
, txExecutionState
& aEs
) {
206 switch (txXPathNodeUtils::getNodeType(aNode
)) {
207 case txXPathNodeType::ATTRIBUTE_NODE
: {
208 nsAutoString nodeValue
;
209 txXPathNodeUtils::appendNodeValue(aNode
, nodeValue
);
211 RefPtr
<nsAtom
> localName
= txXPathNodeUtils::getLocalName(aNode
);
212 return aEs
.mResultHandler
->attribute(
213 txXPathNodeUtils::getPrefix(aNode
), localName
, nullptr,
214 txXPathNodeUtils::getNamespaceID(aNode
), nodeValue
);
216 case txXPathNodeType::COMMENT_NODE
: {
217 nsAutoString nodeValue
;
218 txXPathNodeUtils::appendNodeValue(aNode
, nodeValue
);
219 return aEs
.mResultHandler
->comment(nodeValue
);
221 case txXPathNodeType::DOCUMENT_NODE
:
222 case txXPathNodeType::DOCUMENT_FRAGMENT_NODE
: {
224 txXPathTreeWalker
walker(aNode
);
225 bool hasChild
= walker
.moveToFirstChild();
227 copyNode(walker
.getCurrentPosition(), aEs
);
228 hasChild
= walker
.moveToNextSibling();
232 case txXPathNodeType::ELEMENT_NODE
: {
233 RefPtr
<nsAtom
> localName
= txXPathNodeUtils::getLocalName(aNode
);
234 nsresult rv
= aEs
.mResultHandler
->startElement(
235 txXPathNodeUtils::getPrefix(aNode
), localName
, nullptr,
236 txXPathNodeUtils::getNamespaceID(aNode
));
237 NS_ENSURE_SUCCESS(rv
, rv
);
240 txXPathTreeWalker
walker(aNode
);
241 if (walker
.moveToFirstAttribute()) {
243 nsAutoString nodeValue
;
244 walker
.appendNodeValue(nodeValue
);
246 const txXPathNode
& attr
= walker
.getCurrentPosition();
247 localName
= txXPathNodeUtils::getLocalName(attr
);
248 rv
= aEs
.mResultHandler
->attribute(
249 txXPathNodeUtils::getPrefix(attr
), localName
, nullptr,
250 txXPathNodeUtils::getNamespaceID(attr
), nodeValue
);
251 NS_ENSURE_SUCCESS(rv
, rv
);
252 } while (walker
.moveToNextAttribute());
253 walker
.moveToParent();
257 bool hasChild
= walker
.moveToFirstChild();
259 copyNode(walker
.getCurrentPosition(), aEs
);
260 hasChild
= walker
.moveToNextSibling();
263 return aEs
.mResultHandler
->endElement();
265 case txXPathNodeType::PROCESSING_INSTRUCTION_NODE
: {
266 nsAutoString target
, data
;
267 txXPathNodeUtils::getNodeName(aNode
, target
);
268 txXPathNodeUtils::appendNodeValue(aNode
, data
);
269 return aEs
.mResultHandler
->processingInstruction(target
, data
);
271 case txXPathNodeType::TEXT_NODE
:
272 case txXPathNodeType::CDATA_SECTION_NODE
: {
273 nsAutoString nodeValue
;
274 txXPathNodeUtils::appendNodeValue(aNode
, nodeValue
);
275 return aEs
.mResultHandler
->characters(nodeValue
, false);
282 txCopy::txCopy() : mBailTarget(nullptr) {}
284 nsresult
txCopy::execute(txExecutionState
& aEs
) {
286 const txXPathNode
& node
= aEs
.getEvalContext()->getContextNode();
288 switch (txXPathNodeUtils::getNodeType(node
)) {
289 case txXPathNodeType::DOCUMENT_NODE
:
290 case txXPathNodeType::DOCUMENT_FRAGMENT_NODE
: {
291 // "close" current element to ensure that no attributes are added
292 rv
= aEs
.mResultHandler
->characters(u
""_ns
, false);
293 NS_ENSURE_SUCCESS(rv
, rv
);
299 case txXPathNodeType::ELEMENT_NODE
: {
300 RefPtr
<nsAtom
> localName
= txXPathNodeUtils::getLocalName(node
);
301 rv
= aEs
.mResultHandler
->startElement(
302 txXPathNodeUtils::getPrefix(node
), localName
, nullptr,
303 txXPathNodeUtils::getNamespaceID(node
));
304 NS_ENSURE_SUCCESS(rv
, rv
);
306 // XXX copy namespace nodes once we have them
313 rv
= copyNode(node
, aEs
);
314 NS_ENSURE_SUCCESS(rv
, rv
);
316 aEs
.gotoInstruction(mBailTarget
);
323 txCopyOf::txCopyOf(UniquePtr
<Expr
>&& aSelect
) : mSelect(std::move(aSelect
)) {}
325 nsresult
txCopyOf::execute(txExecutionState
& aEs
) {
326 RefPtr
<txAExprResult
> exprRes
;
328 mSelect
->evaluate(aEs
.getEvalContext(), getter_AddRefs(exprRes
));
329 NS_ENSURE_SUCCESS(rv
, rv
);
331 switch (exprRes
->getResultType()) {
332 case txAExprResult::NODESET
: {
334 static_cast<txNodeSet
*>(static_cast<txAExprResult
*>(exprRes
));
336 for (i
= 0; i
< nodes
->size(); ++i
) {
337 rv
= copyNode(nodes
->get(i
), aEs
);
338 NS_ENSURE_SUCCESS(rv
, rv
);
342 case txAExprResult::RESULT_TREE_FRAGMENT
: {
343 txResultTreeFragment
* rtf
= static_cast<txResultTreeFragment
*>(
344 static_cast<txAExprResult
*>(exprRes
));
345 return rtf
->flushToHandler(aEs
.mResultHandler
);
349 exprRes
->stringValue(value
);
350 if (!value
.IsEmpty()) {
351 return aEs
.mResultHandler
->characters(value
, false);
360 nsresult
txEndElement::execute(txExecutionState
& aEs
) {
361 // This will return false if startElement was not called. This happens
362 // when <xsl:element> produces a bad name, or when <xsl:copy> copies a
365 return aEs
.mResultHandler
->endElement();
371 nsresult
txErrorInstruction::execute(txExecutionState
& aEs
) {
372 // XXX ErrorReport: unknown instruction executed
373 return NS_ERROR_XSLT_EXECUTION_FAILURE
;
376 txGoTo::txGoTo(txInstruction
* aTarget
) : mTarget(aTarget
) {}
378 nsresult
txGoTo::execute(txExecutionState
& aEs
) {
379 aEs
.gotoInstruction(mTarget
);
384 txInsertAttrSet::txInsertAttrSet(const txExpandedName
& aName
) : mName(aName
) {}
386 nsresult
txInsertAttrSet::execute(txExecutionState
& aEs
) {
387 txInstruction
* instr
= aEs
.mStylesheet
->getAttributeSet(mName
);
388 NS_ENSURE_TRUE(instr
, NS_ERROR_XSLT_EXECUTION_FAILURE
);
390 nsresult rv
= aEs
.runTemplate(instr
);
391 NS_ENSURE_SUCCESS(rv
, rv
);
396 txLoopNodeSet::txLoopNodeSet(txInstruction
* aTarget
) : mTarget(aTarget
) {}
398 nsresult
txLoopNodeSet::execute(txExecutionState
& aEs
) {
399 aEs
.popTemplateRule();
400 txNodeSetContext
* context
=
401 static_cast<txNodeSetContext
*>(aEs
.getEvalContext());
402 if (!context
->hasNext()) {
403 delete aEs
.popEvalContext();
409 aEs
.gotoInstruction(mTarget
);
414 txLREAttribute::txLREAttribute(int32_t aNamespaceID
, nsAtom
* aLocalName
,
415 nsAtom
* aPrefix
, UniquePtr
<Expr
>&& aValue
)
416 : mNamespaceID(aNamespaceID
),
417 mLocalName(aLocalName
),
419 mValue(std::move(aValue
)) {
420 if (aNamespaceID
== kNameSpaceID_None
) {
421 mLowercaseLocalName
= TX_ToLowerCaseAtom(aLocalName
);
425 nsresult
txLREAttribute::execute(txExecutionState
& aEs
) {
426 RefPtr
<txAExprResult
> exprRes
;
427 nsresult rv
= mValue
->evaluate(aEs
.getEvalContext(), getter_AddRefs(exprRes
));
428 NS_ENSURE_SUCCESS(rv
, rv
);
430 const nsString
* value
= exprRes
->stringValuePointer();
432 return aEs
.mResultHandler
->attribute(
433 mPrefix
, mLocalName
, mLowercaseLocalName
, mNamespaceID
, *value
);
436 nsAutoString valueStr
;
437 exprRes
->stringValue(valueStr
);
438 return aEs
.mResultHandler
->attribute(mPrefix
, mLocalName
, mLowercaseLocalName
,
439 mNamespaceID
, valueStr
);
442 txMessage::txMessage(bool aTerminate
) : mTerminate(aTerminate
) {}
444 nsresult
txMessage::execute(txExecutionState
& aEs
) {
445 UniquePtr
<txTextHandler
> handler(
446 static_cast<txTextHandler
*>(aEs
.popResultHandler()));
448 nsCOMPtr
<nsIConsoleService
> consoleSvc
=
449 do_GetService("@mozilla.org/consoleservice;1");
451 nsAutoString
logString(u
"xsl:message - "_ns
);
452 logString
.Append(handler
->mValue
);
453 consoleSvc
->LogStringMessage(logString
.get());
456 return mTerminate
? NS_ERROR_XSLT_ABORTED
: NS_OK
;
459 txNumber::txNumber(txXSLTNumber::LevelType aLevel
,
460 UniquePtr
<txPattern
>&& aCount
, UniquePtr
<txPattern
>&& aFrom
,
461 UniquePtr
<Expr
>&& aValue
, UniquePtr
<Expr
>&& aFormat
,
462 UniquePtr
<Expr
>&& aGroupingSeparator
,
463 UniquePtr
<Expr
>&& aGroupingSize
)
465 mCount(std::move(aCount
)),
466 mFrom(std::move(aFrom
)),
467 mValue(std::move(aValue
)),
468 mFormat(std::move(aFormat
)),
469 mGroupingSeparator(std::move(aGroupingSeparator
)),
470 mGroupingSize(std::move(aGroupingSize
)) {}
472 nsresult
txNumber::execute(txExecutionState
& aEs
) {
474 nsresult rv
= txXSLTNumber::createNumber(
475 mValue
.get(), mCount
.get(), mFrom
.get(), mLevel
, mGroupingSize
.get(),
476 mGroupingSeparator
.get(), mFormat
.get(), aEs
.getEvalContext(), res
);
477 NS_ENSURE_SUCCESS(rv
, rv
);
479 return aEs
.mResultHandler
->characters(res
, false);
482 nsresult
txPopParams::execute(txExecutionState
& aEs
) {
483 RefPtr
<txParameterMap
> paramMap
= aEs
.popParamMap();
488 txProcessingInstruction::txProcessingInstruction(UniquePtr
<Expr
>&& aName
)
489 : mName(std::move(aName
)) {}
491 nsresult
txProcessingInstruction::execute(txExecutionState
& aEs
) {
492 UniquePtr
<txTextHandler
> handler(
493 static_cast<txTextHandler
*>(aEs
.popResultHandler()));
494 XMLUtils::normalizePIValue(handler
->mValue
);
497 nsresult rv
= mName
->evaluateToString(aEs
.getEvalContext(), name
);
498 NS_ENSURE_SUCCESS(rv
, rv
);
500 // Check name validity (must be valid NCName and a PITarget)
501 // XXX Need to check for NCName and PITarget
502 const char16_t
* colon
;
503 if (!XMLUtils::isValidQName(name
, &colon
)) {
504 // XXX ErrorReport: bad PI-target
505 return NS_ERROR_FAILURE
;
508 return aEs
.mResultHandler
->processingInstruction(name
, handler
->mValue
);
511 txPushNewContext::txPushNewContext(UniquePtr
<Expr
>&& aSelect
)
512 : mSelect(std::move(aSelect
)), mBailTarget(nullptr) {}
514 txPushNewContext::~txPushNewContext() = default;
516 nsresult
txPushNewContext::execute(txExecutionState
& aEs
) {
517 RefPtr
<txAExprResult
> exprRes
;
519 mSelect
->evaluate(aEs
.getEvalContext(), getter_AddRefs(exprRes
));
520 NS_ENSURE_SUCCESS(rv
, rv
);
522 if (exprRes
->getResultType() != txAExprResult::NODESET
) {
523 // XXX ErrorReport: nodeset expected
524 return NS_ERROR_XSLT_NODESET_EXPECTED
;
528 static_cast<txNodeSet
*>(static_cast<txAExprResult
*>(exprRes
));
530 if (nodes
->isEmpty()) {
531 aEs
.gotoInstruction(mBailTarget
);
537 uint32_t i
, count
= mSortKeys
.Length();
538 for (i
= 0; i
< count
; ++i
) {
539 SortKey
& sort
= mSortKeys
[i
];
540 rv
= sorter
.addSortElement(sort
.mSelectExpr
.get(), sort
.mLangExpr
.get(),
541 sort
.mDataTypeExpr
.get(), sort
.mOrderExpr
.get(),
542 sort
.mCaseOrderExpr
.get(), aEs
.getEvalContext());
543 NS_ENSURE_SUCCESS(rv
, rv
);
545 RefPtr
<txNodeSet
> sortedNodes
;
546 rv
= sorter
.sortNodeSet(nodes
, &aEs
, getter_AddRefs(sortedNodes
));
547 NS_ENSURE_SUCCESS(rv
, rv
);
549 auto context
= MakeUnique
<txNodeSetContext
>(sortedNodes
, &aEs
);
552 aEs
.pushEvalContext(context
.release());
557 void txPushNewContext::addSort(UniquePtr
<Expr
>&& aSelectExpr
,
558 UniquePtr
<Expr
>&& aLangExpr
,
559 UniquePtr
<Expr
>&& aDataTypeExpr
,
560 UniquePtr
<Expr
>&& aOrderExpr
,
561 UniquePtr
<Expr
>&& aCaseOrderExpr
) {
562 SortKey
* key
= mSortKeys
.AppendElement();
563 // workaround for not triggering the Copy Constructor
564 key
->mSelectExpr
= std::move(aSelectExpr
);
565 key
->mLangExpr
= std::move(aLangExpr
);
566 key
->mDataTypeExpr
= std::move(aDataTypeExpr
);
567 key
->mOrderExpr
= std::move(aOrderExpr
);
568 key
->mCaseOrderExpr
= std::move(aCaseOrderExpr
);
571 nsresult
txPushNullTemplateRule::execute(txExecutionState
& aEs
) {
572 aEs
.pushTemplateRule(nullptr, txExpandedName(), nullptr);
576 nsresult
txPushParams::execute(txExecutionState
& aEs
) {
577 aEs
.pushParamMap(nullptr);
581 nsresult
txPushRTFHandler::execute(txExecutionState
& aEs
) {
582 aEs
.pushResultHandler(new txRtfHandler
);
587 txPushStringHandler::txPushStringHandler(bool aOnlyText
)
588 : mOnlyText(aOnlyText
) {}
590 nsresult
txPushStringHandler::execute(txExecutionState
& aEs
) {
591 aEs
.pushResultHandler(new txTextHandler(mOnlyText
));
596 txRemoveVariable::txRemoveVariable(const txExpandedName
& aName
)
599 nsresult
txRemoveVariable::execute(txExecutionState
& aEs
) {
600 aEs
.removeVariable(mName
);
605 nsresult
txReturn::execute(txExecutionState
& aEs
) {
606 NS_ASSERTION(!mNext
, "instructions exist after txReturn");
607 aEs
.returnFromTemplate();
612 txSetParam::txSetParam(const txExpandedName
& aName
, UniquePtr
<Expr
>&& aValue
)
613 : mName(aName
), mValue(std::move(aValue
)) {}
615 nsresult
txSetParam::execute(txExecutionState
& aEs
) {
617 if (!aEs
.mTemplateParams
) {
618 aEs
.mTemplateParams
= new txParameterMap
;
621 RefPtr
<txAExprResult
> exprRes
;
623 rv
= mValue
->evaluate(aEs
.getEvalContext(), getter_AddRefs(exprRes
));
624 NS_ENSURE_SUCCESS(rv
, rv
);
626 UniquePtr
<txRtfHandler
> rtfHandler(
627 static_cast<txRtfHandler
*>(aEs
.popResultHandler()));
628 rv
= rtfHandler
->getAsRTF(getter_AddRefs(exprRes
));
629 NS_ENSURE_SUCCESS(rv
, rv
);
632 rv
= aEs
.mTemplateParams
->bindVariable(mName
, exprRes
);
633 NS_ENSURE_SUCCESS(rv
, rv
);
638 txSetVariable::txSetVariable(const txExpandedName
& aName
,
639 UniquePtr
<Expr
>&& aValue
)
640 : mName(aName
), mValue(std::move(aValue
)) {}
642 nsresult
txSetVariable::execute(txExecutionState
& aEs
) {
644 RefPtr
<txAExprResult
> exprRes
;
646 rv
= mValue
->evaluate(aEs
.getEvalContext(), getter_AddRefs(exprRes
));
647 NS_ENSURE_SUCCESS(rv
, rv
);
649 UniquePtr
<txRtfHandler
> rtfHandler(
650 static_cast<txRtfHandler
*>(aEs
.popResultHandler()));
651 rv
= rtfHandler
->getAsRTF(getter_AddRefs(exprRes
));
652 NS_ENSURE_SUCCESS(rv
, rv
);
655 return aEs
.bindVariable(mName
, exprRes
);
658 txStartElement::txStartElement(UniquePtr
<Expr
>&& aName
,
659 UniquePtr
<Expr
>&& aNamespace
,
660 txNamespaceMap
* aMappings
)
661 : mName(std::move(aName
)),
662 mNamespace(std::move(aNamespace
)),
663 mMappings(aMappings
) {}
665 nsresult
txStartElement::execute(txExecutionState
& aEs
) {
667 nsresult rv
= mName
->evaluateToString(aEs
.getEvalContext(), name
);
668 NS_ENSURE_SUCCESS(rv
, rv
);
670 int32_t nsId
= kNameSpaceID_None
;
671 RefPtr
<nsAtom
> prefix
;
672 uint32_t lnameStart
= 0;
674 const char16_t
* colon
;
675 if (XMLUtils::isValidQName(name
, &colon
)) {
677 prefix
= NS_Atomize(Substring(name
.get(), colon
));
678 lnameStart
= colon
- name
.get() + 1;
683 rv
= mNamespace
->evaluateToString(aEs
.getEvalContext(), nspace
);
684 NS_ENSURE_SUCCESS(rv
, rv
);
686 if (!nspace
.IsEmpty()) {
687 nsId
= txNamespaceManager::getNamespaceID(nspace
);
690 nsId
= mMappings
->lookupNamespace(prefix
);
693 nsId
= kNameSpaceID_Unknown
;
698 if (nsId
!= kNameSpaceID_Unknown
) {
699 rv
= aEs
.mResultHandler
->startElement(prefix
, Substring(name
, lnameStart
),
702 rv
= NS_ERROR_XSLT_BAD_NODE_NAME
;
705 if (rv
== NS_ERROR_XSLT_BAD_NODE_NAME
) {
707 // we call characters with an empty string to "close" any element to
708 // make sure that no attributes are added
709 rv
= aEs
.mResultHandler
->characters(u
""_ns
, false);
711 NS_ENSURE_SUCCESS(rv
, rv
);
713 aEs
.pushBool(success
);
718 txStartLREElement::txStartLREElement(int32_t aNamespaceID
, nsAtom
* aLocalName
,
720 : mNamespaceID(aNamespaceID
), mLocalName(aLocalName
), mPrefix(aPrefix
) {
721 if (aNamespaceID
== kNameSpaceID_None
) {
722 mLowercaseLocalName
= TX_ToLowerCaseAtom(aLocalName
);
726 nsresult
txStartLREElement::execute(txExecutionState
& aEs
) {
727 nsresult rv
= aEs
.mResultHandler
->startElement(
728 mPrefix
, mLocalName
, mLowercaseLocalName
, mNamespaceID
);
729 NS_ENSURE_SUCCESS(rv
, rv
);
736 txText::txText(const nsAString
& aStr
, bool aDOE
) : mStr(aStr
), mDOE(aDOE
) {}
738 nsresult
txText::execute(txExecutionState
& aEs
) {
739 return aEs
.mResultHandler
->characters(mStr
, mDOE
);
742 txValueOf::txValueOf(UniquePtr
<Expr
>&& aExpr
, bool aDOE
)
743 : mExpr(std::move(aExpr
)), mDOE(aDOE
) {}
745 nsresult
txValueOf::execute(txExecutionState
& aEs
) {
746 RefPtr
<txAExprResult
> exprRes
;
747 nsresult rv
= mExpr
->evaluate(aEs
.getEvalContext(), getter_AddRefs(exprRes
));
748 NS_ENSURE_SUCCESS(rv
, rv
);
750 const nsString
* value
= exprRes
->stringValuePointer();
752 if (!value
->IsEmpty()) {
753 return aEs
.mResultHandler
->characters(*value
, mDOE
);
756 nsAutoString valueStr
;
757 exprRes
->stringValue(valueStr
);
758 if (!valueStr
.IsEmpty()) {
759 return aEs
.mResultHandler
->characters(valueStr
, mDOE
);