From c2a3e2ce48a4b481325bfaa559caf8d976b097c0 Mon Sep 17 00:00:00 2001 From: Georgios Kalpakas Date: Fri, 16 Sep 2016 17:25:24 +0300 Subject: [PATCH 1/2] refactor($compile): remove unnecessary dependencies from tests --- test/ng/compileSpec.js | 83 ++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index a9659524fd21..23b2c7b2588b 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -11161,8 +11161,7 @@ describe('$compile', function() { } describe('ngAttr* attribute binding', function() { - - it('should bind after digest but not before', inject(function($compile, $rootScope) { + it('should bind after digest but not before', inject(function() { $rootScope.name = 'Misko'; element = $compile('')($rootScope); expect(element.attr('test')).toBeUndefined(); @@ -11170,7 +11169,7 @@ describe('$compile', function() { expect(element.attr('test')).toBe('Misko'); })); - it('should bind after digest but not before when after overridden attribute', inject(function($compile, $rootScope) { + it('should bind after digest but not before when after overridden attribute', inject(function() { $rootScope.name = 'Misko'; element = $compile('')($rootScope); expect(element.attr('test')).toBe('123'); @@ -11178,7 +11177,7 @@ describe('$compile', function() { expect(element.attr('test')).toBe('Misko'); })); - it('should bind after digest but not before when before overridden attribute', inject(function($compile, $rootScope) { + it('should bind after digest but not before when before overridden attribute', inject(function() { $rootScope.name = 'Misko'; element = $compile('')($rootScope); expect(element.attr('test')).toBe('123'); @@ -11186,7 +11185,7 @@ describe('$compile', function() { expect(element.attr('test')).toBe('Misko'); })); - it('should remove attribute if any bindings are undefined', inject(function($compile, $rootScope) { + it('should remove attribute if any bindings are undefined', inject(function() { element = $compile('')($rootScope); $rootScope.$digest(); expect(element.attr('test')).toBeUndefined(); @@ -11199,6 +11198,8 @@ describe('$compile', function() { })); describe('in directive', function() { + var log; + beforeEach(module(function() { directive('syncTest', function(log) { return { @@ -11219,47 +11220,52 @@ describe('$compile', function() { }); })); - beforeEach(inject(function($templateCache) { + beforeEach(inject(function($templateCache, _log_) { + log = _log_; $templateCache.put('async.html', '

Test

'); })); it('should provide post-digest value in synchronous directive link functions when after overridden attribute', - inject(function(log, $rootScope, $compile) { - $rootScope.test = 'TEST'; - element = $compile('
')($rootScope); - expect(element.attr('test')).toBe('123'); - expect(log.toArray()).toEqual(['TEST', 'TEST']); - })); + function() { + $rootScope.test = 'TEST'; + element = $compile('
')($rootScope); + expect(element.attr('test')).toBe('123'); + expect(log.toArray()).toEqual(['TEST', 'TEST']); + } + ); it('should provide post-digest value in synchronous directive link functions when before overridden attribute', - inject(function(log, $rootScope, $compile) { - $rootScope.test = 'TEST'; - element = $compile('
')($rootScope); - expect(element.attr('test')).toBe('123'); - expect(log.toArray()).toEqual(['TEST', 'TEST']); - })); + function() { + $rootScope.test = 'TEST'; + element = $compile('
')($rootScope); + expect(element.attr('test')).toBe('123'); + expect(log.toArray()).toEqual(['TEST', 'TEST']); + } + ); it('should provide post-digest value in asynchronous directive link functions when after overridden attribute', - inject(function(log, $rootScope, $compile) { - $rootScope.test = 'TEST'; - element = $compile('
')($rootScope); - expect(element.attr('test')).toBe('123'); - $rootScope.$digest(); - expect(log.toArray()).toEqual(['TEST', 'TEST']); - })); + function() { + $rootScope.test = 'TEST'; + element = $compile('
')($rootScope); + expect(element.attr('test')).toBe('123'); + $rootScope.$digest(); + expect(log.toArray()).toEqual(['TEST', 'TEST']); + } + ); it('should provide post-digest value in asynchronous directive link functions when before overridden attribute', - inject(function(log, $rootScope, $compile) { - $rootScope.test = 'TEST'; - element = $compile('
')($rootScope); - expect(element.attr('test')).toBe('123'); - $rootScope.$digest(); - expect(log.toArray()).toEqual(['TEST', 'TEST']); - })); + function() { + $rootScope.test = 'TEST'; + element = $compile('
')($rootScope); + expect(element.attr('test')).toBe('123'); + $rootScope.$digest(); + expect(log.toArray()).toEqual(['TEST', 'TEST']); + } + ); }); - it('should work with different prefixes', inject(function($compile, $rootScope) { + it('should work with different prefixes', inject(function() { $rootScope.name = 'Misko'; element = $compile('')($rootScope); expect(element.attr('test')).toBeUndefined(); @@ -11271,14 +11277,14 @@ describe('$compile', function() { expect(element.attr('test3')).toBe('Misko'); })); - it('should work with the "href" attribute', inject(function($compile, $rootScope) { + it('should work with the "href" attribute', inject(function() { $rootScope.value = 'test'; element = $compile('')($rootScope); $rootScope.$digest(); expect(element.attr('href')).toBe('test/test'); })); - it('should work if they are prefixed with x- or data- and different prefixes', inject(function($compile, $rootScope) { + it('should work if they are prefixed with x- or data- and different prefixes', inject(function() { $rootScope.name = 'Misko'; element = $compile('')($rootScope); @@ -11296,8 +11302,7 @@ describe('$compile', function() { })); describe('when an attribute has a dash-separated name', function() { - - it('should work with different prefixes', inject(function($compile, $rootScope) { + it('should work with different prefixes', inject(function() { $rootScope.name = 'JamieMason'; element = $compile('')($rootScope); expect(element.attr('dash-test')).toBeUndefined(); @@ -11309,7 +11314,7 @@ describe('$compile', function() { expect(element.attr('dash-test3')).toBe('JamieMason'); })); - it('should work if they are prefixed with x- or data-', inject(function($compile, $rootScope) { + it('should work if they are prefixed with x- or data-', inject(function() { $rootScope.name = 'JamieMason'; element = $compile('')($rootScope); expect(element.attr('dash-test2')).toBeUndefined(); @@ -11338,7 +11343,6 @@ describe('$compile', function() { }); }); - it('should keep attributes ending with -end single-element directives', function() { module(function($compileProvider) { $compileProvider.directive('dashEnder', function(log) { @@ -11356,7 +11360,6 @@ describe('$compile', function() { }); }); }); - }); From 4c1eb8027e34a42ff82ee31c6c4f707056808b35 Mon Sep 17 00:00:00 2001 From: Georgios Kalpakas Date: Fri, 16 Sep 2016 17:50:34 +0300 Subject: [PATCH 2/2] fix($compile): set attribute value even if `ngAttr*` contains no interpolation Previoulsy, when the value of an `ngAttrXyz` attribute did not contain any interpolation, then the `xyz` attribute was never set. BTW, this commit adds a negligible overhead (since we have to set up a one-time watcher for example), but it is justifiable for someone that is using `ngAttrXyz` (instead of `xyz` directly). Fixes #15133 --- src/ng/compile.js | 8 ++++---- test/ng/compileSpec.js | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ng/compile.js b/src/ng/compile.js index 631ddc67cedd..638725e08140 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -3251,16 +3251,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { } - function addAttrInterpolateDirective(node, directives, value, name, allOrNothing) { + function addAttrInterpolateDirective(node, directives, value, name, isNgAttr) { var trustedContext = getTrustedContext(node, name); - allOrNothing = ALL_OR_NOTHING_ATTRS[name] || allOrNothing; + var mustHaveExpression = !isNgAttr; + var allOrNothing = ALL_OR_NOTHING_ATTRS[name] || isNgAttr; - var interpolateFn = $interpolate(value, true, trustedContext, allOrNothing); + var interpolateFn = $interpolate(value, mustHaveExpression, trustedContext, allOrNothing); // no interpolation found -> ignore if (!interpolateFn) return; - if (name === 'multiple' && nodeName_(node) === 'select') { throw $compileMinErr('selmulti', 'Binding to the \'multiple\' attribute is not supported. Element: {0}', diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 23b2c7b2588b..f5193fa6a8ca 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -11185,6 +11185,14 @@ describe('$compile', function() { expect(element.attr('test')).toBe('Misko'); })); + it('should set the attribute (after digest) even if there is no interpolation', inject(function() { + element = $compile('')($rootScope); + expect(element.attr('test')).toBeUndefined(); + + $rootScope.$digest(); + expect(element.attr('test')).toBe('foo'); + })); + it('should remove attribute if any bindings are undefined', inject(function() { element = $compile('')($rootScope); $rootScope.$digest();