Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

fix(components): the content tag duplicates elements #1422

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/core_dom/light_dom.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ class LightDom implements SourceLightDom, DestinationLightDom {

void pullNodes() {
_lightDomRootNodes.addAll(_componentElement.nodes);
}

void clearComponentElement() {
// This is needed because _lightDomRootNodes can contains viewports,
// which cannot be detached.
final fakeRoot = new dom.DivElement();
Expand Down
7 changes: 3 additions & 4 deletions lib/core_dom/transcluding_component_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,14 @@ class BoundTranscludingComponentFactory implements BoundComponentFactory {
var childInjectorCompleter; // Used if the ViewFuture is available before the childInjector.

var component = _component;
var lightDom = new LightDom(element, scope);
var lightDom = new LightDom(element, scope)..pullNodes();

// Append the component's template as children
var elementFuture;

if (_viewFuture != null) {
elementFuture = _viewFuture.then((ViewFactory viewFactory) {
lightDom.pullNodes();

lightDom.clearComponentElement();
if (childInjector != null) {
lightDom.shadowDomView = viewFactory.call(childInjector.scope, childInjector);
return element;
Expand All @@ -74,7 +73,7 @@ class BoundTranscludingComponentFactory implements BoundComponentFactory {
}
});
} else {
elementFuture = new async.Future.microtask(() => lightDom.pullNodes());
elementFuture = new async.Future.microtask(lightDom.clearComponentElement);
}
TemplateLoader templateLoader = new TemplateLoader(elementFuture);

Expand Down
39 changes: 37 additions & 2 deletions test/core_dom/compiler_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,8 @@ void main() {
..bind(OneTimeDecorator)
..bind(OnceInside)
..bind(OuterShadowless)
..bind(InnerShadowy);
..bind(InnerShadowy)
..bind(TemplateUrlComponent);
});

describe("distribution", () {
Expand Down Expand Up @@ -467,8 +468,35 @@ void main() {

expect(element).toHaveText('OUTER(INNER(INNERINNER(A,BC)))');
}));
});

it("should not duplicate elements when using components with templateUrl", async((MockHttpBackend backend) {
backend.expectGET("${TEST_SERVER_BASE_PREFIX}test/core_dom/template.html").respond(200, "<content></content>");

_.rootScope.context["show"] = true;
var element = _.compile(r'<div>'
'<template-url-component>'
'<div ng-if="show">A</div>'
'<div>B</div>'
'<template-url-component>'
'</div>');
document.body.append(element);

microLeap();
_.rootScope.apply();

backend.flush();

_.rootScope.context["show"] = false;
microLeap();
_.rootScope.apply();

_.rootScope.context["show"] = true;
microLeap();
_.rootScope.apply();

expect(element).toHaveText('AB');
}));
});

it('should store ElementProbe with Elements', async(() {
if (compilerType == 'no-elementProbe') return;
Expand Down Expand Up @@ -1597,6 +1625,13 @@ class InnerInnerComponent {
InnerInnerComponent() {}
}

@Component(
selector: 'template-url-component',
templateUrl: 'template.html'
)
class TemplateUrlComponent {
}

_shadowScope(element){
if (element.shadowRoot != null) {
return ngProbe(element.shadowRoot).scope;
Expand Down