@@ -26,6 +26,12 @@ describe('$compile', function() {
26
26
return ! isUnknownElement ( d . firstChild ) ;
27
27
}
28
28
29
+ // IE9-11 do not support foreignObject in svg...
30
+ function supportsForeignObject ( ) {
31
+ var d = document . createElementNS ( 'http://www.w3.org/2000/svg' , 'foreignObject' ) ;
32
+ return ! ! d . toString ( ) . match ( / S V G F o r e i g n O b j e c t / ) ;
33
+ }
34
+
29
35
var element , directive , $compile , $rootScope ;
30
36
31
37
beforeEach ( module ( provideLog , function ( $provide , $compileProvider ) {
@@ -80,6 +86,45 @@ describe('$compile', function() {
80
86
terminal : true
81
87
} ) ) ;
82
88
89
+ directive ( 'svgContainer' , function ( ) {
90
+ return {
91
+ template : '<svg width="400" height="400" ng-transclude></svg>' ,
92
+ replace : true ,
93
+ transclude : true
94
+ } ;
95
+ } ) ;
96
+
97
+ directive ( 'svgCustomTranscludeContainer' , function ( ) {
98
+ return {
99
+ template : '<svg width="400" height="400"></svg>' ,
100
+ transclude : true ,
101
+ link : function ( scope , element , attr , ctrls , $transclude ) {
102
+ var futureParent = element . children ( ) . eq ( 0 ) ;
103
+ $transclude ( function ( clone ) {
104
+ futureParent . append ( clone ) ;
105
+ } , futureParent ) ;
106
+ }
107
+ } ;
108
+ } ) ;
109
+
110
+ directive ( 'svgCircle' , function ( ) {
111
+ return {
112
+ template : '<circle cx="2" cy="2" r="1"></circle>' ,
113
+ templateNamespace : 'svg' ,
114
+ replace : true
115
+ } ;
116
+ } ) ;
117
+
118
+ directive ( 'myForeignObject' , function ( ) {
119
+ return {
120
+ template : '<foreignObject width="100" height="100" ng-transclude></foreignObject>' ,
121
+ templateNamespace : 'svg' ,
122
+ replace : true ,
123
+ transclude : true
124
+ } ;
125
+ } ) ;
126
+
127
+
83
128
return function ( _$compile_ , _$rootScope_ ) {
84
129
$rootScope = _$rootScope_ ;
85
130
$compile = _$compile_ ;
@@ -154,6 +199,105 @@ describe('$compile', function() {
154
199
} ) ;
155
200
156
201
202
+ describe ( 'svg namespace transcludes' , function ( ) {
203
+ // this method assumes some sort of sized SVG element is being inspected.
204
+ function assertIsValidSvgCircle ( elem ) {
205
+ expect ( isUnknownElement ( elem ) ) . toBe ( false ) ;
206
+ expect ( isSVGElement ( elem ) ) . toBe ( true ) ;
207
+ var box = elem . getBoundingClientRect ( ) ;
208
+ expect ( box . width === 0 && box . height === 0 ) . toBe ( false ) ;
209
+ }
210
+
211
+ it ( 'should handle transcluded svg elements' , inject ( function ( $compile ) {
212
+ element = jqLite ( '<div><svg-container>' +
213
+ '<circle cx="4" cy="4" r="2"></circle>' +
214
+ '</svg-container></div>' ) ;
215
+ $compile ( element . contents ( ) ) ( $rootScope ) ;
216
+ document . body . appendChild ( element [ 0 ] ) ;
217
+
218
+ var circle = element . find ( 'circle' ) ;
219
+
220
+ assertIsValidSvgCircle ( circle [ 0 ] ) ;
221
+ } ) ) ;
222
+
223
+ it ( 'should handle custom svg elements inside svg tag' , inject ( function ( ) {
224
+ element = jqLite ( '<div><svg width="300" height="300">' +
225
+ '<svg-circle></svg-circle>' +
226
+ '</svg></div>' ) ;
227
+ $compile ( element . contents ( ) ) ( $rootScope ) ;
228
+ document . body . appendChild ( element [ 0 ] ) ;
229
+
230
+ var circle = element . find ( 'circle' ) ;
231
+ assertIsValidSvgCircle ( circle [ 0 ] ) ;
232
+ } ) ) ;
233
+
234
+ it ( 'should handle transcluded custom svg elements' , inject ( function ( ) {
235
+ element = jqLite ( '<div><svg-container>' +
236
+ '<svg-circle></svg-circle>' +
237
+ '</svg-container></div>' ) ;
238
+ $compile ( element . contents ( ) ) ( $rootScope ) ;
239
+ document . body . appendChild ( element [ 0 ] ) ;
240
+
241
+ var circle = element . find ( 'circle' ) ;
242
+ assertIsValidSvgCircle ( circle [ 0 ] ) ;
243
+ } ) ) ;
244
+
245
+ if ( supportsForeignObject ( ) ) {
246
+ it ( 'should handle foreignObject' , inject ( function ( ) {
247
+ element = jqLite ( '<div><svg-container>' +
248
+ '<foreignObject width="100" height="100"><div class="test" style="position:absolute;width:20px;height:20px">test</div></foreignObject>' +
249
+ '</svg-container></div>' ) ;
250
+ $compile ( element . contents ( ) ) ( $rootScope ) ;
251
+ document . body . appendChild ( element [ 0 ] ) ;
252
+
253
+ var testElem = element . find ( 'div' ) ;
254
+ expect ( isHTMLElement ( testElem [ 0 ] ) ) . toBe ( true ) ;
255
+ var bounds = testElem [ 0 ] . getBoundingClientRect ( ) ;
256
+ expect ( bounds . width === 20 && bounds . height === 20 ) . toBe ( true ) ;
257
+ } ) ) ;
258
+
259
+ it ( 'should handle custom svg containers that transclude to foreignObject that transclude html' , inject ( function ( ) {
260
+ element = jqLite ( '<div><svg-container>' +
261
+ '<my-foreign-object><div class="test" style="width:20px;height:20px">test</div></my-foreign-object>' +
262
+ '</svg-container></div>' ) ;
263
+ $compile ( element . contents ( ) ) ( $rootScope ) ;
264
+ document . body . appendChild ( element [ 0 ] ) ;
265
+
266
+ var testElem = element . find ( 'div' ) ;
267
+ expect ( isHTMLElement ( testElem [ 0 ] ) ) . toBe ( true ) ;
268
+ var bounds = testElem [ 0 ] . getBoundingClientRect ( ) ;
269
+ expect ( bounds . width === 20 && bounds . height === 20 ) . toBe ( true ) ;
270
+ } ) ) ;
271
+
272
+ // NOTE: This test may be redundant.
273
+ it ( 'should handle custom svg containers that transclude to foreignObject' +
274
+ ' that transclude to custom svg containers that transclude to custom elements' , inject ( function ( ) {
275
+ element = jqLite ( '<div><svg-container>' +
276
+ '<my-foreign-object><svg-container><svg-circle></svg-circle></svg-container></my-foreign-object>' +
277
+ '</svg-container></div>' ) ;
278
+ $compile ( element . contents ( ) ) ( $rootScope ) ;
279
+ document . body . appendChild ( element [ 0 ] ) ;
280
+
281
+ var circle = element . find ( 'circle' ) ;
282
+ assertIsValidSvgCircle ( circle [ 0 ] ) ;
283
+ } ) ) ;
284
+ }
285
+
286
+ it ( 'should handle directives with templates that manually add the transclude further down' , inject ( function ( ) {
287
+ element = jqLite ( '<div><svg-custom-transclude-container>' +
288
+ '<circle cx="2" cy="2" r="1"></circle></svg-custom-transclude-container>' +
289
+ '</div>' ) ;
290
+ $compile ( element . contents ( ) ) ( $rootScope ) ;
291
+ document . body . appendChild ( element [ 0 ] ) ;
292
+
293
+ var circle = element . find ( 'circle' ) ;
294
+ assertIsValidSvgCircle ( circle [ 0 ] ) ;
295
+
296
+ } ) ) ;
297
+
298
+ } ) ;
299
+
300
+
157
301
describe ( 'compile phase' , function ( ) {
158
302
159
303
it ( 'should attach scope to the document node when it is compiled explicitly' , inject ( function ( $document ) {
0 commit comments