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 "txStylesheetCompileHandlers.h"
10 #include "mozilla/ArrayUtils.h"
11 #include "mozilla/FloatingPoint.h"
12 #include "mozilla/UniquePtrExtensions.h"
13 #include "nsGkAtoms.h"
14 #include "nsWhitespaceTokenizer.h"
16 #include "txInstructions.h"
17 #include "txNamespaceMap.h"
18 #include "txPatternParser.h"
19 #include "txStringUtils.h"
20 #include "txStylesheet.h"
21 #include "txStylesheetCompiler.h"
22 #include "txToplevelItems.h"
23 #include "txURIUtils.h"
24 #include "txXSLTFunctions.h"
25 #include "nsStringFlags.h"
26 #include "nsStyleUtil.h"
27 #include "nsStringIterator.h"
29 using namespace mozilla
;
31 txHandlerTable
* gTxIgnoreHandler
= 0;
32 txHandlerTable
* gTxRootHandler
= 0;
33 txHandlerTable
* gTxEmbedHandler
= 0;
34 txHandlerTable
* gTxTopHandler
= 0;
35 txHandlerTable
* gTxTemplateHandler
= 0;
36 txHandlerTable
* gTxTextHandler
= 0;
37 txHandlerTable
* gTxApplyTemplatesHandler
= 0;
38 txHandlerTable
* gTxCallTemplateHandler
= 0;
39 txHandlerTable
* gTxVariableHandler
= 0;
40 txHandlerTable
* gTxForEachHandler
= 0;
41 txHandlerTable
* gTxTopVariableHandler
= 0;
42 txHandlerTable
* gTxChooseHandler
= 0;
43 txHandlerTable
* gTxParamHandler
= 0;
44 txHandlerTable
* gTxImportHandler
= 0;
45 txHandlerTable
* gTxAttributeSetHandler
= 0;
46 txHandlerTable
* gTxFallbackHandler
= 0;
48 static nsresult
txFnStartLRE(int32_t aNamespaceID
, nsAtom
* aLocalName
,
49 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
51 txStylesheetCompilerState
& aState
);
52 static void txFnEndLRE(txStylesheetCompilerState
& aState
);
54 #define TX_RETURN_IF_WHITESPACE(_str, _state) \
56 if (!_state.mElementContext->mPreserveWhitespace && \
57 XMLUtils::isWhitespace(_str)) { \
62 static nsresult
getStyleAttr(txStylesheetAttr
* aAttributes
, int32_t aAttrCount
,
63 int32_t aNamespace
, nsAtom
* aName
, bool aRequired
,
64 txStylesheetAttr
** aAttr
) {
66 for (i
= 0; i
< aAttrCount
; ++i
) {
67 txStylesheetAttr
* attr
= aAttributes
+ i
;
68 if (attr
->mNamespaceID
== aNamespace
&& attr
->mLocalName
== aName
) {
69 attr
->mLocalName
= nullptr;
78 // XXX ErrorReport: missing required attribute
79 return NS_ERROR_XSLT_PARSE_FAILURE
;
85 static nsresult
parseUseAttrSets(txStylesheetAttr
* aAttributes
,
86 int32_t aAttrCount
, bool aInXSLTNS
,
87 txStylesheetCompilerState
& aState
) {
88 txStylesheetAttr
* attr
= nullptr;
89 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
,
90 aInXSLTNS
? kNameSpaceID_XSLT
: kNameSpaceID_None
,
91 nsGkAtoms::useAttributeSets
, false, &attr
);
96 nsWhitespaceTokenizer
tok(attr
->mValue
);
97 while (tok
.hasMoreTokens()) {
99 rv
= name
.init(tok
.nextToken(), aState
.mElementContext
->mMappings
, false);
100 NS_ENSURE_SUCCESS(rv
, rv
);
102 aState
.addInstruction(MakeUnique
<txInsertAttrSet
>(name
));
107 static nsresult
parseExcludeResultPrefixes(txStylesheetAttr
* aAttributes
,
109 int32_t aNamespaceID
) {
110 txStylesheetAttr
* attr
= nullptr;
111 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, aNamespaceID
,
112 nsGkAtoms::excludeResultPrefixes
, false, &attr
);
117 // XXX Needs to be implemented.
122 static nsresult
getQNameAttr(txStylesheetAttr
* aAttributes
, int32_t aAttrCount
,
123 nsAtom
* aName
, bool aRequired
,
124 txStylesheetCompilerState
& aState
,
125 txExpandedName
& aExpName
) {
127 txStylesheetAttr
* attr
= nullptr;
128 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
, aName
,
134 rv
= aExpName
.init(attr
->mValue
, aState
.mElementContext
->mMappings
, false);
135 if (!aRequired
&& NS_FAILED(rv
) && aState
.fcp()) {
143 static nsresult
getExprAttr(txStylesheetAttr
* aAttributes
, int32_t aAttrCount
,
144 nsAtom
* aName
, bool aRequired
,
145 txStylesheetCompilerState
& aState
,
146 UniquePtr
<Expr
>& aExpr
) {
148 txStylesheetAttr
* attr
= nullptr;
149 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
, aName
,
155 rv
= txExprParser::createExpr(attr
->mValue
, &aState
, getter_Transfers(aExpr
));
156 if (NS_FAILED(rv
) && aState
.ignoreError(rv
)) {
157 // use default value in fcp for not required exprs
159 aExpr
= MakeUnique
<txErrorExpr
>(
173 static nsresult
getAVTAttr(txStylesheetAttr
* aAttributes
, int32_t aAttrCount
,
174 nsAtom
* aName
, bool aRequired
,
175 txStylesheetCompilerState
& aState
,
176 UniquePtr
<Expr
>& aAVT
) {
178 txStylesheetAttr
* attr
= nullptr;
179 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
, aName
,
185 rv
= txExprParser::createAVT(attr
->mValue
, &aState
, getter_Transfers(aAVT
));
186 if (NS_FAILED(rv
) && aState
.fcp()) {
187 // use default value in fcp for not required exprs
189 aAVT
= MakeUnique
<txErrorExpr
>(
203 static nsresult
getPatternAttr(txStylesheetAttr
* aAttributes
,
204 int32_t aAttrCount
, nsAtom
* aName
,
206 txStylesheetCompilerState
& aState
,
207 UniquePtr
<txPattern
>& aPattern
) {
209 txStylesheetAttr
* attr
= nullptr;
210 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
, aName
,
216 rv
= txPatternParser::createPattern(attr
->mValue
, &aState
,
217 getter_Transfers(aPattern
));
218 if (NS_FAILED(rv
) && (aRequired
|| !aState
.ignoreError(rv
))) {
219 // XXX ErrorReport: XSLT-Pattern parse failure
226 static nsresult
getNumberAttr(txStylesheetAttr
* aAttributes
, int32_t aAttrCount
,
227 nsAtom
* aName
, bool aRequired
,
228 txStylesheetCompilerState
& aState
,
230 aNumber
= UnspecifiedNaN
<double>();
231 txStylesheetAttr
* attr
= nullptr;
232 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
, aName
,
238 aNumber
= txDouble::toDouble(attr
->mValue
);
239 if (std::isnan(aNumber
) && (aRequired
|| !aState
.fcp())) {
240 // XXX ErrorReport: number parse failure
241 return NS_ERROR_XSLT_PARSE_FAILURE
;
247 static nsresult
getAtomAttr(txStylesheetAttr
* aAttributes
, int32_t aAttrCount
,
248 nsAtom
* aName
, bool aRequired
,
249 txStylesheetCompilerState
& aState
, nsAtom
** aAtom
) {
251 txStylesheetAttr
* attr
= nullptr;
252 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
, aName
,
258 *aAtom
= NS_Atomize(attr
->mValue
).take();
259 NS_ENSURE_TRUE(*aAtom
, NS_ERROR_OUT_OF_MEMORY
);
264 static nsresult
getYesNoAttr(txStylesheetAttr
* aAttributes
, int32_t aAttrCount
,
265 nsAtom
* aName
, bool aRequired
,
266 txStylesheetCompilerState
& aState
,
267 txThreeState
& aRes
) {
270 nsresult rv
= getAtomAttr(aAttributes
, aAttrCount
, aName
, aRequired
, aState
,
271 getter_AddRefs(atom
));
276 if (atom
== nsGkAtoms::yes
) {
278 } else if (atom
== nsGkAtoms::no
) {
280 } else if (aRequired
|| !aState
.fcp()) {
281 // XXX ErrorReport: unknown values
282 return NS_ERROR_XSLT_PARSE_FAILURE
;
288 static nsresult
getCharAttr(txStylesheetAttr
* aAttributes
, int32_t aAttrCount
,
289 nsAtom
* aName
, bool aRequired
,
290 txStylesheetCompilerState
& aState
,
292 // Don't reset aChar since it contains the default value
293 txStylesheetAttr
* attr
= nullptr;
294 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
, aName
,
300 if (attr
->mValue
.Length() == 1) {
301 aChar
= attr
->mValue
.CharAt(0);
302 } else if (aRequired
|| !aState
.fcp()) {
303 // XXX ErrorReport: not a character
304 return NS_ERROR_XSLT_PARSE_FAILURE
;
310 static void pushInstruction(txStylesheetCompilerState
& aState
,
311 UniquePtr
<txInstruction
> aInstruction
) {
312 aState
.pushObject(aInstruction
.release());
315 template <class T
= txInstruction
>
316 static UniquePtr
<T
> popInstruction(txStylesheetCompilerState
& aState
) {
317 return UniquePtr
<T
>(static_cast<T
*>(aState
.popObject()));
321 * Ignore and error handlers
323 static nsresult
txFnTextIgnore(const nsAString
& aStr
,
324 txStylesheetCompilerState
& aState
) {
328 static nsresult
txFnTextError(const nsAString
& aStr
,
329 txStylesheetCompilerState
& aState
) {
330 TX_RETURN_IF_WHITESPACE(aStr
, aState
);
332 return NS_ERROR_XSLT_PARSE_FAILURE
;
335 void clearAttributes(txStylesheetAttr
* aAttributes
, int32_t aAttrCount
) {
337 for (i
= 0; i
< aAttrCount
; ++i
) {
338 aAttributes
[i
].mLocalName
= nullptr;
342 static nsresult
txFnStartElementIgnore(int32_t aNamespaceID
, nsAtom
* aLocalName
,
344 txStylesheetAttr
* aAttributes
,
346 txStylesheetCompilerState
& aState
) {
348 clearAttributes(aAttributes
, aAttrCount
);
354 static void txFnEndElementIgnore(txStylesheetCompilerState
& aState
) {}
356 static nsresult
txFnStartElementSetIgnore(int32_t aNamespaceID
,
357 nsAtom
* aLocalName
, nsAtom
* aPrefix
,
358 txStylesheetAttr
* aAttributes
,
360 txStylesheetCompilerState
& aState
) {
362 clearAttributes(aAttributes
, aAttrCount
);
365 aState
.pushHandlerTable(gTxIgnoreHandler
);
370 static void txFnEndElementSetIgnore(txStylesheetCompilerState
& aState
) {
371 aState
.popHandlerTable();
374 static nsresult
txFnStartElementError(int32_t aNamespaceID
, nsAtom
* aLocalName
,
376 txStylesheetAttr
* aAttributes
,
378 txStylesheetCompilerState
& aState
) {
379 return NS_ERROR_XSLT_PARSE_FAILURE
;
382 static void txFnEndElementError(txStylesheetCompilerState
& aState
) {
383 MOZ_CRASH("txFnEndElementError shouldn't be called");
389 static nsresult
txFnStartStylesheet(int32_t aNamespaceID
, nsAtom
* aLocalName
,
391 txStylesheetAttr
* aAttributes
,
393 txStylesheetCompilerState
& aState
) {
394 // extension-element-prefixes is handled in
395 // txStylesheetCompiler::startElementInternal
397 txStylesheetAttr
* attr
;
398 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
,
399 nsGkAtoms::id
, false, &attr
);
400 NS_ENSURE_SUCCESS(rv
, rv
);
402 rv
= parseExcludeResultPrefixes(aAttributes
, aAttrCount
, kNameSpaceID_None
);
403 NS_ENSURE_SUCCESS(rv
, rv
);
405 rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
,
406 nsGkAtoms::version
, true, &attr
);
407 NS_ENSURE_SUCCESS(rv
, rv
);
409 aState
.pushHandlerTable(gTxImportHandler
);
414 static void txFnEndStylesheet(txStylesheetCompilerState
& aState
) {
415 aState
.popHandlerTable();
418 static nsresult
txFnStartElementContinueTopLevel(
419 int32_t aNamespaceID
, nsAtom
* aLocalName
, nsAtom
* aPrefix
,
420 txStylesheetAttr
* aAttributes
, int32_t aAttrCount
,
421 txStylesheetCompilerState
& aState
) {
422 aState
.mHandlerTable
= gTxTopHandler
;
424 return NS_XSLT_GET_NEW_HANDLER
;
427 static nsresult
txFnStartLREStylesheet(int32_t aNamespaceID
, nsAtom
* aLocalName
,
429 txStylesheetAttr
* aAttributes
,
431 txStylesheetCompilerState
& aState
) {
432 txStylesheetAttr
* attr
;
433 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_XSLT
,
434 nsGkAtoms::version
, true, &attr
);
435 NS_ENSURE_SUCCESS(rv
, rv
);
437 txExpandedName nullExpr
;
438 double prio
= UnspecifiedNaN
<double>();
440 UniquePtr
<txPattern
> match(new txRootPattern());
441 UniquePtr
<txTemplateItem
> templ(
442 new txTemplateItem(std::move(match
), nullExpr
, nullExpr
, prio
));
443 aState
.openInstructionContainer(templ
.get());
444 aState
.addToplevelItem(templ
.release());
446 aState
.pushHandlerTable(gTxTemplateHandler
);
448 return txFnStartLRE(aNamespaceID
, aLocalName
, aPrefix
, aAttributes
,
452 static void txFnEndLREStylesheet(txStylesheetCompilerState
& aState
) {
455 aState
.popHandlerTable();
457 aState
.addInstruction(MakeUnique
<txReturn
>());
459 aState
.closeInstructionContainer();
462 static nsresult
txFnStartEmbed(int32_t aNamespaceID
, nsAtom
* aLocalName
,
463 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
465 txStylesheetCompilerState
& aState
) {
466 if (!aState
.handleEmbeddedSheet()) {
469 if (aNamespaceID
!= kNameSpaceID_XSLT
||
470 (aLocalName
!= nsGkAtoms::stylesheet
&&
471 aLocalName
!= nsGkAtoms::transform
)) {
472 return NS_ERROR_XSLT_PARSE_FAILURE
;
474 return txFnStartStylesheet(aNamespaceID
, aLocalName
, aPrefix
, aAttributes
,
478 static void txFnEndEmbed(txStylesheetCompilerState
& aState
) {
479 if (!aState
.handleEmbeddedSheet()) {
482 txFnEndStylesheet(aState
);
483 aState
.doneEmbedding();
489 static nsresult
txFnStartOtherTop(int32_t aNamespaceID
, nsAtom
* aLocalName
,
491 txStylesheetAttr
* aAttributes
,
493 txStylesheetCompilerState
& aState
) {
494 if (aNamespaceID
== kNameSpaceID_None
||
495 (aNamespaceID
== kNameSpaceID_XSLT
&& !aState
.fcp())) {
496 return NS_ERROR_XSLT_PARSE_FAILURE
;
499 aState
.pushHandlerTable(gTxIgnoreHandler
);
504 static void txFnEndOtherTop(txStylesheetCompilerState
& aState
) {
505 aState
.popHandlerTable();
509 static nsresult
txFnStartAttributeSet(int32_t aNamespaceID
, nsAtom
* aLocalName
,
511 txStylesheetAttr
* aAttributes
,
513 txStylesheetCompilerState
& aState
) {
516 rv
= getQNameAttr(aAttributes
, aAttrCount
, nsGkAtoms::name
, true, aState
,
518 NS_ENSURE_SUCCESS(rv
, rv
);
520 UniquePtr
<txAttributeSetItem
> attrSet(new txAttributeSetItem(name
));
521 aState
.openInstructionContainer(attrSet
.get());
523 aState
.addToplevelItem(attrSet
.release());
525 rv
= parseUseAttrSets(aAttributes
, aAttrCount
, false, aState
);
526 NS_ENSURE_SUCCESS(rv
, rv
);
528 aState
.pushHandlerTable(gTxAttributeSetHandler
);
533 static void txFnEndAttributeSet(txStylesheetCompilerState
& aState
) {
534 aState
.popHandlerTable();
536 aState
.addInstruction(MakeUnique
<txReturn
>());
538 aState
.closeInstructionContainer();
541 // xsl:decimal-format
542 static nsresult
txFnStartDecimalFormat(int32_t aNamespaceID
, nsAtom
* aLocalName
,
544 txStylesheetAttr
* aAttributes
,
546 txStylesheetCompilerState
& aState
) {
549 rv
= getQNameAttr(aAttributes
, aAttrCount
, nsGkAtoms::name
, false, aState
,
551 NS_ENSURE_SUCCESS(rv
, rv
);
553 UniquePtr
<txDecimalFormat
> format(new txDecimalFormat
);
554 rv
= getCharAttr(aAttributes
, aAttrCount
, nsGkAtoms::decimalSeparator
, false,
555 aState
, format
->mDecimalSeparator
);
556 NS_ENSURE_SUCCESS(rv
, rv
);
558 rv
= getCharAttr(aAttributes
, aAttrCount
, nsGkAtoms::groupingSeparator
, false,
559 aState
, format
->mGroupingSeparator
);
560 NS_ENSURE_SUCCESS(rv
, rv
);
562 txStylesheetAttr
* attr
= nullptr;
563 rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
,
564 nsGkAtoms::infinity
, false, &attr
);
565 NS_ENSURE_SUCCESS(rv
, rv
);
568 format
->mInfinity
= attr
->mValue
;
571 rv
= getCharAttr(aAttributes
, aAttrCount
, nsGkAtoms::minusSign
, false, aState
,
573 NS_ENSURE_SUCCESS(rv
, rv
);
575 rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
, nsGkAtoms::NaN
,
577 NS_ENSURE_SUCCESS(rv
, rv
);
580 format
->mNaN
= attr
->mValue
;
583 rv
= getCharAttr(aAttributes
, aAttrCount
, nsGkAtoms::percent
, false, aState
,
585 NS_ENSURE_SUCCESS(rv
, rv
);
587 rv
= getCharAttr(aAttributes
, aAttrCount
, nsGkAtoms::perMille
, false, aState
,
589 NS_ENSURE_SUCCESS(rv
, rv
);
591 rv
= getCharAttr(aAttributes
, aAttrCount
, nsGkAtoms::zeroDigit
, false, aState
,
593 NS_ENSURE_SUCCESS(rv
, rv
);
595 rv
= getCharAttr(aAttributes
, aAttrCount
, nsGkAtoms::digit
, false, aState
,
597 NS_ENSURE_SUCCESS(rv
, rv
);
599 rv
= getCharAttr(aAttributes
, aAttrCount
, nsGkAtoms::patternSeparator
, false,
600 aState
, format
->mPatternSeparator
);
601 NS_ENSURE_SUCCESS(rv
, rv
);
603 rv
= aState
.mStylesheet
->addDecimalFormat(name
, std::move(format
));
604 NS_ENSURE_SUCCESS(rv
, rv
);
606 aState
.pushHandlerTable(gTxIgnoreHandler
);
611 static void txFnEndDecimalFormat(txStylesheetCompilerState
& aState
) {
612 aState
.popHandlerTable();
616 static nsresult
txFnStartImport(int32_t aNamespaceID
, nsAtom
* aLocalName
,
617 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
619 txStylesheetCompilerState
& aState
) {
620 UniquePtr
<txImportItem
> import(new txImportItem
);
621 import
->mFrame
= MakeUnique
<txStylesheet::ImportFrame
>();
622 txStylesheet::ImportFrame
* frame
= import
->mFrame
.get();
623 aState
.addToplevelItem(import
.release());
625 txStylesheetAttr
* attr
= nullptr;
626 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
,
627 nsGkAtoms::href
, true, &attr
);
628 NS_ENSURE_SUCCESS(rv
, rv
);
631 URIUtils::resolveHref(attr
->mValue
, aState
.mElementContext
->mBaseURI
, absUri
);
632 rv
= aState
.loadImportedStylesheet(absUri
, frame
);
633 NS_ENSURE_SUCCESS(rv
, rv
);
635 aState
.pushHandlerTable(gTxIgnoreHandler
);
640 static void txFnEndImport(txStylesheetCompilerState
& aState
) {
641 aState
.popHandlerTable();
645 static nsresult
txFnStartInclude(int32_t aNamespaceID
, nsAtom
* aLocalName
,
646 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
648 txStylesheetCompilerState
& aState
) {
649 txStylesheetAttr
* attr
= nullptr;
650 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
,
651 nsGkAtoms::href
, true, &attr
);
652 NS_ENSURE_SUCCESS(rv
, rv
);
655 URIUtils::resolveHref(attr
->mValue
, aState
.mElementContext
->mBaseURI
, absUri
);
656 rv
= aState
.loadIncludedStylesheet(absUri
);
657 NS_ENSURE_SUCCESS(rv
, rv
);
659 aState
.pushHandlerTable(gTxIgnoreHandler
);
664 static void txFnEndInclude(txStylesheetCompilerState
& aState
) {
665 aState
.popHandlerTable();
669 static nsresult
txFnStartKey(int32_t aNamespaceID
, nsAtom
* aLocalName
,
670 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
672 txStylesheetCompilerState
& aState
) {
675 rv
= getQNameAttr(aAttributes
, aAttrCount
, nsGkAtoms::name
, true, aState
,
677 NS_ENSURE_SUCCESS(rv
, rv
);
679 aState
.mDisAllowed
= txIParseContext::KEY_FUNCTION
;
681 UniquePtr
<txPattern
> match
;
682 rv
= getPatternAttr(aAttributes
, aAttrCount
, nsGkAtoms::match
, true, aState
,
684 NS_ENSURE_SUCCESS(rv
, rv
);
687 rv
= getExprAttr(aAttributes
, aAttrCount
, nsGkAtoms::use
, true, aState
, use
);
688 NS_ENSURE_SUCCESS(rv
, rv
);
690 aState
.mDisAllowed
= 0;
692 rv
= aState
.mStylesheet
->addKey(name
, std::move(match
), std::move(use
));
693 NS_ENSURE_SUCCESS(rv
, rv
);
695 aState
.pushHandlerTable(gTxIgnoreHandler
);
700 static void txFnEndKey(txStylesheetCompilerState
& aState
) {
701 aState
.popHandlerTable();
704 // xsl:namespace-alias
705 static nsresult
txFnStartNamespaceAlias(int32_t aNamespaceID
,
706 nsAtom
* aLocalName
, nsAtom
* aPrefix
,
707 txStylesheetAttr
* aAttributes
,
709 txStylesheetCompilerState
& aState
) {
710 txStylesheetAttr
* attr
= nullptr;
711 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
,
712 nsGkAtoms::stylesheetPrefix
, true, &attr
);
713 NS_ENSURE_SUCCESS(rv
, rv
);
715 rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
,
716 nsGkAtoms::resultPrefix
, true, &attr
);
717 NS_ENSURE_SUCCESS(rv
, rv
);
719 // XXX Needs to be implemented.
721 aState
.pushHandlerTable(gTxIgnoreHandler
);
726 static void txFnEndNamespaceAlias(txStylesheetCompilerState
& aState
) {
727 aState
.popHandlerTable();
731 static nsresult
txFnStartOutput(int32_t aNamespaceID
, nsAtom
* aLocalName
,
732 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
734 txStylesheetCompilerState
& aState
) {
737 UniquePtr
<txOutputItem
> item(new txOutputItem
);
739 txExpandedName methodExpName
;
740 rv
= getQNameAttr(aAttributes
, aAttrCount
, nsGkAtoms::method
, false, aState
,
742 NS_ENSURE_SUCCESS(rv
, rv
);
744 if (!methodExpName
.isNull()) {
745 if (methodExpName
.mNamespaceID
!= kNameSpaceID_None
) {
746 // The spec doesn't say what to do here so we'll just ignore the
747 // value. We could possibly warn.
748 } else if (methodExpName
.mLocalName
== nsGkAtoms::html
) {
749 item
->mFormat
.mMethod
= eHTMLOutput
;
750 } else if (methodExpName
.mLocalName
== nsGkAtoms::text
) {
751 item
->mFormat
.mMethod
= eTextOutput
;
752 } else if (methodExpName
.mLocalName
== nsGkAtoms::xml
) {
753 item
->mFormat
.mMethod
= eXMLOutput
;
755 return NS_ERROR_XSLT_PARSE_FAILURE
;
759 txStylesheetAttr
* attr
= nullptr;
760 getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
, nsGkAtoms::version
,
763 item
->mFormat
.mVersion
= attr
->mValue
;
766 getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
, nsGkAtoms::encoding
,
769 item
->mFormat
.mEncoding
= attr
->mValue
;
772 rv
= getYesNoAttr(aAttributes
, aAttrCount
, nsGkAtoms::omitXmlDeclaration
,
773 false, aState
, item
->mFormat
.mOmitXMLDeclaration
);
774 NS_ENSURE_SUCCESS(rv
, rv
);
776 rv
= getYesNoAttr(aAttributes
, aAttrCount
, nsGkAtoms::standalone
, false,
777 aState
, item
->mFormat
.mStandalone
);
778 NS_ENSURE_SUCCESS(rv
, rv
);
780 getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
,
781 nsGkAtoms::doctypePublic
, false, &attr
);
783 item
->mFormat
.mPublicId
= attr
->mValue
;
786 getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
,
787 nsGkAtoms::doctypeSystem
, false, &attr
);
789 item
->mFormat
.mSystemId
= attr
->mValue
;
792 getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
,
793 nsGkAtoms::cdataSectionElements
, false, &attr
);
795 nsWhitespaceTokenizer
tokens(attr
->mValue
);
796 while (tokens
.hasMoreTokens()) {
797 UniquePtr
<txExpandedName
> qname(new txExpandedName());
798 rv
= qname
->init(tokens
.nextToken(), aState
.mElementContext
->mMappings
,
800 NS_ENSURE_SUCCESS(rv
, rv
);
802 item
->mFormat
.mCDATASectionElements
.add(qname
.release());
806 rv
= getYesNoAttr(aAttributes
, aAttrCount
, nsGkAtoms::indent
, false, aState
,
807 item
->mFormat
.mIndent
);
808 NS_ENSURE_SUCCESS(rv
, rv
);
810 getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
, nsGkAtoms::mediaType
,
813 item
->mFormat
.mMediaType
= NS_ConvertUTF16toUTF8(attr
->mValue
);
816 aState
.addToplevelItem(item
.release());
818 aState
.pushHandlerTable(gTxIgnoreHandler
);
823 static void txFnEndOutput(txStylesheetCompilerState
& aState
) {
824 aState
.popHandlerTable();
827 // xsl:strip-space/xsl:preserve-space
828 static nsresult
txFnStartStripSpace(int32_t aNamespaceID
, nsAtom
* aLocalName
,
830 txStylesheetAttr
* aAttributes
,
832 txStylesheetCompilerState
& aState
) {
833 txStylesheetAttr
* attr
= nullptr;
834 nsresult rv
= getStyleAttr(aAttributes
, aAttrCount
, kNameSpaceID_None
,
835 nsGkAtoms::elements
, true, &attr
);
836 NS_ENSURE_SUCCESS(rv
, rv
);
838 bool strip
= aLocalName
== nsGkAtoms::stripSpace
;
840 UniquePtr
<txStripSpaceItem
> stripItem(new txStripSpaceItem
);
841 nsWhitespaceTokenizer
tokenizer(attr
->mValue
);
842 while (tokenizer
.hasMoreTokens()) {
843 const nsAString
& name
= tokenizer
.nextToken();
844 int32_t ns
= kNameSpaceID_None
;
845 RefPtr
<nsAtom
> prefix
, localName
;
846 rv
= XMLUtils::splitQName(name
, getter_AddRefs(prefix
),
847 getter_AddRefs(localName
));
849 // check for "*" or "prefix:*"
850 uint32_t length
= name
.Length();
852 name
.BeginReading(c
);
853 if (length
== 2 || c
[length
- 1] != '*') {
855 return NS_ERROR_XSLT_PARSE_FAILURE
;
858 // Check for a valid prefix, that is, the returned prefix
859 // should be empty and the real prefix is returned in
861 if (c
[length
- 2] != ':') {
862 return NS_ERROR_XSLT_PARSE_FAILURE
;
864 rv
= XMLUtils::splitQName(StringHead(name
, length
- 2),
865 getter_AddRefs(prefix
),
866 getter_AddRefs(localName
));
867 if (NS_FAILED(rv
) || prefix
) {
868 // bad chars or two ':'
869 return NS_ERROR_XSLT_PARSE_FAILURE
;
873 localName
= nsGkAtoms::_asterisk
;
876 ns
= aState
.mElementContext
->mMappings
->lookupNamespace(prefix
);
877 NS_ENSURE_TRUE(ns
!= kNameSpaceID_Unknown
, NS_ERROR_FAILURE
);
879 stripItem
->addStripSpaceTest(
880 new txStripSpaceTest(prefix
, localName
, ns
, strip
));
883 aState
.addToplevelItem(stripItem
.release());
885 aState
.pushHandlerTable(gTxIgnoreHandler
);
890 static void txFnEndStripSpace(txStylesheetCompilerState
& aState
) {
891 aState
.popHandlerTable();
895 static nsresult
txFnStartTemplate(int32_t aNamespaceID
, nsAtom
* aLocalName
,
897 txStylesheetAttr
* aAttributes
,
899 txStylesheetCompilerState
& aState
) {
902 rv
= getQNameAttr(aAttributes
, aAttrCount
, nsGkAtoms::name
, false, aState
,
904 NS_ENSURE_SUCCESS(rv
, rv
);
907 rv
= getQNameAttr(aAttributes
, aAttrCount
, nsGkAtoms::mode
, false, aState
,
909 NS_ENSURE_SUCCESS(rv
, rv
);
911 double prio
= UnspecifiedNaN
<double>();
912 rv
= getNumberAttr(aAttributes
, aAttrCount
, nsGkAtoms::priority
, false,
914 NS_ENSURE_SUCCESS(rv
, rv
);
916 UniquePtr
<txPattern
> match
;
917 rv
= getPatternAttr(aAttributes
, aAttrCount
, nsGkAtoms::match
, name
.isNull(),
919 NS_ENSURE_SUCCESS(rv
, rv
);
921 UniquePtr
<txTemplateItem
> templ(
922 new txTemplateItem(std::move(match
), name
, mode
, prio
));
923 aState
.openInstructionContainer(templ
.get());
924 aState
.addToplevelItem(templ
.release());
926 aState
.pushHandlerTable(gTxParamHandler
);
931 static void txFnEndTemplate(txStylesheetCompilerState
& aState
) {
932 aState
.popHandlerTable();
934 aState
.addInstruction(MakeUnique
<txReturn
>());
936 aState
.closeInstructionContainer();
939 // xsl:variable, xsl:param
940 static nsresult
txFnStartTopVariable(int32_t aNamespaceID
, nsAtom
* aLocalName
,
942 txStylesheetAttr
* aAttributes
,
944 txStylesheetCompilerState
& aState
) {
947 rv
= getQNameAttr(aAttributes
, aAttrCount
, nsGkAtoms::name
, true, aState
,
949 NS_ENSURE_SUCCESS(rv
, rv
);
951 UniquePtr
<Expr
> select
;
952 rv
= getExprAttr(aAttributes
, aAttrCount
, nsGkAtoms::select
, false, aState
,
954 NS_ENSURE_SUCCESS(rv
, rv
);
956 UniquePtr
<txVariableItem
> var(new txVariableItem(
957 name
, std::move(select
), aLocalName
== nsGkAtoms::param
));
958 aState
.openInstructionContainer(var
.get());
959 aState
.pushPtr(var
.get(), aState
.eVariableItem
);
962 // XXX should be gTxErrorHandler?
963 aState
.pushHandlerTable(gTxIgnoreHandler
);
965 aState
.pushHandlerTable(gTxTopVariableHandler
);
968 aState
.addToplevelItem(var
.release());
973 static void txFnEndTopVariable(txStylesheetCompilerState
& aState
) {
974 txHandlerTable
* prev
= aState
.mHandlerTable
;
975 aState
.popHandlerTable();
976 txVariableItem
* var
=
977 static_cast<txVariableItem
*>(aState
.popPtr(aState
.eVariableItem
));
979 if (prev
== gTxTopVariableHandler
) {
980 // No children were found.
981 NS_ASSERTION(!var
->mValue
, "There shouldn't be a select-expression here");
982 var
->mValue
= MakeUnique
<txLiteralExpr
>(u
""_ns
);
983 } else if (!var
->mValue
) {
984 // If we don't have a select-expression there mush be children.
985 aState
.addInstruction(MakeUnique
<txReturn
>());
988 aState
.closeInstructionContainer();
991 static nsresult
txFnStartElementStartTopVar(int32_t aNamespaceID
,
992 nsAtom
* aLocalName
, nsAtom
* aPrefix
,
993 txStylesheetAttr
* aAttributes
,
995 txStylesheetCompilerState
& aState
) {
996 aState
.mHandlerTable
= gTxTemplateHandler
;
998 return NS_XSLT_GET_NEW_HANDLER
;
1001 static nsresult
txFnTextStartTopVar(const nsAString
& aStr
,
1002 txStylesheetCompilerState
& aState
) {
1003 TX_RETURN_IF_WHITESPACE(aStr
, aState
);
1005 aState
.mHandlerTable
= gTxTemplateHandler
;
1007 return NS_XSLT_GET_NEW_HANDLER
;
1018 txInsertAttrSet one for each qname in xsl:use-attribute-sets
1019 txLREAttribute one for each attribute
1023 static nsresult
txFnStartLRE(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1024 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1026 txStylesheetCompilerState
& aState
) {
1027 nsresult rv
= NS_OK
;
1029 aState
.addInstruction(
1030 MakeUnique
<txStartLREElement
>(aNamespaceID
, aLocalName
, aPrefix
));
1032 rv
= parseExcludeResultPrefixes(aAttributes
, aAttrCount
, kNameSpaceID_XSLT
);
1033 NS_ENSURE_SUCCESS(rv
, rv
);
1035 rv
= parseUseAttrSets(aAttributes
, aAttrCount
, true, aState
);
1036 NS_ENSURE_SUCCESS(rv
, rv
);
1038 txStylesheetAttr
* attr
= nullptr;
1040 for (i
= 0; i
< aAttrCount
; ++i
) {
1041 attr
= aAttributes
+ i
;
1043 if (attr
->mNamespaceID
== kNameSpaceID_XSLT
) {
1044 if (attr
->mLocalName
== nsGkAtoms::version
) {
1045 attr
->mLocalName
= nullptr;
1051 UniquePtr
<Expr
> avt
;
1052 rv
= txExprParser::createAVT(attr
->mValue
, &aState
, getter_Transfers(avt
));
1053 NS_ENSURE_SUCCESS(rv
, rv
);
1055 aState
.addInstruction(MakeUnique
<txLREAttribute
>(
1056 attr
->mNamespaceID
, attr
->mLocalName
, attr
->mPrefix
, std::move(avt
)));
1062 static void txFnEndLRE(txStylesheetCompilerState
& aState
) {
1063 aState
.addInstruction(MakeUnique
<txEndElement
>());
1071 static nsresult
txFnText(const nsAString
& aStr
,
1072 txStylesheetCompilerState
& aState
) {
1073 TX_RETURN_IF_WHITESPACE(aStr
, aState
);
1075 aState
.addInstruction(MakeUnique
<txText
>(aStr
, false));
1086 static nsresult
txFnStartApplyImports(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1088 txStylesheetAttr
* aAttributes
,
1090 txStylesheetCompilerState
& aState
) {
1091 aState
.addInstruction(MakeUnique
<txApplyImportsStart
>());
1092 aState
.addInstruction(MakeUnique
<txApplyImportsEnd
>());
1094 aState
.pushHandlerTable(gTxIgnoreHandler
);
1099 static void txFnEndApplyImports(txStylesheetCompilerState
& aState
) {
1100 aState
.popHandlerTable();
1108 txPushNewContext -+ (holds <xsl:sort>s)
1109 txApplyTemplate <-+ |
1113 static nsresult
txFnStartApplyTemplates(int32_t aNamespaceID
,
1114 nsAtom
* aLocalName
, nsAtom
* aPrefix
,
1115 txStylesheetAttr
* aAttributes
,
1117 txStylesheetCompilerState
& aState
) {
1118 nsresult rv
= NS_OK
;
1120 aState
.addInstruction(MakeUnique
<txPushParams
>());
1122 txExpandedName mode
;
1123 rv
= getQNameAttr(aAttributes
, aAttrCount
, nsGkAtoms::mode
, false, aState
,
1125 NS_ENSURE_SUCCESS(rv
, rv
);
1127 pushInstruction(aState
, MakeUnique
<txApplyTemplates
>(mode
));
1129 UniquePtr
<Expr
> select
;
1130 rv
= getExprAttr(aAttributes
, aAttrCount
, nsGkAtoms::select
, false, aState
,
1132 NS_ENSURE_SUCCESS(rv
, rv
);
1135 UniquePtr
<txNodeTest
> nt(new txNodeTypeTest(txNodeTypeTest::NODE_TYPE
));
1136 select
= MakeUnique
<LocationStep
>(nt
.release(), LocationStep::CHILD_AXIS
);
1139 UniquePtr
<txPushNewContext
> pushcontext(
1140 new txPushNewContext(std::move(select
)));
1141 aState
.pushSorter(pushcontext
.get());
1142 pushInstruction(aState
, std::move(pushcontext
));
1144 aState
.pushHandlerTable(gTxApplyTemplatesHandler
);
1149 static void txFnEndApplyTemplates(txStylesheetCompilerState
& aState
) {
1150 aState
.popHandlerTable();
1152 txPushNewContext
* pushcontext
=
1153 aState
.addInstruction(popInstruction
<txPushNewContext
>(aState
));
1158 txInstruction
* instr
= aState
.addInstruction(popInstruction(aState
));
1159 aState
.addInstruction(MakeUnique
<txLoopNodeSet
>(instr
));
1161 pushcontext
->mBailTarget
= aState
.addInstruction(MakeUnique
<txPopParams
>());
1171 static nsresult
txFnStartAttribute(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1173 txStylesheetAttr
* aAttributes
,
1175 txStylesheetCompilerState
& aState
) {
1176 nsresult rv
= NS_OK
;
1178 aState
.addInstruction(MakeUnique
<txPushStringHandler
>(true));
1180 UniquePtr
<Expr
> name
;
1181 rv
= getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::name
, true, aState
, name
);
1182 NS_ENSURE_SUCCESS(rv
, rv
);
1184 UniquePtr
<Expr
> nspace
;
1185 rv
= getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::_namespace
, false, aState
,
1187 NS_ENSURE_SUCCESS(rv
, rv
);
1189 pushInstruction(aState
,
1190 MakeUnique
<txAttribute
>(std::move(name
), std::move(nspace
),
1191 aState
.mElementContext
->mMappings
));
1193 // We need to push the template-handler since the current might be
1194 // the attributeset-handler
1195 aState
.pushHandlerTable(gTxTemplateHandler
);
1200 static void txFnEndAttribute(txStylesheetCompilerState
& aState
) {
1201 aState
.popHandlerTable();
1202 aState
.addInstruction(popInstruction(aState
));
1213 static nsresult
txFnStartCallTemplate(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1215 txStylesheetAttr
* aAttributes
,
1217 txStylesheetCompilerState
& aState
) {
1218 nsresult rv
= NS_OK
;
1220 aState
.addInstruction(MakeUnique
<txPushParams
>());
1222 txExpandedName name
;
1223 rv
= getQNameAttr(aAttributes
, aAttrCount
, nsGkAtoms::name
, true, aState
,
1225 NS_ENSURE_SUCCESS(rv
, rv
);
1227 pushInstruction(aState
, MakeUnique
<txCallTemplate
>(name
));
1229 aState
.pushHandlerTable(gTxCallTemplateHandler
);
1234 static void txFnEndCallTemplate(txStylesheetCompilerState
& aState
) {
1235 aState
.popHandlerTable();
1238 aState
.addInstruction(popInstruction(aState
));
1240 aState
.addInstruction(MakeUnique
<txPopParams
>());
1246 txCondotionalGoto --+ \
1247 [children] | | one for each xsl:when
1250 txCondotionalGoto | <-+ --+
1254 [children] | <-+ for the xsl:otherwise, if there is one
1257 static nsresult
txFnStartChoose(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1258 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1260 txStylesheetCompilerState
& aState
) {
1261 aState
.pushChooseGotoList();
1263 aState
.pushHandlerTable(gTxChooseHandler
);
1268 static void txFnEndChoose(txStylesheetCompilerState
& aState
) {
1269 aState
.popHandlerTable();
1270 txListIterator
iter(aState
.mChooseGotoList
.get());
1272 while ((gotoinstr
= static_cast<txGoTo
*>(iter
.next()))) {
1273 aState
.addGotoTarget(&gotoinstr
->mTarget
);
1276 aState
.popChooseGotoList();
1286 static nsresult
txFnStartComment(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1287 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1289 txStylesheetCompilerState
& aState
) {
1290 aState
.addInstruction(MakeUnique
<txPushStringHandler
>(true));
1295 static void txFnEndComment(txStylesheetCompilerState
& aState
) {
1296 aState
.addInstruction(MakeUnique
<txComment
>());
1303 txInsertAttrSet | one for each qname in use-attribute-sets
1308 static nsresult
txFnStartCopy(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1309 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1311 txStylesheetCompilerState
& aState
) {
1312 aState
.pushPtr(aState
.addInstruction(MakeUnique
<txCopy
>()), aState
.eCopy
);
1314 return parseUseAttrSets(aAttributes
, aAttrCount
, false, aState
);
1317 static void txFnEndCopy(txStylesheetCompilerState
& aState
) {
1318 aState
.addInstruction(MakeUnique
<txEndElement
>());
1320 txCopy
* copy
= static_cast<txCopy
*>(aState
.popPtr(aState
.eCopy
));
1321 aState
.addGotoTarget(©
->mBailTarget
);
1329 static nsresult
txFnStartCopyOf(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1330 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1332 txStylesheetCompilerState
& aState
) {
1333 nsresult rv
= NS_OK
;
1335 UniquePtr
<Expr
> select
;
1336 rv
= getExprAttr(aAttributes
, aAttrCount
, nsGkAtoms::select
, true, aState
,
1338 NS_ENSURE_SUCCESS(rv
, rv
);
1340 aState
.addInstruction(MakeUnique
<txCopyOf
>(std::move(select
)));
1342 aState
.pushHandlerTable(gTxIgnoreHandler
);
1347 static void txFnEndCopyOf(txStylesheetCompilerState
& aState
) {
1348 aState
.popHandlerTable();
1355 txInsertAttrSet one for each qname in use-attribute-sets
1359 static nsresult
txFnStartElement(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1360 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1362 txStylesheetCompilerState
& aState
) {
1363 nsresult rv
= NS_OK
;
1365 UniquePtr
<Expr
> name
;
1366 rv
= getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::name
, true, aState
, name
);
1367 NS_ENSURE_SUCCESS(rv
, rv
);
1369 UniquePtr
<Expr
> nspace
;
1370 rv
= getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::_namespace
, false, aState
,
1372 NS_ENSURE_SUCCESS(rv
, rv
);
1374 aState
.addInstruction(MakeUnique
<txStartElement
>(
1375 std::move(name
), std::move(nspace
), aState
.mElementContext
->mMappings
));
1377 rv
= parseUseAttrSets(aAttributes
, aAttrCount
, false, aState
);
1378 NS_ENSURE_SUCCESS(rv
, rv
);
1383 static void txFnEndElement(txStylesheetCompilerState
& aState
) {
1384 aState
.addInstruction(MakeUnique
<txEndElement
>());
1392 static nsresult
txFnStartFallback(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1394 txStylesheetAttr
* aAttributes
,
1396 txStylesheetCompilerState
& aState
) {
1397 aState
.mSearchingForFallback
= false;
1399 aState
.pushHandlerTable(gTxTemplateHandler
);
1404 static void txFnEndFallback(txStylesheetCompilerState
& aState
) {
1405 aState
.popHandlerTable();
1407 NS_ASSERTION(!aState
.mSearchingForFallback
,
1408 "bad nesting of unknown-instruction and fallback handlers");
1414 txPushNewContext -+ (holds <xsl:sort>s)
1415 txPushNullTemplateRule <-+ |
1420 static nsresult
txFnStartForEach(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1421 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1423 txStylesheetCompilerState
& aState
) {
1424 nsresult rv
= NS_OK
;
1426 UniquePtr
<Expr
> select
;
1427 rv
= getExprAttr(aAttributes
, aAttrCount
, nsGkAtoms::select
, true, aState
,
1429 NS_ENSURE_SUCCESS(rv
, rv
);
1431 txPushNewContext
* pushcontext
=
1432 aState
.addInstruction(MakeUnique
<txPushNewContext
>(std::move(select
)));
1433 aState
.pushPtr(pushcontext
, aState
.ePushNewContext
);
1434 aState
.pushSorter(pushcontext
);
1436 aState
.pushPtr(aState
.addInstruction(MakeUnique
<txPushNullTemplateRule
>()),
1437 aState
.ePushNullTemplateRule
);
1439 aState
.pushHandlerTable(gTxForEachHandler
);
1444 static void txFnEndForEach(txStylesheetCompilerState
& aState
) {
1445 aState
.popHandlerTable();
1447 // This is a txPushNullTemplateRule
1448 txInstruction
* pnullrule
=
1449 static_cast<txInstruction
*>(aState
.popPtr(aState
.ePushNullTemplateRule
));
1451 aState
.addInstruction(MakeUnique
<txLoopNodeSet
>(pnullrule
));
1454 txPushNewContext
* pushcontext
=
1455 static_cast<txPushNewContext
*>(aState
.popPtr(aState
.ePushNewContext
));
1456 aState
.addGotoTarget(&pushcontext
->mBailTarget
);
1459 static nsresult
txFnStartElementContinueTemplate(
1460 int32_t aNamespaceID
, nsAtom
* aLocalName
, nsAtom
* aPrefix
,
1461 txStylesheetAttr
* aAttributes
, int32_t aAttrCount
,
1462 txStylesheetCompilerState
& aState
) {
1463 aState
.mHandlerTable
= gTxTemplateHandler
;
1465 return NS_XSLT_GET_NEW_HANDLER
;
1468 static nsresult
txFnTextContinueTemplate(const nsAString
& aStr
,
1469 txStylesheetCompilerState
& aState
) {
1470 TX_RETURN_IF_WHITESPACE(aStr
, aState
);
1472 aState
.mHandlerTable
= gTxTemplateHandler
;
1474 return NS_XSLT_GET_NEW_HANDLER
;
1480 txConditionalGoto -+
1484 static nsresult
txFnStartIf(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1485 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1487 txStylesheetCompilerState
& aState
) {
1488 nsresult rv
= NS_OK
;
1490 UniquePtr
<Expr
> test
;
1492 getExprAttr(aAttributes
, aAttrCount
, nsGkAtoms::test
, true, aState
, test
);
1493 NS_ENSURE_SUCCESS(rv
, rv
);
1495 aState
.pushPtr(aState
.addInstruction(
1496 MakeUnique
<txConditionalGoto
>(std::move(test
), nullptr)),
1497 aState
.eConditionalGoto
);
1502 static void txFnEndIf(txStylesheetCompilerState
& aState
) {
1503 txConditionalGoto
* condGoto
=
1504 static_cast<txConditionalGoto
*>(aState
.popPtr(aState
.eConditionalGoto
));
1505 aState
.addGotoTarget(&condGoto
->mTarget
);
1515 static nsresult
txFnStartMessage(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1516 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1518 txStylesheetCompilerState
& aState
) {
1519 aState
.addInstruction(MakeUnique
<txPushStringHandler
>(false));
1522 nsresult rv
= getYesNoAttr(aAttributes
, aAttrCount
, nsGkAtoms::terminate
,
1523 false, aState
, term
);
1524 NS_ENSURE_SUCCESS(rv
, rv
);
1526 pushInstruction(aState
, MakeUnique
<txMessage
>(term
== eTrue
));
1531 static void txFnEndMessage(txStylesheetCompilerState
& aState
) {
1532 aState
.addInstruction(popInstruction(aState
));
1540 static nsresult
txFnStartNumber(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1541 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1543 txStylesheetCompilerState
& aState
) {
1544 nsresult rv
= NS_OK
;
1546 RefPtr
<nsAtom
> levelAtom
;
1547 rv
= getAtomAttr(aAttributes
, aAttrCount
, nsGkAtoms::level
, false, aState
,
1548 getter_AddRefs(levelAtom
));
1549 NS_ENSURE_SUCCESS(rv
, rv
);
1551 txXSLTNumber::LevelType level
= txXSLTNumber::eLevelSingle
;
1552 if (levelAtom
== nsGkAtoms::multiple
) {
1553 level
= txXSLTNumber::eLevelMultiple
;
1554 } else if (levelAtom
== nsGkAtoms::any
) {
1555 level
= txXSLTNumber::eLevelAny
;
1556 } else if (levelAtom
&& levelAtom
!= nsGkAtoms::single
&& !aState
.fcp()) {
1557 return NS_ERROR_XSLT_PARSE_FAILURE
;
1560 UniquePtr
<txPattern
> count
;
1561 rv
= getPatternAttr(aAttributes
, aAttrCount
, nsGkAtoms::count
, false, aState
,
1563 NS_ENSURE_SUCCESS(rv
, rv
);
1565 UniquePtr
<txPattern
> from
;
1566 rv
= getPatternAttr(aAttributes
, aAttrCount
, nsGkAtoms::from
, false, aState
,
1568 NS_ENSURE_SUCCESS(rv
, rv
);
1570 UniquePtr
<Expr
> value
;
1571 rv
= getExprAttr(aAttributes
, aAttrCount
, nsGkAtoms::value
, false, aState
,
1573 NS_ENSURE_SUCCESS(rv
, rv
);
1575 UniquePtr
<Expr
> format
;
1576 rv
= getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::format
, false, aState
,
1578 NS_ENSURE_SUCCESS(rv
, rv
);
1580 UniquePtr
<Expr
> lang
;
1582 getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::lang
, false, aState
, lang
);
1583 NS_ENSURE_SUCCESS(rv
, rv
);
1585 UniquePtr
<Expr
> letterValue
;
1586 rv
= getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::letterValue
, false,
1587 aState
, letterValue
);
1588 NS_ENSURE_SUCCESS(rv
, rv
);
1590 UniquePtr
<Expr
> groupingSeparator
;
1591 rv
= getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::groupingSeparator
, false,
1592 aState
, groupingSeparator
);
1593 NS_ENSURE_SUCCESS(rv
, rv
);
1595 UniquePtr
<Expr
> groupingSize
;
1596 rv
= getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::groupingSize
, false,
1597 aState
, groupingSize
);
1598 NS_ENSURE_SUCCESS(rv
, rv
);
1600 aState
.addInstruction(MakeUnique
<txNumber
>(
1601 level
, std::move(count
), std::move(from
), std::move(value
),
1602 std::move(format
), std::move(groupingSeparator
),
1603 std::move(groupingSize
)));
1605 aState
.pushHandlerTable(gTxIgnoreHandler
);
1610 static void txFnEndNumber(txStylesheetCompilerState
& aState
) {
1611 aState
.popHandlerTable();
1619 static nsresult
txFnStartOtherwise(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1621 txStylesheetAttr
* aAttributes
,
1623 txStylesheetCompilerState
& aState
) {
1624 aState
.pushHandlerTable(gTxTemplateHandler
);
1629 static void txFnEndOtherwise(txStylesheetCompilerState
& aState
) {
1630 aState
.popHandlerTable();
1631 aState
.mHandlerTable
= gTxIgnoreHandler
; // XXX should be gTxErrorHandler
1638 txPushRTFHandler | --- (for RTF-parameters)
1643 static nsresult
txFnStartParam(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1644 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1646 txStylesheetCompilerState
& aState
) {
1647 nsresult rv
= NS_OK
;
1649 txExpandedName name
;
1650 rv
= getQNameAttr(aAttributes
, aAttrCount
, nsGkAtoms::name
, true, aState
,
1652 NS_ENSURE_SUCCESS(rv
, rv
);
1654 aState
.pushPtr(aState
.addInstruction(MakeUnique
<txCheckParam
>(name
)),
1655 aState
.eCheckParam
);
1657 UniquePtr
<Expr
> select
;
1658 rv
= getExprAttr(aAttributes
, aAttrCount
, nsGkAtoms::select
, false, aState
,
1660 NS_ENSURE_SUCCESS(rv
, rv
);
1662 UniquePtr
<txSetVariable
> var
=
1663 MakeUnique
<txSetVariable
>(name
, std::move(select
));
1665 // XXX should be gTxErrorHandler?
1666 aState
.pushHandlerTable(gTxIgnoreHandler
);
1668 aState
.pushHandlerTable(gTxVariableHandler
);
1671 pushInstruction(aState
, std::move(var
));
1676 static void txFnEndParam(txStylesheetCompilerState
& aState
) {
1677 UniquePtr
<txSetVariable
> var
= popInstruction
<txSetVariable
>(aState
);
1678 txHandlerTable
* prev
= aState
.mHandlerTable
;
1679 aState
.popHandlerTable();
1681 if (prev
== gTxVariableHandler
) {
1682 // No children were found.
1683 NS_ASSERTION(!var
->mValue
, "There shouldn't be a select-expression here");
1684 var
->mValue
= MakeUnique
<txLiteralExpr
>(u
""_ns
);
1687 aState
.addVariable(var
->mName
);
1689 aState
.addInstruction(std::move(var
));
1691 txCheckParam
* checkParam
=
1692 static_cast<txCheckParam
*>(aState
.popPtr(aState
.eCheckParam
));
1693 aState
.addGotoTarget(&checkParam
->mBailTarget
);
1697 xsl:processing-instruction
1701 txProcessingInstruction
1703 static nsresult
txFnStartPI(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1704 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1706 txStylesheetCompilerState
& aState
) {
1707 aState
.addInstruction(MakeUnique
<txPushStringHandler
>(true));
1709 UniquePtr
<Expr
> name
;
1711 getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::name
, true, aState
, name
);
1712 NS_ENSURE_SUCCESS(rv
, rv
);
1714 pushInstruction(aState
, MakeUnique
<txProcessingInstruction
>(std::move(name
)));
1719 static void txFnEndPI(txStylesheetCompilerState
& aState
) {
1720 aState
.addInstruction(popInstruction(aState
));
1728 static nsresult
txFnStartSort(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1729 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1731 txStylesheetCompilerState
& aState
) {
1732 nsresult rv
= NS_OK
;
1734 UniquePtr
<Expr
> select
;
1735 rv
= getExprAttr(aAttributes
, aAttrCount
, nsGkAtoms::select
, false, aState
,
1737 NS_ENSURE_SUCCESS(rv
, rv
);
1740 UniquePtr
<txNodeTest
> nt(new txNodeTypeTest(txNodeTypeTest::NODE_TYPE
));
1741 select
= MakeUnique
<LocationStep
>(nt
.release(), LocationStep::SELF_AXIS
);
1744 UniquePtr
<Expr
> lang
;
1746 getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::lang
, false, aState
, lang
);
1747 NS_ENSURE_SUCCESS(rv
, rv
);
1749 UniquePtr
<Expr
> dataType
;
1750 rv
= getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::dataType
, false, aState
,
1752 NS_ENSURE_SUCCESS(rv
, rv
);
1754 UniquePtr
<Expr
> order
;
1755 rv
= getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::order
, false, aState
,
1757 NS_ENSURE_SUCCESS(rv
, rv
);
1759 UniquePtr
<Expr
> caseOrder
;
1760 rv
= getAVTAttr(aAttributes
, aAttrCount
, nsGkAtoms::caseOrder
, false, aState
,
1762 NS_ENSURE_SUCCESS(rv
, rv
);
1764 aState
.mSorter
->addSort(std::move(select
), std::move(lang
),
1765 std::move(dataType
), std::move(order
),
1766 std::move(caseOrder
));
1768 aState
.pushHandlerTable(gTxIgnoreHandler
);
1773 static void txFnEndSort(txStylesheetCompilerState
& aState
) {
1774 aState
.popHandlerTable();
1780 [children] (only txText)
1782 static nsresult
txFnStartText(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1783 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1785 txStylesheetCompilerState
& aState
) {
1786 NS_ASSERTION(!aState
.mDOE
, "nested d-o-e elements should not happen");
1788 nsresult rv
= NS_OK
;
1790 rv
= getYesNoAttr(aAttributes
, aAttrCount
, nsGkAtoms::disableOutputEscaping
,
1791 false, aState
, doe
);
1792 NS_ENSURE_SUCCESS(rv
, rv
);
1794 aState
.mDOE
= doe
== eTrue
;
1796 aState
.pushHandlerTable(gTxTextHandler
);
1801 static void txFnEndText(txStylesheetCompilerState
& aState
) {
1802 aState
.mDOE
= false;
1803 aState
.popHandlerTable();
1806 static nsresult
txFnTextText(const nsAString
& aStr
,
1807 txStylesheetCompilerState
& aState
) {
1808 aState
.addInstruction(MakeUnique
<txText
>(aStr
, aState
.mDOE
));
1818 static nsresult
txFnStartValueOf(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1819 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1821 txStylesheetCompilerState
& aState
) {
1822 nsresult rv
= NS_OK
;
1825 rv
= getYesNoAttr(aAttributes
, aAttrCount
, nsGkAtoms::disableOutputEscaping
,
1826 false, aState
, doe
);
1827 NS_ENSURE_SUCCESS(rv
, rv
);
1829 UniquePtr
<Expr
> select
;
1830 rv
= getExprAttr(aAttributes
, aAttrCount
, nsGkAtoms::select
, true, aState
,
1832 NS_ENSURE_SUCCESS(rv
, rv
);
1834 aState
.addInstruction(MakeUnique
<txValueOf
>(std::move(select
), doe
== eTrue
));
1836 aState
.pushHandlerTable(gTxIgnoreHandler
);
1841 static void txFnEndValueOf(txStylesheetCompilerState
& aState
) {
1842 aState
.popHandlerTable();
1848 txPushRTFHandler --- (for RTF-parameters)
1852 static nsresult
txFnStartVariable(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1854 txStylesheetAttr
* aAttributes
,
1856 txStylesheetCompilerState
& aState
) {
1857 nsresult rv
= NS_OK
;
1859 txExpandedName name
;
1860 rv
= getQNameAttr(aAttributes
, aAttrCount
, nsGkAtoms::name
, true, aState
,
1862 NS_ENSURE_SUCCESS(rv
, rv
);
1864 UniquePtr
<Expr
> select
;
1865 rv
= getExprAttr(aAttributes
, aAttrCount
, nsGkAtoms::select
, false, aState
,
1867 NS_ENSURE_SUCCESS(rv
, rv
);
1869 UniquePtr
<txSetVariable
> var
=
1870 MakeUnique
<txSetVariable
>(name
, std::move(select
));
1872 // XXX should be gTxErrorHandler?
1873 aState
.pushHandlerTable(gTxIgnoreHandler
);
1875 aState
.pushHandlerTable(gTxVariableHandler
);
1878 pushInstruction(aState
, std::move(var
));
1883 static void txFnEndVariable(txStylesheetCompilerState
& aState
) {
1884 UniquePtr
<txSetVariable
> var
= popInstruction
<txSetVariable
>(aState
);
1886 txHandlerTable
* prev
= aState
.mHandlerTable
;
1887 aState
.popHandlerTable();
1889 if (prev
== gTxVariableHandler
) {
1890 // No children were found.
1891 NS_ASSERTION(!var
->mValue
, "There shouldn't be a select-expression here");
1892 var
->mValue
= MakeUnique
<txLiteralExpr
>(u
""_ns
);
1895 aState
.addVariable(var
->mName
);
1897 aState
.addInstruction(std::move(var
));
1900 static nsresult
txFnStartElementStartRTF(int32_t aNamespaceID
,
1901 nsAtom
* aLocalName
, nsAtom
* aPrefix
,
1902 txStylesheetAttr
* aAttributes
,
1904 txStylesheetCompilerState
& aState
) {
1905 aState
.addInstruction(MakeUnique
<txPushRTFHandler
>());
1907 aState
.mHandlerTable
= gTxTemplateHandler
;
1909 return NS_XSLT_GET_NEW_HANDLER
;
1912 static nsresult
txFnTextStartRTF(const nsAString
& aStr
,
1913 txStylesheetCompilerState
& aState
) {
1914 TX_RETURN_IF_WHITESPACE(aStr
, aState
);
1916 aState
.addInstruction(MakeUnique
<txPushRTFHandler
>());
1918 aState
.mHandlerTable
= gTxTemplateHandler
;
1920 return NS_XSLT_GET_NEW_HANDLER
;
1928 static nsresult
txFnStartWhen(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1929 nsAtom
* aPrefix
, txStylesheetAttr
* aAttributes
,
1931 txStylesheetCompilerState
& aState
) {
1932 nsresult rv
= NS_OK
;
1934 UniquePtr
<Expr
> test
;
1936 getExprAttr(aAttributes
, aAttrCount
, nsGkAtoms::test
, true, aState
, test
);
1937 NS_ENSURE_SUCCESS(rv
, rv
);
1939 aState
.pushPtr(aState
.addInstruction(
1940 MakeUnique
<txConditionalGoto
>(std::move(test
), nullptr)),
1941 aState
.eConditionalGoto
);
1943 aState
.pushHandlerTable(gTxTemplateHandler
);
1948 static void txFnEndWhen(txStylesheetCompilerState
& aState
) {
1949 aState
.popHandlerTable();
1950 aState
.mChooseGotoList
->add(
1951 aState
.addInstruction(MakeUnique
<txGoTo
>(nullptr)));
1953 txConditionalGoto
* condGoto
=
1954 static_cast<txConditionalGoto
*>(aState
.popPtr(aState
.eConditionalGoto
));
1955 aState
.addGotoTarget(&condGoto
->mTarget
);
1961 txPushRTFHandler -- for RTF-parameters
1965 static nsresult
txFnStartWithParam(int32_t aNamespaceID
, nsAtom
* aLocalName
,
1967 txStylesheetAttr
* aAttributes
,
1969 txStylesheetCompilerState
& aState
) {
1970 nsresult rv
= NS_OK
;
1972 txExpandedName name
;
1973 rv
= getQNameAttr(aAttributes
, aAttrCount
, nsGkAtoms::name
, true, aState
,
1975 NS_ENSURE_SUCCESS(rv
, rv
);
1977 UniquePtr
<Expr
> select
;
1978 rv
= getExprAttr(aAttributes
, aAttrCount
, nsGkAtoms::select
, false, aState
,
1980 NS_ENSURE_SUCCESS(rv
, rv
);
1982 UniquePtr
<txSetParam
> var
= MakeUnique
<txSetParam
>(name
, std::move(select
));
1984 // XXX should be gTxErrorHandler?
1985 aState
.pushHandlerTable(gTxIgnoreHandler
);
1987 aState
.pushHandlerTable(gTxVariableHandler
);
1990 pushInstruction(aState
, std::move(var
));
1995 static void txFnEndWithParam(txStylesheetCompilerState
& aState
) {
1996 UniquePtr
<txSetParam
> var
= popInstruction
<txSetParam
>(aState
);
1997 txHandlerTable
* prev
= aState
.mHandlerTable
;
1998 aState
.popHandlerTable();
2000 if (prev
== gTxVariableHandler
) {
2001 // No children were found.
2002 NS_ASSERTION(!var
->mValue
, "There shouldn't be a select-expression here");
2003 var
->mValue
= MakeUnique
<txLiteralExpr
>(u
""_ns
);
2006 aState
.addInstruction(std::move(var
));
2012 [fallbacks] if one or more xsl:fallbacks are found
2014 txErrorInstruction otherwise
2016 static nsresult
txFnStartUnknownInstruction(int32_t aNamespaceID
,
2017 nsAtom
* aLocalName
, nsAtom
* aPrefix
,
2018 txStylesheetAttr
* aAttributes
,
2020 txStylesheetCompilerState
& aState
) {
2021 NS_ASSERTION(!aState
.mSearchingForFallback
,
2022 "bad nesting of unknown-instruction and fallback handlers");
2024 if (aNamespaceID
== kNameSpaceID_XSLT
&& !aState
.fcp()) {
2025 return NS_ERROR_XSLT_PARSE_FAILURE
;
2028 aState
.mSearchingForFallback
= true;
2030 aState
.pushHandlerTable(gTxFallbackHandler
);
2035 static void txFnEndUnknownInstruction(txStylesheetCompilerState
& aState
) {
2036 aState
.popHandlerTable();
2038 if (aState
.mSearchingForFallback
) {
2039 aState
.addInstruction(MakeUnique
<txErrorInstruction
>());
2042 aState
.mSearchingForFallback
= false;
2049 struct txHandlerTableData
{
2050 txElementHandler mOtherHandler
;
2051 txElementHandler mLREHandler
;
2052 HandleTextFn mTextHandler
;
2055 const txHandlerTableData gTxIgnoreTableData
= {
2057 {0, 0, txFnStartElementIgnore
, txFnEndElementIgnore
},
2059 {0, 0, txFnStartElementIgnore
, txFnEndElementIgnore
},
2063 const txElementHandler gTxRootElementHandlers
[] = {
2064 {kNameSpaceID_XSLT
, "stylesheet", txFnStartStylesheet
, txFnEndStylesheet
},
2065 {kNameSpaceID_XSLT
, "transform", txFnStartStylesheet
, txFnEndStylesheet
}};
2067 const txHandlerTableData gTxRootTableData
= {
2069 {0, 0, txFnStartElementError
, txFnEndElementError
},
2071 {0, 0, txFnStartLREStylesheet
, txFnEndLREStylesheet
},
2075 const txHandlerTableData gTxEmbedTableData
= {
2077 {0, 0, txFnStartEmbed
, txFnEndEmbed
},
2079 {0, 0, txFnStartEmbed
, txFnEndEmbed
},
2083 const txElementHandler gTxTopElementHandlers
[] = {
2084 {kNameSpaceID_XSLT
, "attribute-set", txFnStartAttributeSet
,
2085 txFnEndAttributeSet
},
2086 {kNameSpaceID_XSLT
, "decimal-format", txFnStartDecimalFormat
,
2087 txFnEndDecimalFormat
},
2088 {kNameSpaceID_XSLT
, "include", txFnStartInclude
, txFnEndInclude
},
2089 {kNameSpaceID_XSLT
, "key", txFnStartKey
, txFnEndKey
},
2090 {kNameSpaceID_XSLT
, "namespace-alias", txFnStartNamespaceAlias
,
2091 txFnEndNamespaceAlias
},
2092 {kNameSpaceID_XSLT
, "output", txFnStartOutput
, txFnEndOutput
},
2093 {kNameSpaceID_XSLT
, "param", txFnStartTopVariable
, txFnEndTopVariable
},
2094 {kNameSpaceID_XSLT
, "preserve-space", txFnStartStripSpace
,
2096 {kNameSpaceID_XSLT
, "strip-space", txFnStartStripSpace
, txFnEndStripSpace
},
2097 {kNameSpaceID_XSLT
, "template", txFnStartTemplate
, txFnEndTemplate
},
2098 {kNameSpaceID_XSLT
, "variable", txFnStartTopVariable
, txFnEndTopVariable
}};
2100 const txHandlerTableData gTxTopTableData
= {
2102 {0, 0, txFnStartOtherTop
, txFnEndOtherTop
},
2104 {0, 0, txFnStartOtherTop
, txFnEndOtherTop
},
2108 const txElementHandler gTxTemplateElementHandlers
[] = {
2109 {kNameSpaceID_XSLT
, "apply-imports", txFnStartApplyImports
,
2110 txFnEndApplyImports
},
2111 {kNameSpaceID_XSLT
, "apply-templates", txFnStartApplyTemplates
,
2112 txFnEndApplyTemplates
},
2113 {kNameSpaceID_XSLT
, "attribute", txFnStartAttribute
, txFnEndAttribute
},
2114 {kNameSpaceID_XSLT
, "call-template", txFnStartCallTemplate
,
2115 txFnEndCallTemplate
},
2116 {kNameSpaceID_XSLT
, "choose", txFnStartChoose
, txFnEndChoose
},
2117 {kNameSpaceID_XSLT
, "comment", txFnStartComment
, txFnEndComment
},
2118 {kNameSpaceID_XSLT
, "copy", txFnStartCopy
, txFnEndCopy
},
2119 {kNameSpaceID_XSLT
, "copy-of", txFnStartCopyOf
, txFnEndCopyOf
},
2120 {kNameSpaceID_XSLT
, "element", txFnStartElement
, txFnEndElement
},
2121 {kNameSpaceID_XSLT
, "fallback", txFnStartElementSetIgnore
,
2122 txFnEndElementSetIgnore
},
2123 {kNameSpaceID_XSLT
, "for-each", txFnStartForEach
, txFnEndForEach
},
2124 {kNameSpaceID_XSLT
, "if", txFnStartIf
, txFnEndIf
},
2125 {kNameSpaceID_XSLT
, "message", txFnStartMessage
, txFnEndMessage
},
2126 {kNameSpaceID_XSLT
, "number", txFnStartNumber
, txFnEndNumber
},
2127 {kNameSpaceID_XSLT
, "processing-instruction", txFnStartPI
, txFnEndPI
},
2128 {kNameSpaceID_XSLT
, "text", txFnStartText
, txFnEndText
},
2129 {kNameSpaceID_XSLT
, "value-of", txFnStartValueOf
, txFnEndValueOf
},
2130 {kNameSpaceID_XSLT
, "variable", txFnStartVariable
, txFnEndVariable
}};
2132 const txHandlerTableData gTxTemplateTableData
= {
2134 {0, 0, txFnStartUnknownInstruction
, txFnEndUnknownInstruction
},
2136 {0, 0, txFnStartLRE
, txFnEndLRE
},
2140 const txHandlerTableData gTxTextTableData
= {
2142 {0, 0, txFnStartElementError
, txFnEndElementError
},
2144 {0, 0, txFnStartElementError
, txFnEndElementError
},
2148 const txElementHandler gTxApplyTemplatesElementHandlers
[] = {
2149 {kNameSpaceID_XSLT
, "sort", txFnStartSort
, txFnEndSort
},
2150 {kNameSpaceID_XSLT
, "with-param", txFnStartWithParam
, txFnEndWithParam
}};
2152 const txHandlerTableData gTxApplyTemplatesTableData
= {
2154 {0, 0, txFnStartElementSetIgnore
,
2155 txFnEndElementSetIgnore
}, // should this be error?
2157 {0, 0, txFnStartElementSetIgnore
, txFnEndElementSetIgnore
},
2161 const txElementHandler gTxCallTemplateElementHandlers
[] = {
2162 {kNameSpaceID_XSLT
, "with-param", txFnStartWithParam
, txFnEndWithParam
}};
2164 const txHandlerTableData gTxCallTemplateTableData
= {
2166 {0, 0, txFnStartElementSetIgnore
,
2167 txFnEndElementSetIgnore
}, // should this be error?
2169 {0, 0, txFnStartElementSetIgnore
, txFnEndElementSetIgnore
},
2173 const txHandlerTableData gTxVariableTableData
= {
2175 {0, 0, txFnStartElementStartRTF
, 0},
2177 {0, 0, txFnStartElementStartRTF
, 0},
2181 const txElementHandler gTxForEachElementHandlers
[] = {
2182 {kNameSpaceID_XSLT
, "sort", txFnStartSort
, txFnEndSort
}};
2184 const txHandlerTableData gTxForEachTableData
= {
2186 {0, 0, txFnStartElementContinueTemplate
, 0},
2188 {0, 0, txFnStartElementContinueTemplate
, 0},
2190 txFnTextContinueTemplate
};
2192 const txHandlerTableData gTxTopVariableTableData
= {
2194 {0, 0, txFnStartElementStartTopVar
, 0},
2196 {0, 0, txFnStartElementStartTopVar
, 0},
2198 txFnTextStartTopVar
};
2200 const txElementHandler gTxChooseElementHandlers
[] = {
2201 {kNameSpaceID_XSLT
, "otherwise", txFnStartOtherwise
, txFnEndOtherwise
},
2202 {kNameSpaceID_XSLT
, "when", txFnStartWhen
, txFnEndWhen
}};
2204 const txHandlerTableData gTxChooseTableData
= {
2206 {0, 0, txFnStartElementError
, 0},
2208 {0, 0, txFnStartElementError
, 0},
2212 const txElementHandler gTxParamElementHandlers
[] = {
2213 {kNameSpaceID_XSLT
, "param", txFnStartParam
, txFnEndParam
}};
2215 const txHandlerTableData gTxParamTableData
= {
2217 {0, 0, txFnStartElementContinueTemplate
, 0},
2219 {0, 0, txFnStartElementContinueTemplate
, 0},
2221 txFnTextContinueTemplate
};
2223 const txElementHandler gTxImportElementHandlers
[] = {
2224 {kNameSpaceID_XSLT
, "import", txFnStartImport
, txFnEndImport
}};
2226 const txHandlerTableData gTxImportTableData
= {
2228 {0, 0, txFnStartElementContinueTopLevel
, 0},
2230 {0, 0, txFnStartOtherTop
, txFnEndOtherTop
}, // XXX what should we do here?
2232 txFnTextIgnore
// XXX what should we do here?
2235 const txElementHandler gTxAttributeSetElementHandlers
[] = {
2236 {kNameSpaceID_XSLT
, "attribute", txFnStartAttribute
, txFnEndAttribute
}};
2238 const txHandlerTableData gTxAttributeSetTableData
= {
2240 {0, 0, txFnStartElementError
, 0},
2242 {0, 0, txFnStartElementError
, 0},
2246 const txElementHandler gTxFallbackElementHandlers
[] = {
2247 {kNameSpaceID_XSLT
, "fallback", txFnStartFallback
, txFnEndFallback
}};
2249 const txHandlerTableData gTxFallbackTableData
= {
2251 {0, 0, txFnStartElementSetIgnore
, txFnEndElementSetIgnore
},
2253 {0, 0, txFnStartElementSetIgnore
, txFnEndElementSetIgnore
},
2260 txHandlerTable::txHandlerTable(const HandleTextFn aTextHandler
,
2261 const txElementHandler
* aLREHandler
,
2262 const txElementHandler
* aOtherHandler
)
2263 : mTextHandler(aTextHandler
),
2264 mLREHandler(aLREHandler
),
2265 mOtherHandler(aOtherHandler
) {}
2267 nsresult
txHandlerTable::init(const txElementHandler
* aHandlers
,
2269 nsresult rv
= NS_OK
;
2272 for (i
= 0; i
< aCount
; ++i
) {
2273 RefPtr
<nsAtom
> nameAtom
= NS_Atomize(aHandlers
->mLocalName
);
2274 txExpandedName
name(aHandlers
->mNamespaceID
, nameAtom
);
2275 rv
= mHandlers
.add(name
, aHandlers
);
2276 NS_ENSURE_SUCCESS(rv
, rv
);
2283 const txElementHandler
* txHandlerTable::find(int32_t aNamespaceID
,
2284 nsAtom
* aLocalName
) {
2285 txExpandedName
name(aNamespaceID
, aLocalName
);
2286 const txElementHandler
* handler
= mHandlers
.get(name
);
2288 handler
= mOtherHandler
;
2293 #define INIT_HANDLER(_name) \
2294 gTx##_name##Handler = new txHandlerTable( \
2295 gTx##_name##TableData.mTextHandler, &gTx##_name##TableData.mLREHandler, \
2296 &gTx##_name##TableData.mOtherHandler); \
2297 if (!gTx##_name##Handler) return false
2299 #define INIT_HANDLER_WITH_ELEMENT_HANDLERS(_name) \
2300 INIT_HANDLER(_name); \
2302 rv = gTx##_name##Handler->init(gTx##_name##ElementHandlers, \
2303 ArrayLength(gTx##_name##ElementHandlers)); \
2304 if (NS_FAILED(rv)) return false
2306 #define SHUTDOWN_HANDLER(_name) \
2307 delete gTx##_name##Handler; \
2308 gTx##_name##Handler = nullptr
2311 bool txHandlerTable::init() {
2312 nsresult rv
= NS_OK
;
2314 INIT_HANDLER_WITH_ELEMENT_HANDLERS(Root
);
2315 INIT_HANDLER(Embed
);
2316 INIT_HANDLER_WITH_ELEMENT_HANDLERS(Top
);
2317 INIT_HANDLER(Ignore
);
2318 INIT_HANDLER_WITH_ELEMENT_HANDLERS(Template
);
2320 INIT_HANDLER_WITH_ELEMENT_HANDLERS(ApplyTemplates
);
2321 INIT_HANDLER_WITH_ELEMENT_HANDLERS(CallTemplate
);
2322 INIT_HANDLER(Variable
);
2323 INIT_HANDLER_WITH_ELEMENT_HANDLERS(ForEach
);
2324 INIT_HANDLER(TopVariable
);
2325 INIT_HANDLER_WITH_ELEMENT_HANDLERS(Choose
);
2326 INIT_HANDLER_WITH_ELEMENT_HANDLERS(Param
);
2327 INIT_HANDLER_WITH_ELEMENT_HANDLERS(Import
);
2328 INIT_HANDLER_WITH_ELEMENT_HANDLERS(AttributeSet
);
2329 INIT_HANDLER_WITH_ELEMENT_HANDLERS(Fallback
);
2335 void txHandlerTable::shutdown() {
2336 SHUTDOWN_HANDLER(Root
);
2337 SHUTDOWN_HANDLER(Embed
);
2338 SHUTDOWN_HANDLER(Top
);
2339 SHUTDOWN_HANDLER(Ignore
);
2340 SHUTDOWN_HANDLER(Template
);
2341 SHUTDOWN_HANDLER(Text
);
2342 SHUTDOWN_HANDLER(ApplyTemplates
);
2343 SHUTDOWN_HANDLER(CallTemplate
);
2344 SHUTDOWN_HANDLER(Variable
);
2345 SHUTDOWN_HANDLER(ForEach
);
2346 SHUTDOWN_HANDLER(TopVariable
);
2347 SHUTDOWN_HANDLER(Choose
);
2348 SHUTDOWN_HANDLER(Param
);
2349 SHUTDOWN_HANDLER(Import
);
2350 SHUTDOWN_HANDLER(AttributeSet
);
2351 SHUTDOWN_HANDLER(Fallback
);