diff --git a/docs/content/guide/directive.ngdoc b/docs/content/guide/directive.ngdoc index 643a3b44ce15..a82e6994e20f 100644 --- a/docs/content/guide/directive.ngdoc +++ b/docs/content/guide/directive.ngdoc @@ -174,6 +174,15 @@ For example, we could fix the example above by instead writing: ``` +If one wants to modify a camelcased attribute (SVG elements have valid camelcased attributes), such as `viewBox` on the `svg` element, one can use underscores to denote that the attribute to bind to is naturally camelcased. + +For example, to bind to `viewBox`, we can write: + +```html + + +``` + ## Creating Directives diff --git a/src/ng/compile.js b/src/ng/compile.js index 7ff234fe1c33..e1b74a50dad4 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -1405,7 +1405,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { // support ngAttr attribute binding ngAttrName = directiveNormalize(name); if (isNgAttr = NG_ATTR_BINDING.test(ngAttrName)) { - name = snake_case(ngAttrName.substr(6), '-'); + name = name.replace(PREFIX_REGEXP, '') + .substr(8).replace(/_(.)/g, function(match, letter) { + return letter.toUpperCase(); + }); } var directiveNName = ngAttrName.replace(/(Start|End)$/, ''); diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 9509e90b6202..1e4717add671 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -6542,16 +6542,21 @@ describe('$compile', function() { expect(element.attr('href')).toBe('test/test'); })); - 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- and different prefixes', inject(function($compile, $rootScope) { $rootScope.name = "Misko"; - element = $compile('')($rootScope); + element = $compile('')($rootScope); expect(element.attr('test2')).toBeUndefined(); expect(element.attr('test3')).toBeUndefined(); expect(element.attr('test4')).toBeUndefined(); + expect(element.attr('test5')).toBeUndefined(); + expect(element.attr('test6')).toBeUndefined(); $rootScope.$digest(); expect(element.attr('test2')).toBe('Misko'); expect(element.attr('test3')).toBe('Misko'); expect(element.attr('test4')).toBe('Misko'); + expect(element.attr('test5')).toBe('Misko'); + expect(element.attr('test6')).toBe('Misko'); })); describe('when an attribute has a dash-separated name', function() { @@ -6619,6 +6624,35 @@ describe('$compile', function() { }); + describe('when an attribute has an underscore-separated name', function() { + + it('should work with different prefixes', inject(function($compile, $rootScope) { + $rootScope.dimensions = "0 0 0 0"; + element = $compile('')($rootScope); + expect(element.attr('viewBox')).toBeUndefined(); + $rootScope.$digest(); + expect(element.attr('viewBox')).toBe('0 0 0 0'); + })); + + it('should work if they are prefixed with x- or data-', inject(function($compile, $rootScope) { + $rootScope.dimensions = "0 0 0 0"; + $rootScope.number = 0.42; + $rootScope.scale = 1; + element = $compile('' + + '' + + '' + + '' + + '' + + '')($rootScope); + expect(element.attr('viewBox')).toBeUndefined(); + $rootScope.$digest(); + expect(element.attr('viewBox')).toBe('0 0 0 0'); + expect(element.find('filter').attr('filterUnits')).toBe('0.42'); + expect(element.find('feDiffuseLighting').attr('surfaceScale')).toBe('1'); + expect(element.find('feSpecularLighting').attr('surfaceScale')).toBe('1'); + })); + }); + describe('multi-element directive', function() { it('should group on link function', inject(function($compile, $rootScope) { $rootScope.show = false;