diff options
| -rw-r--r-- | src/ng/compile.js | 5 | ||||
| -rw-r--r-- | src/ng/directive/input.js | 2 | ||||
| -rwxr-xr-x | test/ng/compileSpec.js | 146 | 
3 files changed, 123 insertions, 30 deletions
| diff --git a/src/ng/compile.js b/src/ng/compile.js index a4e44f01..fce6f34e 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -1095,7 +1095,7 @@ function $CompileProvider($provide) {          childLinkFn && childLinkFn(scope, linkNode.childNodes, undefined, boundTranscludeFn);          // POSTLINKING -        for(i = 0, ii = postLinkFns.length; i < ii; i++) { +        for(i = postLinkFns.length - 1; i >= 0; i--) {            try {              linkFn = postLinkFns[i];              linkFn(scope, $element, attrs, @@ -1328,7 +1328,7 @@ function $CompileProvider($provide) {        }        directives.push({ -        priority: 100, +        priority: -100,          compile: valueFn(function attrInterpolateLinkFn(scope, element, attr) {            var $$observers = (attr.$$observers || (attr.$$observers = {})); @@ -1346,6 +1346,7 @@ function $CompileProvider($provide) {            // register any observers            if (!interpolateFn) return; +          // TODO(i): this should likely be attr.$set(name, iterpolateFn(scope) so that we reset the actual attr value            attr[name] = interpolateFn(scope);            ($$observers[name] || ($$observers[name] = [])).$$inter = true;            (attr.$$observers && attr.$$observers[name].$$scope || scope). diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index fa953419..ee613a6e 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -958,7 +958,7 @@ var VALID_CLASS = 'ng-valid',      </file>   * </example>   * - *  + *   */  var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse',      function($scope, $exceptionHandler, $attr, $element, $parse) { diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index f164ca7a..5e28c62b 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -96,19 +96,25 @@ describe('$compile', function() {          directive('div', function(log) {            return {              restrict: 'ECA', -            link: log.fn('1') +            link: { +              pre: log.fn('pre1'), +              post: log.fn('post1') +            }            };          });          directive('div', function(log) {            return {              restrict: 'ECA', -            link: log.fn('2') +            link: { +              pre: log.fn('pre2'), +              post: log.fn('post2') +            }            };          });        });        inject(function($compile, $rootScope, log) {          element = $compile('<div></div>')($rootScope); -        expect(log).toEqual('1; 2'); +        expect(log).toEqual('pre1; pre2; post2; post1');        });      });    }); @@ -206,7 +212,7 @@ describe('$compile', function() {            '<span greet="angular" log="L" x-high-log="H" data-medium-log="M"></span>')            ($rootScope);          expect(element.text()).toEqual('Hello angular'); -        expect(log).toEqual('H; M; L'); +        expect(log).toEqual('L; M; H');        })); @@ -387,7 +393,7 @@ describe('$compile', function() {            element = $compile(              '<span log="L" x-high-log="H" data-medium-log="M"></span>')              ($rootScope); -          expect(log).toEqual('H; M; L'); +          expect(log).toEqual('L; M; H');          }));        }); @@ -511,8 +517,7 @@ describe('$compile', function() {              ($rootScope);            $rootScope.$digest();            expect(element.text()).toEqual('Replace!'); -          // HIGH goes after MEDIUM since it executes as part of replaced template -          expect(log).toEqual('MEDIUM; HIGH; LOG'); +          expect(log).toEqual('LOG; HIGH; MEDIUM');          })); @@ -521,7 +526,7 @@ describe('$compile', function() {              ($rootScope);            $rootScope.$digest();            expect(element.text()).toEqual('Append!'); -          expect(log).toEqual('HIGH; LOG; MEDIUM'); +          expect(log).toEqual('LOG; HIGH; MEDIUM');          })); @@ -1079,7 +1084,7 @@ describe('$compile', function() {              expect(log).toEqual(                'first-C; FLUSH; second-C; last-C; third-C; ' +                'first-PreL; second-PreL; last-PreL; third-PreL; ' + -              'third-PostL; first-PostL; second-PostL; last-PostL'); +              'third-PostL; last-PostL; second-PostL; first-PostL');              var span = element.find('span');              expect(span.attr('first')).toEqual(''); @@ -1104,7 +1109,7 @@ describe('$compile', function() {              expect(log).toEqual(                'iFirst-C; FLUSH; iSecond-C; iThird-C; iLast-C; ' +                'iFirst-PreL; iSecond-PreL; iThird-PreL; iLast-PreL; ' + -              'iFirst-PostL; iSecond-PostL; iThird-PostL; iLast-PostL'); +              'iLast-PostL; iThird-PostL; iSecond-PostL; iFirst-PostL');              var div = element.find('div');              expect(div.attr('i-first')).toEqual(''); @@ -1130,7 +1135,7 @@ describe('$compile', function() {              expect(log).toEqual(                'first-C; FLUSH; second-C; last-C; third-C; ' +                'first-PreL; second-PreL; last-PreL; third-PreL; ' + -              'third-PostL; first-PostL; second-PostL; last-PostL'); +              'third-PostL; last-PostL; second-PostL; first-PostL');              var span = element.find('span');              expect(span.attr('first')).toEqual(''); @@ -1156,7 +1161,7 @@ describe('$compile', function() {              expect(log).toEqual(                'iFirst-C; FLUSH; iSecond-C; iThird-C; iLast-C; ' +                'iFirst-PreL; iSecond-PreL; iThird-PreL; iLast-PreL; ' + -              'iFirst-PostL; iSecond-PostL; iThird-PostL; iLast-PostL'); +              'iLast-PostL; iThird-PostL; iSecond-PostL; iFirst-PostL');              var div = element.find('div');              expect(div.attr('i-first')).toEqual(''); @@ -1344,10 +1349,10 @@ describe('$compile', function() {                  scope: true,                  restrict: 'CA',                  compile: function() { -                  return function (scope, element) { +                  return {pre: function (scope, element) {                      log(scope.$id);                      expect(element.data('$scope')).toBe(scope); -                  }; +                  }};                  }                };              }); @@ -1409,9 +1414,9 @@ describe('$compile', function() {            directive('log', function(log) {              return {                restrict: 'CA', -              link: function(scope) { +              link: {pre: function(scope) {                  log('log-' + scope.$id + '-' + scope.$parent.$id); -              } +              }}              };            });          })); @@ -1419,7 +1424,7 @@ describe('$compile', function() {          it('should allow creation of new scopes', inject(function($rootScope, $compile, log) {            element = $compile('<div><span scope><a log></a></span></div>')($rootScope); -          expect(log).toEqual('LOG; log-002-001; 002'); +          expect(log).toEqual('002; log-002-001; LOG');            expect(element.find('span').hasClass('ng-scope')).toBe(true);          })); @@ -1427,7 +1432,7 @@ describe('$compile', function() {          it('should allow creation of new isolated scopes for directives', inject(              function($rootScope, $compile, log) {            element = $compile('<div><span iscope><a log></a></span></div>')($rootScope); -          expect(log).toEqual('LOG; log-002-001; 002'); +          expect(log).toEqual('log-002-001; LOG; 002');            $rootScope.name = 'abc';            expect(iscope.$parent).toBe($rootScope);            expect(iscope.name).toBeUndefined(); @@ -1439,7 +1444,7 @@ describe('$compile', function() {            $httpBackend.expect('GET', 'tscope.html').respond('<a log>{{name}}; scopeId: {{$id}}</a>');            element = $compile('<div><span tscope></span></div>')($rootScope);            $httpBackend.flush(); -          expect(log).toEqual('LOG; log-002-001; 002'); +          expect(log).toEqual('log-002-001; LOG; 002');            $rootScope.name = 'Jozo';            $rootScope.$apply();            expect(element.text()).toBe('Jozo; scopeId: 002'); @@ -1453,7 +1458,7 @@ describe('$compile', function() {                respond('<p><a log>{{name}}; scopeId: {{$id}}</a></p>');            element = $compile('<div><span trscope></span></div>')($rootScope);            $httpBackend.flush(); -          expect(log).toEqual('LOG; log-002-001; 002'); +          expect(log).toEqual('log-002-001; LOG; 002');            $rootScope.name = 'Jozo';            $rootScope.$apply();            expect(element.text()).toBe('Jozo; scopeId: 002'); @@ -1467,7 +1472,7 @@ describe('$compile', function() {                respond('<p><a log>{{name}}; scopeId: {{$id}} |</a></p>');            element = $compile('<div><span ng-repeat="i in [1,2,3]" trscope></span></div>')($rootScope);            $httpBackend.flush(); -          expect(log).toEqual('LOG; log-003-002; 003; LOG; log-005-004; 005; LOG; log-007-006; 007'); +          expect(log).toEqual('log-003-002; LOG; 003; log-005-004; LOG; 005; log-007-006; LOG; 007');            $rootScope.name = 'Jozo';            $rootScope.$apply();            expect(element.text()).toBe('Jozo; scopeId: 003 |Jozo; scopeId: 005 |Jozo; scopeId: 007 |'); @@ -1481,7 +1486,7 @@ describe('$compile', function() {            $httpBackend.expect('GET', 'tiscope.html').respond('<a log></a>');            element = $compile('<div><span tiscope></span></div>')($rootScope);            $httpBackend.flush(); -          expect(log).toEqual('LOG; log-002-001; 002'); +          expect(log).toEqual('log-002-001; LOG; 002');            $rootScope.name = 'abc';            expect(iscope.$parent).toBe($rootScope);            expect(iscope.name).toBeUndefined(); @@ -1501,7 +1506,7 @@ describe('$compile', function() {                    '</b>' +                  '</div>'                )($rootScope); -            expect(log).toEqual('LOG; log-003-002; 003; LOG; log-002-001; 002; LOG; log-004-001; 004'); +            expect(log).toEqual('002; 003; log-003-002; LOG; log-002-001; LOG; 004; log-004-001; LOG');            })          ); @@ -1571,7 +1576,38 @@ describe('$compile', function() {            $rootScope.$digest();            expect(element.text()).toEqual('text: angular');            expect(element.attr('name')).toEqual('attr: angular'); -        })); +        }) +    ); + + +    it('should process attribute interpolation at the beginning of the post-linking phase', function() { +      module(function() { +        directive('attrLog', function(log) { +          return { +            compile: function($element, $attrs) { +              log('compile=' + $attrs.myName); + +              return { +                pre: function($scope, $element, $attrs) { +                  log('preLink=' + $attrs.myName); +                }, +                post: function($scope, $element) { +                  log('postLink=' + $attrs.myName); +                } +              } +            } +          } +        }) +      }); +      inject(function($rootScope, $compile, log) { +        element = $compile('<div attr-log my-name="{{name}}"></div>')($rootScope); +        $rootScope.name = 'angular'; +        $rootScope.$apply(); +        log('digest=' + element.attr('my-name')); +        expect(log).toEqual('compile={{name}}; preLink={{name}}; postLink=; digest=angular'); +      }); +    }); +      describe('SCE values', function() {        it('should resolve compile and link both attribute and text bindings', inject( @@ -1753,7 +1789,7 @@ describe('$compile', function() {      it('should compile from top to bottom but link from bottom up', inject(          function($compile, $rootScope, log) {            element = $compile('<a b><c></c></a>')($rootScope); -          expect(log).toEqual('tA; tB; tC; preA; preB; preC; postC; postA; postB'); +          expect(log).toEqual('tA; tB; tC; preA; preB; preC; postC; postB; postA');          }      )); @@ -2230,7 +2266,7 @@ describe('$compile', function() {        });        inject(function(log, $compile, $rootScope) {          element = $compile('<div main dep other></div>')($rootScope); -        expect(log).toEqual('main; dep:main; false'); +        expect(log).toEqual('false; dep:main; main');        });      }); @@ -2639,7 +2675,7 @@ describe('$compile', function() {          element = $compile('<div><div high-log trans="text" log>{{$parent.$id}}-{{$id}};</div></div>')              ($rootScope);          $rootScope.$apply(); -        expect(log).toEqual('compile: <!-- trans: text -->; HIGH; link; LOG; LOG'); +        expect(log).toEqual('compile: <!-- trans: text -->; link; LOG; LOG; HIGH');          expect(element.text()).toEqual('001-002;001-003;');        });      }); @@ -2907,6 +2943,62 @@ describe('$compile', function() {      }); +    it('should make the result of a transclusion available to the parent *replace* directive in post-linking phase (template)', +        function() { +      module(function() { +        directive('replacedTrans', function(log) { +          return { +            transclude: true, +            replace: true, +            template: '<div ng-transclude></div>', +            link: { +              pre: function($scope, $element) { +                log('pre(' + $element.text() + ')'); +              }, +              post: function($scope, $element) { +                log('post(' + $element.text() + ')'); +              } +            } +          }; +        }); +      }); +      inject(function(log, $rootScope, $compile) { +        element = $compile('<div replaced-trans><span>unicorn!</span></div>')($rootScope); +        $rootScope.$apply(); +        expect(log).toEqual('pre(); post(unicorn!)'); +      }); +    }); + + +    it('should make the result of a transclusion available to the parent *replace* directive in post-linking phase (templateUrl)', +        function() { +      module(function() { +        directive('replacedTrans', function(log) { +          return { +            transclude: true, +            replace: true, +            templateUrl: 'trans.html', +            link: { +              pre: function($scope, $element) { +                log('pre(' + $element.text() + ')'); +              }, +              post: function($scope, $element) { +                log('post(' + $element.text() + ')'); +              } +            } +          }; +        }); +      }); +      inject(function(log, $rootScope, $compile, $templateCache) { +        $templateCache.put('trans.html', '<div ng-transclude></div>'); + +        element = $compile('<div replaced-trans><span>unicorn!</span></div>')($rootScope); +        $rootScope.$apply(); +        expect(log).toEqual('pre(); post(unicorn!)'); +      }); +    }); + +      it('should terminate compilation only for element trasclusion', function() {        module(function() {          directive('elementTrans', function(log) { | 
