diff --git a/src/dynamic-element.js b/src/dynamic-element.js index d905f83..099c17a 100644 --- a/src/dynamic-element.js +++ b/src/dynamic-element.js @@ -1,5 +1,7 @@ /*eslint padded-blocks:0*/ +import {bindingMode} from 'aurelia-binding'; import {useView, customElement, bindable} from 'aurelia-templating'; + export function _createDynamicElement(name: string, viewUrl: string, bindableNames: string[]): Function { @customElement(name) @useView(viewUrl) @@ -8,8 +10,37 @@ export function _createDynamicElement(name: string, viewUrl: string, bindableNam this.$parent = bindingContext; } } + + let parts; + let config; + let propertyName; + let defaultBindingMode; + let coerce; + let coerceParts; + for (let i = 0, ii = bindableNames.length; i < ii; ++i) { - bindable(bindableNames[i])(DynamicElement); + defaultBindingMode = coerce = undefined; + + parts = bindableNames[i].split('&'); + propertyName = parts[0].trim(); + if (parts.length === 2) { + defaultBindingMode = parts[1].trim(); + } + + coerceParts = propertyName.split(':'); + + if (coerceParts.length === 2) { + propertyName = coerceParts[0].trim(); + coerce = coerceParts[1].trim(); + } + + config = { + name: propertyName, + defaultBindingMode: bindingMode[defaultBindingMode], + coerce + }; + + bindable(config)(DynamicElement); } return DynamicElement; } diff --git a/test/html-resource-plugin.spec.js b/test/html-resource-plugin.spec.js index e8873c9..6a5e786 100644 --- a/test/html-resource-plugin.spec.js +++ b/test/html-resource-plugin.spec.js @@ -1,4 +1,8 @@ +import {bindingMode} from 'aurelia-binding'; +import {HtmlBehaviorResource} from 'aurelia-templating'; import {getElementName} from '../src/html-resource-plugin'; +import {_createDynamicElement} from '../src/dynamic-element'; +import {metadata} from 'aurelia-metadata'; describe('html-resource-plugin', () => { it('computes element name', () => { @@ -11,3 +15,47 @@ describe('html-resource-plugin', () => { expect(getElementName('https://bar/foo.html?bar.html')).toBe('foo'); }); }); + +describe('dynamic-element', () => { + it('creates dynamic element in normal usage', () => { + const propName = 'balance'; + const coerce = 'number'; + const defaultBindingMode = 'oneWay'; + const DynamicElement = _createDynamicElement('foo', 'bar', [`${propName}:${coerce} & ${defaultBindingMode}`]); + const resource = metadata.get(metadata.resource, DynamicElement); + const bindableProperty = resource.attributes[propName]; + const test = prop => prop.name === propName && prop.coerce === coerce && prop.defaultBindingMode === bindingMode[defaultBindingMode]; + expect(test(bindableProperty)).toBe(true); + }); + + it('creates dynamic element in spaceful usage', () => { + const propName = 'balance'; + const coerce = 'number'; + const defaultBindingMode = 'oneWay'; + const DynamicElement = _createDynamicElement('foo', 'bar', [` ${propName} : ${coerce} & ${defaultBindingMode} `]); + const resource = metadata.get(metadata.resource, DynamicElement); + const bindableProperty = resource.attributes[propName]; + const test = prop => prop.name === propName && prop.coerce === coerce && prop.defaultBindingMode === bindingMode[defaultBindingMode]; + expect(test(bindableProperty)).toBe(true); + }); + + it('creates dynamic element without default binding mode', () => { + const propName = 'balance'; + const coerce = 'number'; + const DynamicElement = _createDynamicElement('foo', 'bar', [` ${propName} : ${coerce} `]); + const resource = metadata.get(metadata.resource, DynamicElement); + const bindableProperty = resource.attributes[propName]; + const test = prop => prop.name === propName && prop.coerce === coerce && prop.defaultBindingMode === bindingMode.oneWay; + expect(test(bindableProperty)).toBe(true); + }); + + it('creates dynamic element without coerce', () => { + const propName = 'balance'; + const defaultBindingMode = 'oneWay'; + const DynamicElement = _createDynamicElement('foo', 'bar', [` ${propName} & ${defaultBindingMode} `]); + const resource = metadata.get(metadata.resource, DynamicElement); + const bindableProperty = resource.attributes[propName]; + const test = prop => prop.name === propName && prop.coerce === undefined && prop.defaultBindingMode === bindingMode[defaultBindingMode]; + expect(test(bindableProperty)).toBe(true); + }); +});