@@ -5,11 +5,39 @@ import XRegExp = require('xregexp');
55
66export class XmlPatcher implements patch . IPatcher {
77 constructor (
8- private patches : patch . IPatch [ ] ,
8+ public patches : patch . IPatch [ ] ,
99 private namespaces : { [ tag : string ] : string }
1010 ) {
1111 }
1212
13+ detectArrayOperation ( path : string ) : { path : string , isArrayOperation : boolean , append ?: boolean , index ?: number } {
14+ var lastSlash = path . lastIndexOf ( '/' ) ;
15+ var lastFragment = path . substr ( lastSlash + 1 ) ;
16+ var remainingPath = path . substr ( 0 , lastSlash ) ;
17+
18+ console . log ( lastFragment ) ;
19+ if ( lastFragment == '-' ) {
20+ return {
21+ path : remainingPath ,
22+ isArrayOperation : true ,
23+ append : true
24+ } ;
25+ }
26+
27+ if ( XRegExp . match ( lastFragment , / ^ \d + $ / g) ) {
28+ return {
29+ path : remainingPath ,
30+ isArrayOperation : true ,
31+ index : parseInt ( lastFragment )
32+ } ;
33+ }
34+
35+ return {
36+ path : path ,
37+ isArrayOperation : false
38+ } ;
39+ }
40+
1341 getParentPath ( path : string ) : { path : string , nodeName : string , isAttribute : boolean } {
1442 var lastSlash = path . lastIndexOf ( '/' ) ;
1543 var nodeName = path . substr ( lastSlash + 1 ) ;
@@ -27,11 +55,28 @@ export class XmlPatcher implements patch.IPatcher {
2755 }
2856
2957 remove ( xml : Document , select : any , patch : patch . IPatch ) : boolean {
58+ var arrayOperation = this . detectArrayOperation ( patch . path ) ;
59+ console . log ( JSON . stringify ( arrayOperation ) ) ;
60+ if ( arrayOperation . isArrayOperation ) {
61+ if ( arrayOperation . append ) {
62+ var node = < SVGSVGElement > select ( arrayOperation . path , xml , true ) ;
63+ node . removeChild ( node . lastChild ) ;
64+ console . log ( 'arrayOperation.path' ) ;
65+ console . log ( node ) ;
66+ console . log ( 'remove lastchild' ) ;
67+ return true ;
68+ } else {
69+ var node = < SVGSVGElement > select ( arrayOperation . path , xml , true ) ;
70+ node . removeChild ( node . childNodes [ arrayOperation . index ] ) ;
71+ return true ;
72+ }
73+ }
74+
3075 var node = < SVGSVGElement > select ( patch . path , xml , true ) ;
3176 if ( node ) {
3277 var parentPath = this . getParentPath ( patch . path ) ;
3378 var parentNode = < SVGSVGElement > select ( parentPath . path , xml , true ) ;
34- if ( parentPath . isAttribute ) {
79+ if ( parentPath . isAttribute ) {
3580 parentNode . removeAttribute ( parentPath . nodeName ) ;
3681 } else {
3782 node . parentNode . removeChild ( node ) ;
@@ -47,7 +92,7 @@ export class XmlPatcher implements patch.IPatcher {
4792 var toNode = < SVGSVGElement > select ( patch . path , xml , true ) ;
4893 if ( fromNode ) {
4994 patch . value = fromNode . textContent ;
50- this . remove ( xml , select , { op : 'remove' , path : patch . from } ) ;
95+ this . remove ( xml , select , { op : 'remove' , path : patch . from } ) ;
5196 return this . replace ( xml , select , patch ) ;
5297 } else {
5398 return this . notfound ( patch ) ;
@@ -66,6 +111,23 @@ export class XmlPatcher implements patch.IPatcher {
66111 }
67112
68113 add ( xml : Document , select : any , patch : patch . IPatch ) : boolean {
114+ var arrayOperation = this . detectArrayOperation ( patch . path ) ;
115+ console . log ( JSON . stringify ( arrayOperation ) ) ;
116+ if ( arrayOperation . isArrayOperation ) {
117+ if ( arrayOperation . append ) {
118+ var node = < SVGSVGElement > select ( arrayOperation . path , xml , true ) ;
119+ var newNode = xml . createElement ( patch . value ) ;
120+ node . appendChild ( newNode ) ;
121+ return true ;
122+ } else {
123+ var node = < SVGSVGElement > select ( arrayOperation . path , xml , true ) ;
124+ var newNode = xml . createElement ( patch . value ) ;
125+ node . insertBefore ( newNode , node . childNodes [ arrayOperation . index ] )
126+ node . appendChild ( newNode ) ;
127+ return true ;
128+ }
129+ }
130+
69131 var node = < SVGSVGElement > select ( patch . path , xml , true ) ;
70132 if ( node ) {
71133 node . textContent = patch . value ;
@@ -96,10 +158,10 @@ export class XmlPatcher implements patch.IPatcher {
96158 if ( node ) {
97159 var parentPath = this . getParentPath ( patch . path ) ;
98160 var parentNode = < SVGSVGElement > select ( parentPath . path , xml , true ) ;
99- if ( parentPath . isAttribute ) {
161+ if ( parentPath . isAttribute ) {
100162 parentNode . setAttribute ( parentPath . nodeName , patch . value ) ;
101163 } else {
102- node . textContent = patch . value ;
164+ node . textContent = patch . value ;
103165 }
104166 return true ;
105167 } else {
@@ -135,12 +197,12 @@ export class XmlPatcher implements patch.IPatcher {
135197 } else if ( patch . op == 'test' ) {
136198 operation = this . test . bind ( this ) ;
137199 }
138-
200+
139201 if ( ! operation ( xml , select , patch ) ) {
140202 throw new Error ( "Failed to patch xml file" ) ;
141203 }
142204 }
143-
205+
144206 return new xmldom . XMLSerializer ( ) . serializeToString ( xml ) ;
145207 }
146208}
0 commit comments