@@ -126,12 +126,12 @@ export class Xslt {
126126 }
127127
128128 this . xsltProcessContext ( expressionContext , stylesheet , outputDocument ) ;
129- const ret = xmlTransformedText ( outputDocument , {
129+ const transformedOutputXml = xmlTransformedText ( outputDocument , {
130130 cData : false ,
131131 escape : this . options . escape ,
132132 selfClosingTags : this . options . selfClosingTags
133133 } ) ;
134- return ret ;
134+ return transformedOutputXml ;
135135 }
136136
137137 /**
@@ -202,17 +202,25 @@ export class Xslt {
202202 const modifiedContext = context . clone ( nodes ) ;
203203 for ( let i = 0 ; i < templates . length ; ++ i ) {
204204 for ( let j = 0 ; j < modifiedContext . contextSize ( ) ; ++ j ) {
205- const clonedContext = modifiedContext . clone (
206- [ modifiedContext . nodeList [ j ] ] ,
207- undefined ,
208- 0 ,
209- undefined
210- ) ;
211- clonedContext . inApplyTemplates = true ;
212- // The output depth should be restarted, since
213- // another template is being applied from this point.
214- clonedContext . outputDepth = 0 ;
215- this . xsltProcessContext ( clonedContext , templates [ i ] , output ) ;
205+ // If the current node is text, there's no need to test all the templates
206+ // against it. Just appending it to its parent is fine.
207+ if ( modifiedContext . nodeList [ j ] . nodeType === DOM_TEXT_NODE ) {
208+ const textNodeContext = context . clone ( [ modifiedContext . nodeList [ j ] ] , undefined , 0 , undefined ) ;
209+ // TODO: verify if it is okay to pass the own text node as template.
210+ this . commonLogicTextNode ( textNodeContext , modifiedContext . nodeList [ j ] ) ;
211+ } else {
212+ const clonedContext = modifiedContext . clone (
213+ [ modifiedContext . nodeList [ j ] ] ,
214+ undefined ,
215+ 0 ,
216+ undefined
217+ ) ;
218+ clonedContext . inApplyTemplates = true ;
219+ // The output depth should be restarted, since
220+ // another template is being applied from this point.
221+ clonedContext . outputDepth = 0 ;
222+ this . xsltProcessContext ( clonedContext , templates [ i ] , output ) ;
223+ }
216224 }
217225 }
218226
@@ -522,24 +530,6 @@ export class Xslt {
522530 for ( let i = 0 ; i < sortContext . contextSize ( ) ; ++ i ) {
523531 this . xsltChildNodes ( sortContext . clone ( sortContext . nodeList , undefined , i ) , template , output ) ;
524532 }
525- // TODO: group nodes by parent node.
526- // const nodeGroups = this.groupBy(nodes, 'parentNode');
527-
528- /* for (let [group, _nodes] of Object.entries(nodeGroups)) {
529- const sortContext = context.clone(_nodes, 0);
530- this.xsltSort(sortContext, template);
531-
532- for (let i = 0; i < sortContext.contextSize(); ++i) {
533- this.xsltChildNodes(sortContext.clone(sortContext.nodeList, i), template, output);
534- }
535- } */
536- }
537-
538- protected groupBy ( xs : any , key : any ) {
539- return xs . reduce ( ( rv , x ) => {
540- ( rv [ x [ key ] ] = rv [ x [ key ] ] || [ ] ) . push ( x ) ;
541- return rv ;
542- } , { } ) ;
543533 }
544534
545535 /**
@@ -654,6 +644,28 @@ export class Xslt {
654644 }
655645 }
656646
647+ /**
648+ * This logic is used in two different places:
649+ * - `xsltPassThrough`, if the template asks this library to write a text node;
650+ * - `xsltProcessContext`, `apply-templates` operation, when the current node is text.
651+ * @param context The Expression Context.
652+ * @param template The template, that contains the node value to be written.
653+ */
654+ private commonLogicTextNode ( context : ExprContext , template : XNode ) {
655+ const textNodeList = context . outputNodeList [ context . outputPosition ] . transformedChildNodes . filter (
656+ ( n ) => n . nodeType === DOM_TEXT_NODE
657+ ) ;
658+
659+ if ( textNodeList . length > 0 ) {
660+ let node = textNodeList [ 0 ] ;
661+ node . transformedNodeValue = template . nodeValue ;
662+ } else {
663+ let node = domCreateTransformedTextNode ( this . outputDocument , template . nodeValue ) ;
664+ node . transformedParentNode = context . outputNodeList [ context . outputPosition ] ;
665+ domAppendTransformedChild ( context . outputNodeList [ context . outputPosition ] , node ) ;
666+ }
667+ }
668+
657669 /**
658670 * Passes template text to the output. The current template node does
659671 * not specify an XSL-T operation and therefore is appended to the
@@ -666,22 +678,10 @@ export class Xslt {
666678 protected xsltPassThrough ( context : ExprContext , template : XNode , output : XNode ) {
667679 if ( template . nodeType == DOM_TEXT_NODE ) {
668680 if ( this . xsltPassText ( template ) ) {
669- const textNodeList = context . outputNodeList [ context . outputPosition ] . transformedChildNodes . filter (
670- ( n ) => n . nodeType === DOM_TEXT_NODE
671- ) ;
672-
673- if ( textNodeList . length > 0 ) {
674- let node = textNodeList [ 0 ] ;
675- node . transformedNodeValue = template . nodeValue ;
676- } else {
677- let node = domCreateTransformedTextNode ( this . outputDocument , template . nodeValue ) ;
678- node . transformedParentNode = context . outputNodeList [ context . outputPosition ] ;
679- domAppendTransformedChild ( context . outputNodeList [ context . outputPosition ] , node ) ;
680- }
681+ this . commonLogicTextNode ( context , template ) ;
681682 }
682683 } else if ( template . nodeType == DOM_ELEMENT_NODE ) {
683684 let node : XNode ;
684- // let node = domCreateElement(outputDocument, template.nodeName);
685685 let elementContext = context ;
686686 if ( context . nodeList [ context . position ] . nodeName === '#document' ) {
687687 node = context . nodeList [ context . position ] . firstChild ;
0 commit comments