@@ -32,6 +32,92 @@ import {createRenderView, NodeFactory} from '../view_factory';
3232import { DefaultRenderView , DefaultRenderFragmentRef , DefaultProtoViewRef } from '../view' ;
3333import { camelCaseToDashCase } from './util' ;
3434
35+ // TODO(tbosch): solve SVG properly once https://github.com/angular/angular/issues/4417 is done
36+ const XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink' ;
37+ const SVG_NAMESPACE = 'http://www.w3.org/2000/svg' ;
38+ const SVG_ELEMENT_NAMES = CONST_EXPR ( {
39+ 'altGlyph' : true ,
40+ 'altGlyphDef' : true ,
41+ 'altGlyphItem' : true ,
42+ 'animate' : true ,
43+ 'animateColor' : true ,
44+ 'animateMotion' : true ,
45+ 'animateTransform' : true ,
46+ 'circle' : true ,
47+ 'clipPath' : true ,
48+ 'color-profile' : true ,
49+ 'cursor' : true ,
50+ 'defs' : true ,
51+ 'desc' : true ,
52+ 'ellipse' : true ,
53+ 'feBlend' : true ,
54+ 'feColorMatrix' : true ,
55+ 'feComponentTransfer' : true ,
56+ 'feComposite' : true ,
57+ 'feConvolveMatrix' : true ,
58+ 'feDiffuseLighting' : true ,
59+ 'feDisplacementMap' : true ,
60+ 'feDistantLight' : true ,
61+ 'feFlood' : true ,
62+ 'feFuncA' : true ,
63+ 'feFuncB' : true ,
64+ 'feFuncG' : true ,
65+ 'feFuncR' : true ,
66+ 'feGaussianBlur' : true ,
67+ 'feImage' : true ,
68+ 'feMerge' : true ,
69+ 'feMergeNode' : true ,
70+ 'feMorphology' : true ,
71+ 'feOffset' : true ,
72+ 'fePointLight' : true ,
73+ 'feSpecularLighting' : true ,
74+ 'feSpotLight' : true ,
75+ 'feTile' : true ,
76+ 'feTurbulence' : true ,
77+ 'filter' : true ,
78+ 'font' : true ,
79+ 'font-face' : true ,
80+ 'font-face-format' : true ,
81+ 'font-face-name' : true ,
82+ 'font-face-src' : true ,
83+ 'font-face-uri' : true ,
84+ 'foreignObject' : true ,
85+ 'g' : true ,
86+ 'glyph' : true ,
87+ 'glyphRef' : true ,
88+ 'hkern' : true ,
89+ 'image' : true ,
90+ 'line' : true ,
91+ 'linearGradient' : true ,
92+ 'marker' : true ,
93+ 'mask' : true ,
94+ 'metadata' : true ,
95+ 'missing-glyph' : true ,
96+ 'mpath' : true ,
97+ 'path' : true ,
98+ 'pattern' : true ,
99+ 'polygon' : true ,
100+ 'polyline' : true ,
101+ 'radialGradient' : true ,
102+ 'rect' : true ,
103+ 'set' : true ,
104+ 'stop' : true ,
105+ 'style' : true ,
106+ 'svg' : true ,
107+ 'switch' : true ,
108+ 'symbol' : true ,
109+ 'text' : true ,
110+ 'textPath' : true ,
111+ 'title' : true ,
112+ 'tref' : true ,
113+ 'tspan' : true ,
114+ 'use' : true ,
115+ 'view' : true ,
116+ 'vkern' : true
117+ } ) ;
118+
119+ const SVG_ATTR_NAMESPACES = CONST_EXPR ( { 'href' : XLINK_NAMESPACE } ) ;
120+
35121export abstract class DomRenderer extends Renderer implements NodeFactory < Node > {
36122 abstract registerComponentTemplate ( templateId : number , commands : RenderTemplateCmd [ ] ,
37123 styles : string [ ] , nativeShadow : boolean ) ;
@@ -271,17 +357,25 @@ export class DomRenderer_ extends DomRenderer {
271357 wtfLeave ( s ) ;
272358 }
273359 createElement ( name : string , attrNameAndValues : string [ ] ) : Node {
274- var el = DOM . createElement ( name ) ;
275- this . _setAttributes ( el , attrNameAndValues ) ;
360+ var isSvg = SVG_ELEMENT_NAMES [ name ] == true ;
361+ var el = isSvg ? DOM . createElementNS ( SVG_NAMESPACE , name ) : DOM . createElement ( name ) ;
362+ this . _setAttributes ( el , attrNameAndValues , isSvg ) ;
276363 return el ;
277364 }
278365 mergeElement ( existing : Node , attrNameAndValues : string [ ] ) {
279366 DOM . clearNodes ( existing ) ;
280- this . _setAttributes ( existing , attrNameAndValues ) ;
367+ this . _setAttributes ( existing , attrNameAndValues , false ) ;
281368 }
282- private _setAttributes ( node : Node , attrNameAndValues : string [ ] ) {
369+ private _setAttributes ( node : Node , attrNameAndValues : string [ ] , isSvg : boolean ) {
283370 for ( var attrIdx = 0 ; attrIdx < attrNameAndValues . length ; attrIdx += 2 ) {
284- DOM . setAttribute ( node , attrNameAndValues [ attrIdx ] , attrNameAndValues [ attrIdx + 1 ] ) ;
371+ var attrName = attrNameAndValues [ attrIdx ] ;
372+ var attrValue = attrNameAndValues [ attrIdx + 1 ] ;
373+ var attrNs = isSvg ? SVG_ATTR_NAMESPACES [ attrName ] : null ;
374+ if ( isPresent ( attrNs ) ) {
375+ DOM . setAttributeNS ( node , XLINK_NAMESPACE , attrName , attrValue ) ;
376+ } else {
377+ DOM . setAttribute ( node , attrName , attrValue ) ;
378+ }
285379 }
286380 }
287381 createRootContentInsertionPoint ( ) : Node {
0 commit comments