dart-archive / angular.dart

Legacy source repository. See github.com/dart-lang/angular
https://webdev.dartlang.org/angular/
1.25k stars 248 forks source link

Components doesn't work in SVG #987

Open Pajn opened 10 years ago

Pajn commented 10 years ago

Components doesn't work in SVG. This will become quite a problem for apps that makes heavy usage of SVG if #959 is completed and merged before this is fixed. The template is added to the dom but never rendered to the screen.

SVG doesn't support shadow dom so the example uses master to support the useShadowDom flag.

Example:

@Component(
    selector: 'svgcomponent',
    template: '<circle ng-attr-cx="{{ cmp.x }}" ng-attr-cy="{{ cmp.y }}" r="20" fill="black" />',
    publishAs: 'cmp',
    useShadowDom: false
)
class SvgComponent {
    @NgAttr('x')
    int x;
    @NgAttr('y')
    int y;
}

Resulting dom:

<svg width="200px" height="200px" xmlns="http://www.w3.org/2000/svg" class="ng-binding">
  <svgcomponent x="50" y="50" class="ng-binding">
    <circle ng-attr-cx="50" ng-attr-cy="50" r="20" fill="black" class="ng-binding" cx="50" cy="50" />
  </svgcomponent>
</svg>

This does work in AngularJS. Similar example (not mine): http://plnkr.co/edit/ORXN3I?p=preview

One thing that differs between AngularJS and AngularDart output is that AngularJS replaces the custom element with the template where AngularDart places the template inside the custom element and thus leaves a unknown element for the SVG parser. I don't know if this is the issue or not, but it may be worth looking into.

Here is a Stackoverflow question discussing the problem that previously were in AngularJS with regards of custom elements and SVG https://stackoverflow.com/questions/13641105/including-svg-template-in-angularjs-directive

Pajn commented 10 years ago

I thought I should try with an attribute selector on a "real" svg element as well, giving the resulting dom:

<svg width="200px" height="200px" xmlns="http://www.w3.org/2000/svg" class="ng-binding">
  <g svgcomponent="" x="50" y="50" class="ng-binding">
    <circle ng-attr-cx="50" ng-attr-cy="50" r="20" fill="black" class="ng-binding" cx="50" cy="50"></circle>
  </g>
</svg>

This have the same problem (not rendering to the screen). So my guess at the issue above is not correct (or at least, not the only issue). Here I guess that the namespace problem discussed on the above stackoverflow question may be to blame.

Pajn commented 10 years ago

I thought I should try to fix this. I'm leaning against the namespace hypotheses. My idea for API change were to add a namespaceUri parameter on Component decorator, however I can't find where Elements are actually created so that I can pass that parameter on. Could anyone give me a hint or something?

vicb commented 10 years ago

The elements are create by the viewFactory, see https://github.com/angular/angular.dart/blob/3de00bd4902d20137dad0b551312eceb9a599d98/lib/core_dom/transcluding_component_factory.dart#L122