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

Commit 7e18521

Browse files
committed
feat(tagging compiler): Create fewer ElementBinder lists
1 parent 59e4808 commit 7e18521

File tree

3 files changed

+36
-19
lines changed

3 files changed

+36
-19
lines changed

lib/core_dom/element_binder.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,4 +414,6 @@ class TaggedElementBinder {
414414
}
415415
textBinders.add(tagged);
416416
}
417+
418+
toString() => "[TaggedElementBinder binder:$binder parentBinderOffset:$parentBinderOffset textBinders:$textBinders injector:$injector]";
417419
}

lib/core_dom/tagging_compiler.dart

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
part of angular.core.dom;
22

3+
TaggedElementBinder _addBinder(List list, TaggedElementBinder binder) {
4+
assert(binder.parentBinderOffset != list.length); // Do not point to yourself!
5+
list.add(binder);
6+
return binder;
7+
}
8+
39
@NgInjectableService()
410
class TaggingCompiler implements Compiler {
511
final Profiler _perf;
@@ -13,11 +19,11 @@ class TaggingCompiler implements Compiler {
1319
ElementBinder useExistingElementBinder,
1420
DirectiveMap directives,
1521
int parentElementBinderOffset,
16-
TaggedElementBinder directParentElementBinder) {
17-
List<TaggedElementBinder> elementBinders = [];
22+
TaggedElementBinder directParentElementBinder,
23+
List<TaggedElementBinder> elementBinders) {
24+
assert(parentElementBinderOffset != null);
1825
if (domCursor.current == null) return null;
1926

20-
2127
do {
2228
var node = domCursor.current;
2329

@@ -43,10 +49,10 @@ class TaggingCompiler implements Compiler {
4349
if (node.nodeType == 1) {
4450

4551
var taggedElementBinder = null;
52+
int taggedElementBinderIndex = parentElementBinderOffset;
4653
if (elementBinder.hasDirectives || elementBinder.hasTemplate) {
47-
taggedElementBinder = new TaggedElementBinder(elementBinder, parentElementBinderOffset);
48-
elementBinders.add(taggedElementBinder);
49-
parentElementBinderOffset = elementBinders.length - 1;
54+
taggedElementBinder = _addBinder(elementBinders, new TaggedElementBinder(elementBinder, parentElementBinderOffset));
55+
taggedElementBinderIndex = elementBinders.length - 1;
5056

5157
// TODO(deboer): Hack, this sucks.
5258
(templateCursor.current as dom.Element).classes.add('ng-binding');
@@ -57,9 +63,8 @@ class TaggingCompiler implements Compiler {
5763
if (domCursor.descend()) {
5864
templateCursor.descend();
5965

60-
elementBinders.addAll(
61-
_compileView(domCursor, templateCursor, null, directives, parentElementBinderOffset,
62-
taggedElementBinder));
66+
_compileView(domCursor, templateCursor, null, directives, taggedElementBinderIndex,
67+
taggedElementBinder, elementBinders);
6368

6469
domCursor.ascend();
6570
templateCursor.ascend();
@@ -73,8 +78,7 @@ class TaggingCompiler implements Compiler {
7378
(node.parentNode != null && templateCursor.current.parentNode != null)) {
7479
if (directParentElementBinder == null) {
7580

76-
directParentElementBinder = new TaggedElementBinder(null, parentElementBinderOffset);
77-
elementBinders.add(directParentElementBinder);
81+
directParentElementBinder = _addBinder(elementBinders, new TaggedElementBinder(null, parentElementBinderOffset));
7882

7983
assert(templateCursor.current.parentNode is dom.Element);
8084
assert(node.parentNode is dom.Element);
@@ -84,7 +88,7 @@ class TaggingCompiler implements Compiler {
8488
}
8589
directParentElementBinder.addText(new TaggedTextBinder(elementBinder, 0 /* TODO */));
8690
} else if(!(node.parentNode != null && templateCursor.current.parentNode != null)) { // Always add an elementBinder for top-level text.
87-
elementBinders.add(new TaggedElementBinder(elementBinder, parentElementBinderOffset));
91+
_addBinder(elementBinders, new TaggedElementBinder(elementBinder, parentElementBinderOffset));
8892
}
8993
} else {
9094
throw "Unsupported node type for $node: [${node.nodeType}]";
@@ -106,9 +110,8 @@ class TaggingCompiler implements Compiler {
106110

107111
var transcludeCursor = templateCursor.replaceWithAnchor(anchorName);
108112
var domCursorIndex = domCursor.index;
109-
var elementBinders =
110-
_compileView(domCursor, transcludeCursor, transcludedElementBinder, directives, parentElementBinderOffset, null);
111-
if (elementBinders == null) elementBinders = [];
113+
var elementBinders = [];
114+
_compileView(domCursor, transcludeCursor, transcludedElementBinder, directives, parentElementBinderOffset, null, elementBinders);
112115

113116
viewFactory = new TaggingViewFactory(transcludeCursor.elements, elementBinders, _perf, _expando);
114117
domCursor.index = domCursorIndex;
@@ -134,12 +137,13 @@ class TaggingCompiler implements Compiler {
134137
assert((timerId = _perf.startTimer('ng.compile', _html(elements))) != false);
135138
List<dom.Node> domElements = elements;
136139
List<dom.Node> templateElements = cloneElements(domElements);
137-
List<TaggedElementBinder> elementBinders = _compileView(
140+
List<TaggedElementBinder> elementBinders = [];
141+
_compileView(
138142
new NodeCursor(domElements), new NodeCursor(templateElements),
139-
null, directives, -1, null);
143+
null, directives, -1, null, elementBinders);
140144

141-
var viewFactory = new TaggingViewFactory(templateElements,
142-
elementBinders == null ? [] : elementBinders, _perf, _expando);
145+
var viewFactory = new TaggingViewFactory(
146+
templateElements, elementBinders, _perf, _expando);
143147

144148
assert(_perf.stopTimer(timerId) != false);
145149
return viewFactory;

test/core_dom/compiler_spec.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,17 @@ void main() {
593593
expect(log.result()).toEqual('TabComponent-0; LocalAttrDirective-0; PaneComponent-1; LocalAttrDirective-0; PaneComponent-2; LocalAttrDirective-0');
594594
})));
595595

596+
it('should use the correct parent injector', async(inject((Compiler $compile, Scope rootScope, Logger log, Injector injector) {
597+
// Getting the parent offsets correct while descending the template is tricky. If we get it wrong, this
598+
// test case will create too many TabCompoenents.
599+
600+
var element = $('<div ng-bind="true"><div ignore-children></div><tab local><pane local></pane></tab>');
601+
$compile(element, directives)(injector, element);
602+
microLeap();
603+
604+
expect(log.result()).toEqual('Ignore; TabComponent-0; LocalAttrDirective-0; PaneComponent-1; LocalAttrDirective-0');
605+
})));
606+
596607
it('should reuse controllers for transclusions', async(inject((Compiler $compile, Scope rootScope, Logger log, Injector injector) {
597608
var element = $('<div simple-transclude-in-attach include-transclude>view</div>');
598609
$compile(element, directives)(injector, element);

0 commit comments

Comments
 (0)