@@ -26,6 +26,12 @@ describe('$compile', function() {
2626 return ! isUnknownElement ( d . firstChild ) ;
2727 }
2828
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+
2935 var element , directive , $compile , $rootScope ;
3036
3137 beforeEach ( module ( provideLog , function ( $provide , $compileProvider ) {
@@ -80,6 +86,45 @@ describe('$compile', function() {
8086 terminal : true
8187 } ) ) ;
8288
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+
83128 return function ( _$compile_ , _$rootScope_ ) {
84129 $rootScope = _$rootScope_ ;
85130 $compile = _$compile_ ;
@@ -154,6 +199,105 @@ describe('$compile', function() {
154199 } ) ;
155200
156201
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+
157301 describe ( 'compile phase' , function ( ) {
158302
159303 it ( 'should attach scope to the document node when it is compiled explicitly' , inject ( function ( $document ) {
0 commit comments