diff options
| author | Caitlin Potter | 2014-01-28 11:34:01 -0500 | 
|---|---|---|
| committer | Caitlin Potter | 2014-02-10 18:41:28 -0500 | 
| commit | e7338d3f27e8824196136a18e1c3e0fcf51a0e28 (patch) | |
| tree | d747538a5c18d3b37a1f86e950b3f2321b3348b2 /test/ng/compileSpec.js | |
| parent | 2dfbc083c518ce591610ec619127bc8441615df9 (diff) | |
| download | angular.js-e7338d3f27e8824196136a18e1c3e0fcf51a0e28.tar.bz2 | |
fix($compile): ensure element transclusion directives are linked with comment element
This corrects a complicated compiler issue, described in detail below:
Previously, if an element transclusion directive contained an asynchronous directive whose template
contained another element transclusion directive, the inner element transclusion directive would be
linked with the element, rather than the expected comment node.
An example manifestation of this bug would look like so:
```html
<div ng-repeat="i in [1,2,3,4,5]">
  <div my-directive>
  </div>
</div>
```
`my-directive` would be a replace directive, and its template would contain another element
transclusion directive, like so:
```html
<div ng-if="true">{{i}}</div>
```
ngIf would be linked with this template content, rather than the comment node, and the template element
would be attached to the DOM, rather than the comment. As a result, this caused ng-if to duplicate the
template when its expression evaluated to true.
Closes #6006
Closes #6101
Diffstat (limited to 'test/ng/compileSpec.js')
| -rwxr-xr-x | test/ng/compileSpec.js | 51 | 
1 files changed, 51 insertions, 0 deletions
| diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 085eb6e9..60b1024b 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -3972,6 +3972,57 @@ describe('$compile', function() {          });        }); +      // issue #6006 +      it('should link directive with $element as a comment node', function() { +        module(function($provide) { +          directive('innerAgain', function(log) { +            return { +              transclude: 'element', +              link: function(scope, element, attr, controllers, transclude) { +                log('innerAgain:'+lowercase(nodeName_(element))+':'+trim(element[0].data)); +                transclude(scope, function(clone) { +                  element.parent().append(clone); +                }); +              } +            }; +          }); +          directive('inner', function(log) { +            return { +              replace: true, +              templateUrl: 'inner.html', +              link: function(scope, element) { +                log('inner:'+lowercase(nodeName_(element))+':'+trim(element[0].data)); +              } +            }; +          }); +          directive('outer', function(log) { +            return { +              transclude: 'element', +              link: function(scope, element, attrs, controllers, transclude) { +                log('outer:'+lowercase(nodeName_(element))+':'+trim(element[0].data)); +                transclude(scope, function(clone) { +                  element.parent().append(clone); +                }); +              } +            }; +          }); +        }); +        inject(function(log, $compile, $rootScope, $templateCache) { +          $templateCache.put('inner.html', '<div inner-again><p>Content</p></div>'); +          element = $compile('<div><div outer><div inner></div></div></div>')($rootScope); +          $rootScope.$digest(); +          var child = element.children(); + +          expect(log.toArray()).toEqual([ +            "outer:#comment:outer:", +            "innerAgain:#comment:innerAgain:", +            "inner:#comment:innerAgain:"]); +          expect(child.length).toBe(1); +          expect(child.contents().length).toBe(2); +          expect(lowercase(nodeName_(child.contents().eq(0)))).toBe('#comment'); +          expect(lowercase(nodeName_(child.contents().eq(1)))).toBe('div'); +        }); +      });      });      it('should safely create transclude comment node and not break with "-->"', | 
