Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit bb47505

Browse files
committed
fix(compiler): Support camelCase property bindings
Fixes #1460
1 parent 4dee442 commit bb47505

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed

lib/core_dom/element_binder.dart

+1
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ class ElementBinder {
308308
var jsNode;
309309
List bindAssignableProps = [];
310310
bindAttrs.forEach((String prop, AST ast) {
311+
prop = camelCase(prop);
311312
if (jsNode == null) jsNode = new js.JsObject.fromBrowserObject(node);
312313
scope.watchAST(ast, (v, _) {
313314
jsNode[prop] = v;

lib/utils.dart

+6
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ relaxFnArgs(Function fn) {
8181

8282
capitalize(String s) => s.substring(0, 1).toUpperCase() + s.substring(1);
8383

84+
String camelCase(String s) {
85+
var part = s.split('-').map((s) => s.toLowerCase());
86+
if (part.length <= 1)
87+
return part.join();
88+
return part.first + part.skip(1).map(capitalize).join();
89+
}
8490

8591
/// Returns whether or not the given identifier is a reserved word in Dart.
8692
bool isReservedWord(String identifier) => RESERVED_WORDS.contains(identifier);

test/core_dom/web_components_spec.dart

+13-6
Original file line numberDiff line numberDiff line change
@@ -58,29 +58,36 @@ main() {
5858

5959

6060
it('should bind to Custom Element properties', () {
61-
registerElement('tests-bound', {'prop-y': 10});
61+
registerElement('tests-bound', {'propY': 10});
6262
compileAndUpgrade('<tests-bound bind-prop-y=27></tests-bound>');
6363

6464
// Scope has not been digested yet
65-
expect(customProp('prop-y')).toEqual(10);
65+
expect(customProp('propY')).toEqual(10);
6666

6767
_.rootScope.apply();
68-
expect(customProp('prop-y')).toEqual(27);
68+
expect(customProp('propY')).toEqual(27);
6969
});
7070

7171

7272
it('should bind to a non-existent property', () {
7373
registerElement('tests-empty', {});
74-
compileAndUpgrade('<tests-empty bind-new-prop=27></tests-empty>');
74+
compileAndUpgrade('<tests-empty bind-newprop=27></tests-empty>');
7575
_.rootScope.apply();
76-
expect(customProp('new-prop')).toEqual(27);
76+
expect(customProp('newprop')).toEqual(27);
77+
});
78+
79+
it('should bind to a camelCase property', () {
80+
registerElement('tests-camel', {});
81+
compileAndUpgrade('<tests-camel bind-new-prop=27></tests-camel>');
82+
_.rootScope.apply();
83+
expect(customProp('newProp')).toEqual(27);
7784
});
7885

7986
it('should bind to both directives and properties', () {
8087
registerElement('tests-double', {});
8188
compileAndUpgrade('<tests-double ng-bind bind-ng-bind="\'hello\'"></tests-double>');
8289
_.rootScope.apply();
83-
expect(customProp('ng-bind')).toEqual("hello");
90+
expect(customProp('ngBind')).toEqual("hello");
8491
expect(_.rootElement).toHaveText('hello');
8592
});
8693

test/utils_spec.dart

+14
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,19 @@ main() {
3131
}).toThrowWith(message: 'Unknown function type, expecting 0 to 5 args.');
3232
});
3333
});
34+
35+
describe('camelCase', () {
36+
it('should ignore non camelCase', () {
37+
expect(camelCase('regular')).toEqual('regular');
38+
});
39+
40+
it('should convert snake-case', () {
41+
expect(camelCase('snake-case')).toEqual('snakeCase');
42+
});
43+
44+
it('should lowercase strings', () {
45+
expect(camelCase('Caps-first')).toEqual('capsFirst');
46+
});
47+
});
3448
}
3549

0 commit comments

Comments
 (0)