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

Commit

Permalink
fix(shadowdom): fixes bug with nested content tags.
Browse files Browse the repository at this point in the history
IntermediateContentTags were not properly accounting for nodes that pass
through them.
  • Loading branch information
rkirov committed Feb 14, 2015
1 parent 011d65f commit f9406a4
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 4 deletions.
11 changes: 9 additions & 2 deletions lib/core_dom/content_tag.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ abstract class _ContentStrategy {
void attach();
void detach();
void insert(Iterable<dom.Node> nodes);
Iterable<dom.Node> get nodes;
}

/**
Expand All @@ -14,6 +15,7 @@ class _ShadowDomContent implements _ContentStrategy {
void attach(){}
void detach(){}
void insert(Iterable<dom.Node> nodes){}
Iterable<dom.Node> get nodes => null;
}

/**
Expand All @@ -35,6 +37,7 @@ class _RenderedTranscludingContent implements _ContentStrategy {
dom.ScriptElement _endScript;

Iterable<dom.Node> _currNodes;
Iterable<dom.Node> get nodes => _currNodes;

_RenderedTranscludingContent(this._content, this._sourceLightDom);

Expand All @@ -50,7 +53,7 @@ class _RenderedTranscludingContent implements _ContentStrategy {

void insert(Iterable<dom.Node> nodes){
final p = _endScript.parent;
if (p != null && ! _equalToCurrNodes(nodes)) {
if (p != null && !_equalToCurrNodes(nodes)) {
_removeNodesBetweenScriptTags();
_currNodes = nodes.toList();
p.insertAllBefore(nodes, _endScript);
Expand Down Expand Up @@ -95,19 +98,22 @@ class _IntermediateTranscludingContent implements _ContentStrategy {
final SourceLightDom _sourceLightDom;
final DestinationLightDom _destinationLightDom;
final Content _content;
Iterable<dom.Node> _currNodes;
Iterable<dom.Node> get nodes => _currNodes;

_IntermediateTranscludingContent(this._content, this._sourceLightDom, this._destinationLightDom);

void attach(){
_sourceLightDom.redistribute();
_destinationLightDom.addContentTag(_content);
}

void detach(){
_sourceLightDom.redistribute();
}

void insert(Iterable<dom.Node> nodes){
_content.element.nodes = nodes;
_currNodes = nodes.toList();
_destinationLightDom.redistribute();
}
}
Expand All @@ -127,6 +133,7 @@ class Content implements AttachAware, DetachAware {
view.addContent(this);
}

Iterable<dom.Node> get nodes => strategy._currNodes;
void attach() => strategy.attach();
void detach() => strategy.detach();
void insert(Iterable<dom.Node> nodes) => strategy.insert(nodes);
Expand Down
12 changes: 10 additions & 2 deletions lib/core_dom/light_dom.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ abstract class SourceLightDom {
abstract class DestinationLightDom {
void redistribute();
void addViewPort(ViewPort viewPort);
void addContentTag(Content content);
bool hasRoot(dom.Element element);
}

Expand All @@ -15,6 +16,7 @@ class LightDom implements SourceLightDom, DestinationLightDom {

final List<dom.Node> _lightDomRootNodes = [];
final Map<dom.Node, ViewPort> _ports = {};
final Map<dom.Node, Content> _contentTags = {};

final Scope _scope;

Expand Down Expand Up @@ -45,6 +47,10 @@ class LightDom implements SourceLightDom, DestinationLightDom {
redistribute();
}

void addContentTag(Content content) {
_contentTags[content.element] = content;
}

//TODO: vsavkin Add dirty flag after implementing view-scoped dom writes.
void redistribute() {
_scope.rootScope.domWrite(() {
Expand Down Expand Up @@ -82,7 +88,9 @@ class LightDom implements SourceLightDom, DestinationLightDom {
if (_ports.containsKey(root)) {
list.addAll(_ports[root].nodes);
} else if (root is dom.ContentElement) {
list.addAll(root.nodes);
if (!_contentTags.containsKey(root))
throw new Exception('Unmatched content tag encountered during redistibution.');
list.addAll(_contentTags[root].nodes);
} else {
list.add(root);
}
Expand All @@ -105,4 +113,4 @@ void redistributeNodes(Iterable<Content> contents, List<dom.Node> nodes) {
nodes.removeWhere(matchSelector);
}
}
}
}
25 changes: 25 additions & 0 deletions test/core_dom/compiler_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ void main() {
..bind(OuterComponent)
..bind(InnerComponent)
..bind(InnerInnerComponent)
..bind(SimpleOuterComponent)
..bind(SimpleInnerComponent)
..bind(OuterWithDivComponent)
..bind(OneTimeDecorator)
..bind(OnceInside)
Expand Down Expand Up @@ -615,6 +617,13 @@ void main() {
expect(element).toHaveText('OUTTER:INNER(OUTTER)');
}));

it('should create simple nested components', async((VmTurnZone zone) {
var element = _.compile(r'<div><simple-outer>TEXT</simple-outer></div>');
microLeap();
_.rootScope.apply();
expect(element).toHaveText('OUTER(INNER(TEXT))');
}));

it('should create a component that can access parent scope', async((VmTurnZone zone) {
_.rootScope.context['fromParent'] = "should not be used";
_.rootScope.context['val'] = "poof";
Expand Down Expand Up @@ -1744,6 +1753,22 @@ class InnerComponent implements ScopeAware {
InnerComponent();
}

@Component(
selector: 'simple-inner',
template: 'INNER(<content></content>)'
)
class SimpleInnerComponent implements ScopeAware {
Scope scope;
}

@Component(
selector: 'simple-outer',
template: 'OUTER(<simple-inner><content></content></simple-inner>)'
)
class SimpleOuterComponent implements ScopeAware {
Scope scope;
}

@Component(
selector: 'innerinner',
template: 'INNERINNER(<content select=".left"></content>,<content select=".right"></content>)'
Expand Down

0 comments on commit f9406a4

Please sign in to comment.