angularjssvgng-bind-htmltspan

ng-bind-html in a svg text tag do not display tspan in firefox and IE


I can't succeed in build an svg with angularjs when tspan are load from ng-bind-html attribute, Firefox and IE do not display them.

My controler look like that :

$scope.titlenotok="svg not ok";
var content = '<tspan dy="20" x="0"  xml:space="preserve">line1 not ok</tspan><tspan dy="30" x="0"  xml:space="preserve">line 2 not ok</tspan>'
$scope.notok = $sce.trustAsHtml(content);

I create a fiddle to illustrate

http://jsfiddle.net/3WNhT/

For chrome it's OK.


Solution

  • Robert was right.

    Here is my solution. The secret was to use createElementNS. so that, The browser understand that it is a svg element and not a html element.

    Here is the directive

    app.directive('multilinesvgtext',  function () {
        var xmlns = "http://www.w3.org/2000/svg";
        var myLink = function (scope, elem, attrs) {
    
            attrs.$observe('contenu', function (val) {
                var data = val;
    
                var generateTSpan = function (lineOftext) {
                    var tspanElement = document.createElementNS(xmlns, 'tspan');
                    tspanElement.setAttribute('x', attrs.x);
                    tspanElement.setAttribute('dy', attrs.dy);
                    tspanElement.setAttribute('class', attrs.class);
                    tspanElement.setAttribute('xml:space', 'preserve');
                    var tspanContent = document.createTextNode(lineOftext);
                    tspanElement.appendChild(tspanContent);
                    return tspanElement;
                };
                // We delete the old children
                while (elem[0].firstChild) {
                    elem[0].removeChild(elem[0].firstChild);
                }
                var lines = data.split('\n');
                for(var i= 0; i < lines.length; i++)
                {
                    var textContent = lines[i]!=='' ? lines[i] : ' ';
                    var newTspanElement = generateTSpan(textContent);
                    elem[0].appendChild(newTspanElement);
                }
            });
        };
        return {
            restrict: 'A',
            link: myLink
        };
     }
    );
    

    Which can be uses like that :

    <text multilinesvgtext  x="30" y="168" fill="#FFFFFF" data-dy="13" class="myclass" data-contenu="{{mydata}}"></text>
    

    My directive add tspan children for each line of text in mydata and use data-dy attribute as dy attribute for this tspan.