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;