From e7b94c2a1f4b893f3b76a30f47c0012519e61ede Mon Sep 17 00:00:00 2001 From: James deBoer Date: Mon, 15 Jul 2013 15:50:16 -0700 Subject: [PATCH] feat(compiler): Mapped attributes are snake-cased correctly. --- lib/angular.dart | 1 + lib/block.dart | 2 +- lib/string_utilities.dart | 7 +++++++ test/compiler_spec.dart | 18 +++++++++++++++++- test/string_utilities_spec.dart | 10 ++++++++++ 5 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 lib/string_utilities.dart create mode 100644 test/string_utilities_spec.dart diff --git a/lib/angular.dart b/lib/angular.dart index 006803185..769e34ba2 100644 --- a/lib/angular.dart +++ b/lib/angular.dart @@ -37,6 +37,7 @@ part 'node_cursor.dart'; part 'parser.dart'; part 'scope.dart'; part 'selector.dart'; +part 'string_utilities.dart'; ASSERT(condition) { if (!condition) { diff --git a/lib/block.dart b/lib/block.dart index 008e78519..7a4dd4cf6 100644 --- a/lib/block.dart +++ b/lib/block.dart @@ -318,7 +318,7 @@ class ComponentFactory { createAttributeMapping(Scope parentScope, Scope shadowScope, Parser parser) { directive.$map.forEach((attrName, mapping) { - var attrValue = element.attributes[attrName]; + var attrValue = element.attributes[snake_case(attrName, '-')]; if (attrValue == null) attrValue = ''; if (mapping == '@') { shadowScope[attrName] = attrValue; diff --git a/lib/string_utilities.dart b/lib/string_utilities.dart new file mode 100644 index 000000000..846e81f4a --- /dev/null +++ b/lib/string_utilities.dart @@ -0,0 +1,7 @@ +part of angular; + +var SNAKE_CASE_REGEXP = new RegExp("[A-Z]"); + +snake_case(String name, [separator = '_']) => + name.replaceAllMapped(SNAKE_CASE_REGEXP, (Match match) => + (match.start != 0 ? separator : '') + match.group(0).toLowerCase()); diff --git a/test/compiler_spec.dart b/test/compiler_spec.dart index 9f470b8dc..4aff600c1 100644 --- a/test/compiler_spec.dart +++ b/test/compiler_spec.dart @@ -391,6 +391,7 @@ main() { describe('components', () { beforeEach(module((AngularModule module) { module.directive(SimpleComponent); + module.directive(CamelCaseMapComponent); module.directive(IoComponent); module.directive(ParentExpressionComponent); module.directive(PublishMeComponent); @@ -412,7 +413,7 @@ main() { it('should create a component that can access parent scope', inject(() { $rootScope.fromParent = "should not be used"; $rootScope.val = "poof"; - var element = $(''); + var element = $(''); $compile(element)(injector, element); @@ -455,6 +456,14 @@ main() { expect($rootScope.done).toEqual(true); })); + it('should expose mapped attributes as camel case', inject(() { + var element = $(''); + $compile(element)(injector, element); + $rootScope.$apply(); + var componentScope = $rootScope.camelCase; + expect(componentScope.camelCase).toEqual('6'); + })); + it('should throw an exception if required directive is missing', inject((Compiler $compile, Scope $rootScope, Injector injector) { expect(() { var element = $(''); @@ -510,6 +519,13 @@ class IoComponent { } } +class CamelCaseMapComponent { + static Map $map = {"camelCase": "@"}; + CamelCaseMapComponent(Scope scope) { + scope.$root.camelCase = scope; + } +} + class ParentExpressionComponent { static String $template = '
inside {{fromParent()}}
'; static Map $map = {"fromParent": "&"}; diff --git a/test/string_utilities_spec.dart b/test/string_utilities_spec.dart new file mode 100644 index 000000000..f16ba5b78 --- /dev/null +++ b/test/string_utilities_spec.dart @@ -0,0 +1,10 @@ +import "_specs.dart"; + +main() { + describe('snake_case', (){ + it('should convert to snake_case', () { + expect(snake_case('ABC')).toEqual('a_b_c'); + expect(snake_case('alanBobCharles')).toEqual('alan_bob_charles'); + }); + }); +}