@@ -126,12 +126,12 @@ export class Xslt {
126
126
}
127
127
128
128
this . xsltProcessContext ( expressionContext , stylesheet , outputDocument ) ;
129
- const ret = xmlTransformedText ( outputDocument , {
129
+ const transformedOutputXml = xmlTransformedText ( outputDocument , {
130
130
cData : false ,
131
131
escape : this . options . escape ,
132
132
selfClosingTags : this . options . selfClosingTags
133
133
} ) ;
134
- return ret ;
134
+ return transformedOutputXml ;
135
135
}
136
136
137
137
/**
@@ -202,17 +202,25 @@ export class Xslt {
202
202
const modifiedContext = context . clone ( nodes ) ;
203
203
for ( let i = 0 ; i < templates . length ; ++ i ) {
204
204
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
+ }
216
224
}
217
225
}
218
226
@@ -522,24 +530,6 @@ export class Xslt {
522
530
for ( let i = 0 ; i < sortContext . contextSize ( ) ; ++ i ) {
523
531
this . xsltChildNodes ( sortContext . clone ( sortContext . nodeList , undefined , i ) , template , output ) ;
524
532
}
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
- } , { } ) ;
543
533
}
544
534
545
535
/**
@@ -654,6 +644,28 @@ export class Xslt {
654
644
}
655
645
}
656
646
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
+
657
669
/**
658
670
* Passes template text to the output. The current template node does
659
671
* not specify an XSL-T operation and therefore is appended to the
@@ -666,22 +678,10 @@ export class Xslt {
666
678
protected xsltPassThrough ( context : ExprContext , template : XNode , output : XNode ) {
667
679
if ( template . nodeType == DOM_TEXT_NODE ) {
668
680
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 ) ;
681
682
}
682
683
} else if ( template . nodeType == DOM_ELEMENT_NODE ) {
683
684
let node : XNode ;
684
- // let node = domCreateElement(outputDocument, template.nodeName);
685
685
let elementContext = context ;
686
686
if ( context . nodeList [ context . position ] . nodeName === '#document' ) {
687
687
node = context . nodeList [ context . position ] . firstChild ;
0 commit comments