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

Commit 811b460

Browse files
committed
feat(element binder): Make ElementBinder non-recursive and create an external tree
1 parent b1a518b commit 811b460

File tree

3 files changed

+35
-20
lines changed

3 files changed

+35
-20
lines changed

lib/core_dom/compiler.dart

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,20 @@ class Compiler implements Function {
77

88
Compiler(this._perf, this._expando);
99

10-
List<ElementBinder> _compileView(NodeCursor domCursor, NodeCursor templateCursor,
10+
List<ElementBinderTreeRef> _compileView(NodeCursor domCursor, NodeCursor templateCursor,
1111
ElementBinder existingElementBinder,
1212
DirectiveMap directives) {
1313
if (domCursor.current == null) return null;
1414

15-
List<ElementBinder> elementBinders = null; // don't pre-create to create sparse tree and prevent GC pressure.
15+
List<ElementBinderTreeRef> elementBinders = null; // don't pre-create to create sparse tree and prevent GC pressure.
1616

1717
do {
18+
var subtrees, binder;
19+
1820
ElementBinder elementBinder = existingElementBinder == null
1921
? directives.selector(domCursor.current)
2022
: existingElementBinder;
2123

22-
elementBinder.offsetIndex = templateCursor.index;
23-
2424
if (elementBinder.hasTemplate) {
2525
elementBinder.templateViewFactory = compileTransclusion(
2626
domCursor, templateCursor,
@@ -31,18 +31,20 @@ class Compiler implements Function {
3131
if (domCursor.descend()) {
3232
templateCursor.descend();
3333

34-
elementBinder.childElementBinders =
34+
subtrees =
3535
_compileView(domCursor, templateCursor, null, directives);
3636

3737
domCursor.ascend();
3838
templateCursor.ascend();
3939
}
4040
}
4141

42-
if (elementBinder.isUseful) {
43-
if (elementBinders == null) elementBinders = [];
44-
elementBinders.add(elementBinder);
42+
if (elementBinder.hasDirectives) {
43+
binder = elementBinder;
4544
}
45+
46+
if (elementBinders == null) elementBinders = [];
47+
elementBinders.add(new ElementBinderTreeRef(templateCursor.index, new ElementBinderTree(binder, subtrees)));
4648
} while (templateCursor.moveNext() && domCursor.moveNext());
4749

4850
return elementBinders;

lib/core_dom/element_binder.dart

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ class ElementBinder {
3030
ViewFactory templateViewFactory;
3131

3232
DirectiveRef component;
33-
var childElementBinders;
34-
var offsetIndex;
3533

3634
// Can be either COMPILE_CHILDREN or IGNORE_CHILDREN
3735
String childMode = NgAnnotation.COMPILE_CHILDREN;
@@ -46,8 +44,6 @@ class ElementBinder {
4644

4745
decorators = other.decorators;
4846
component = other.component;
49-
childElementBinders = other.childElementBinders;
50-
offsetIndex = other.offsetIndex;
5147
childMode = other.childMode;
5248
}
5349

@@ -92,8 +88,8 @@ class ElementBinder {
9288
return decorators;
9389
}
9490

95-
bool get isUseful {
96-
return (_usableDirectiveRefs != null && _usableDirectiveRefs.length != 0) || childElementBinders != null;
91+
bool get hasDirectives {
92+
return (_usableDirectiveRefs != null && _usableDirectiveRefs.length != 0);
9793
}
9894

9995
// DI visibility callback allowing node-local visibility.
@@ -378,3 +374,18 @@ class ElementBinder {
378374
});
379375
}
380376
}
377+
378+
379+
// Used for walking the DOM
380+
class ElementBinderTreeRef {
381+
final int offsetIndex;
382+
final ElementBinderTree subtree;
383+
384+
ElementBinderTreeRef(this.offsetIndex, this.subtree);
385+
}
386+
class ElementBinderTree {
387+
ElementBinder binder;
388+
List<ElementBinderTreeRef> subtrees;
389+
390+
ElementBinderTree(this.binder, this.subtrees);
391+
}

lib/core_dom/view_factory.dart

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ class BoundViewFactory {
2424
* [Compiler] as a result of compiling a template.
2525
*/
2626
class ViewFactory implements Function {
27-
final List<ElementBinder> elementBinders;
27+
final List<ElementBinderTreeRef> elementBinders;
2828
final List<dom.Node> templateElements;
2929
final Profiler _perf;
3030
final Expando _expando;
3131

3232
ViewFactory(this.templateElements, this.elementBinders, this._perf, this._expando) {
33-
assert(elementBinders.forEach((ElementBinder eb) { assert(eb is ElementBinder); }) != true);
33+
assert(elementBinders.forEach((ElementBinderTreeRef eb) { assert(eb is ElementBinderTreeRef); }) != true);
3434
}
3535

3636
BoundViewFactory bind(Injector injector) =>
@@ -57,7 +57,9 @@ class ViewFactory implements Function {
5757
var eb = elementBinders[i];
5858
int index = eb.offsetIndex;
5959

60-
List childElementBinders = eb.childElementBinders;
60+
ElementBinderTree tree = eb.subtree;
61+
62+
//List childElementBinders = eb.childElementBinders;
6163
int nodeListIndex = index + preRenderedIndexOffset;
6264
dom.Node node = nodeList[nodeListIndex];
6365

@@ -73,10 +75,10 @@ class ViewFactory implements Function {
7375
parentNode.append(node);
7476
}
7577

76-
var childInjector = eb.bind(view, parentInjector, node);
78+
var childInjector = tree.binder != null ? tree.binder.bind(view, parentInjector, node) : parentInjector;
7779

78-
if (childElementBinders != null) {
79-
_link(view, node.nodes, childElementBinders, childInjector);
80+
if (tree.subtrees != null) {
81+
_link(view, node.nodes, tree.subtrees, childInjector);
8082
}
8183

8284
if (fakeParent) {

0 commit comments

Comments
 (0)