Discussion:
SCE, concatonation, and interpolation of attributes not working for svg xlinks
Christopher Piggott
2013-11-07 16:06:43 UTC
Permalink
Hi,

I use a lot of templates (including pieces brought in with ng-include) that
include SVG. I've gotten into the habit of naming elements using the scope
ID as part of the name, because it allows me to distinguish them when there
are multiple instances of the template on the page (like widgets). Example:

<g id="tank{{$id}}"> ... </g>

Sometimes I do this in a definition:

<defs>
<g id="tank{{$id}}"> ... </g>
</defs>


As of 1.2, though, this doesn't work. Interpolation the id seems to work
fine without errors, but this fails:

<use x="200" y="150" xlink:href="#tank{{$id}}"/>

This fails because of the concatonation in the interpolation.

Error: [$interpolate:noconcat] Error while interpolating: #tank{{$id}}
Strict Contextual Escaping disallows interpolations that concatenate
multiple expressions when a trusted value is required.
See http://docs.angularjs.org/api/ng.$sce

It is not clear to me from the documentation how I am supposed to handle
this. What I really want to do is tell it that if it's an xlink:href
that's OK. What I do NOT want to do is to disable $sce entirely.

--Chris
--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+***@googlegroups.com.
To post to this group, send email to ***@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.
Christopher Piggott
2013-11-08 17:30:42 UTC
Permalink
I came up with a workaround. It goes like this:

<defs> <g id="{{ makeId('tank') }}"> ... </g> </defs>

<use x=0 y=0 xlink:href="{{ makeId('#tank') }}"/>

Note that there is a # in the use but not in the id. The scope function
that makes this happen is:

$scope.makeId = function(prefix) { return prefix + "$" + $scope.$id; }

I don't feel great about this solution, though it does get me going for now.

--Chris
Post by Christopher Piggott
Hi,
I use a lot of templates (including pieces brought in with ng-include)
that include SVG. I've gotten into the habit of naming elements using the
scope ID as part of the name, because it allows me to distinguish them when
there are multiple instances of the template on the page (like widgets).
<g id="tank{{$id}}"> ... </g>
<defs>
<g id="tank{{$id}}"> ... </g>
</defs>
As of 1.2, though, this doesn't work. Interpolation the id seems to work
<use x="200" y="150" xlink:href="#tank{{$id}}"/>
This fails because of the concatonation in the interpolation.
Error: [$interpolate:noconcat] Error while interpolating: #tank{{$id}}
Strict Contextual Escaping disallows interpolations that concatenate
multiple expressions when a trusted value is required.
See http://docs.angularjs.org/api/ng.$sce
It is not clear to me from the documentation how I am supposed to handle
this. What I really want to do is tell it that if it's an xlink:href
that's OK. What I do NOT want to do is to disable $sce entirely.
--Chris
--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+***@googlegroups.com.
To post to this group, send email to ***@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.
OpenNota
2013-11-09 14:19:53 UTC
Permalink
This is what they recommend to do to migrate from 1.0 to 1.2:

Before:

scope.baseUrl = 'page';
scope.a = 1;
scope.b = 2;
<!-- Are a and b properly escaped here? Is baseUrl controlled by user? -->
<iframe src="{{baseUrl}}?a={{a}&b={{b}}">
After:

var baseUrl = "page";
scope.getIframeSrc = function() {
// One should think about their particular case and sanitize accordingly
var qs = ["a", "b"].map(function(value, name) {
return encodeURIComponent(name) + "=" +
encodeURIComponent(value);
}).join("&");
// `baseUrl` isn't exposed to a user's control, so we don't have to
worry about escaping it.
return baseUrl + "?" + qs;
};
<iframe src="{{getIframeSrc()}}">


See
http://docs.angularjs.org/guide/migration#you-can-only-bind-one-expression-to
--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+***@googlegroups.com.
To post to this group, send email to ***@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.
Loading...