From d7df853bde30ffe97045eff649240284ae6ffdf8 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Tue, 26 May 2015 15:54:10 +0200 Subject: [PATCH] feat(Directive): convert properties to an array fixes #2013 BREAKING CHANGE: Before @Directive(properties: { 'sameName': 'sameName', 'directiveProp': 'elProp | pipe' }) After @Directive(properties: [ 'sameName', 'directiveProp: elProp | pipe' ]) --- modules/angular2/docs/core/02_directives.md | 20 ++--- .../src/core/annotations_impl/annotations.ts | 78 +++++++++---------- .../src/core/annotations_impl/visibility.ts | 24 +++--- .../src/core/compiler/element_injector.ts | 2 +- modules/angular2/src/directives/class.ts | 2 +- modules/angular2/src/directives/ng_for.ts | 2 +- modules/angular2/src/directives/ng_if.ts | 2 +- modules/angular2/src/directives/ng_switch.ts | 4 +- modules/angular2/src/forms/directives.ts | 4 +- modules/angular2/src/render/api.ts | 4 +- .../render/dom/compiler/directive_parser.ts | 27 +++++-- modules/angular2/src/render/dom/convert.ts | 2 +- modules/angular2/src/router/router_link.js | 8 +- .../common/directive_metadata_reader.dart | 2 +- .../test/core/compiler/compiler_spec.ts | 4 +- .../core/compiler/integration_dart_spec.dart | 2 +- .../test/core/compiler/integration_spec.ts | 14 ++-- .../core/compiler/query_integration_spec.ts | 2 +- .../directive_lifecycle_integration_spec.ts | 9 +-- .../dom/compiler/directive_parser_spec.ts | 3 +- .../angular2/test/render/dom/convert_spec.ts | 9 +-- .../test_lib/test_component_builder_spec.ts | 2 +- .../basic_bind_files/bar.ng_deps.dart | 2 +- .../expected/bar.ng_deps.dart | 2 +- .../expected/soup.ng_deps.dart | 4 +- .../soup.ng_deps.dart | 4 +- .../properties.ng_deps.dart | 2 +- .../src/components/button/button.ts | 2 +- .../src/components/checkbox/checkbox.ts | 2 +- .../src/components/grid_list/grid_list.ts | 4 +- .../progress-linear/progress_linear.ts | 2 +- .../src/components/radio/radio_button.ts | 5 +- .../src/components/switcher/switch.ts | 2 +- .../src/compiler/compiler_benchmark.js | 30 +++---- .../src/largetable/largetable_benchmark.js | 8 +- .../src/naive_infinite_scroll/cells.js | 48 ++++++------ .../src/naive_infinite_scroll/scroll_item.js | 6 +- modules/benchmarks/src/tree/tree_benchmark.js | 2 +- modules/examples/src/forms/index.ts | 8 +- modules/examples/src/material/dialog/index.js | 2 +- 40 files changed, 182 insertions(+), 179 deletions(-) diff --git a/modules/angular2/docs/core/02_directives.md b/modules/angular2/docs/core/02_directives.md index 89ce99de33..9210f3c3e0 100644 --- a/modules/angular2/docs/core/02_directives.md +++ b/modules/angular2/docs/core/02_directives.md @@ -63,9 +63,9 @@ Here is a trivial example of a tooltip decorator. The directive will log a toolt ``` @Directive({ selector: '[tooltip]', | CSS Selector which triggers the decorator - properties: { | List which properties need to be bound - text: 'tooltip' | - DOM element tooltip property should be - }, | mapped to the directive text property. + properties: [ | List which properties need to be bound + 'text: tooltip' | - DOM element tooltip property should be + ], | mapped to the directive text property. hostListeners: { | List which events need to be mapped. mouseover: 'show' | - Invoke the show() method every time } | the mouseover event is fired. @@ -108,10 +108,10 @@ Example of a component: ``` @Component({ | Component annotation selector: 'pane', | CSS selector on element - properties: { | List which property need to be bound - 'title': 'title', | - title mapped to component title - 'open': 'open' | - open attribute mapped to component's open property - }, | + properties: [ | List which property need to be bound + 'title', | - title mapped to component title + 'open' | - open attribute mapped to component's open property + ], | }) | @View({ | View annotation templateUrl: 'pane.html' | - URL of template HTML @@ -173,9 +173,9 @@ Directives that use a ViewContainer can control instantiation of child views whi ``` @Directive({ selector: '[if]', - properties: { - 'condition': 'if' - } + properties: [ + 'condition: if' + ] }) export class If { viewContainer: ViewContainerRef; diff --git a/modules/angular2/src/core/annotations_impl/annotations.ts b/modules/angular2/src/core/annotations_impl/annotations.ts index f02497390f..90e0a675f6 100644 --- a/modules/angular2/src/core/annotations_impl/annotations.ts +++ b/modules/angular2/src/core/annotations_impl/annotations.ts @@ -103,9 +103,9 @@ import {DEFAULT} from 'angular2/change_detection'; * * @Directive({ * selector: '[dependency]', - * properties: { - * 'id':'dependency' - * } + * properties: [ + * 'id: dependency' + * ] * }) * class Dependency { * id:string; @@ -275,9 +275,9 @@ import {DEFAULT} from 'angular2/change_detection'; * ``` * @Directive({ * selector: '[tooltip]', - * properties: { - * 'text': 'tooltip' - * }, + * properties: [ + * 'text: tooltip' + * ], * hostListeners: { * 'onmouseenter': 'onMouseEnter()', * 'onmouseleave': 'onMouseLeave()' @@ -361,9 +361,7 @@ import {DEFAULT} from 'angular2/change_detection'; * ``` * @Directive({ * selector: '[unless]', - * properties: { - * 'unless': 'unless' - * } + * properties: ['unless'] * }) * export class Unless { * viewContainer: ViewContainerRef; @@ -453,25 +451,28 @@ export class Directive extends Injectable { * Enumerates the set of properties that accept data binding for a directive. * * The `properties` property defines a set of `directiveProperty` to `bindingProperty` - * key-value pairs: + * configuration: * * - `directiveProperty` specifies the component property where the value is written. * - `bindingProperty` specifies the DOM property where the value is read from. * * You can include a {@link Pipe} when specifying a `bindingProperty` to allow for data - * transformation and structural - * change detection of the value. These pipes will be evaluated in the context of this component. - * + * transformation and structural change detection of the value. These pipes will be evaluated in + * the context of this component. * * ## Syntax * + * There is no need to specify both `directiveProperty` and `bindingProperty` when they both have + * the same value. + * * ``` * @Directive({ - * properties: { - * 'directiveProperty1': 'bindingProperty1', - * 'directiveProperty2': 'bindingProperty2 | pipe1 | ...', + * properties: [ + * 'propertyName', // shorthand notation for 'propertyName: propertyName' + * 'directiveProperty1: bindingProperty1', + * 'directiveProperty2: bindingProperty2 | pipe1 | ...', * ... - * } + * ] * } * ``` * @@ -479,26 +480,24 @@ export class Directive extends Injectable { * ## Basic Property Binding * * We can easily build a simple `Tooltip` directive that exposes a `tooltip` property, which can - * be used in templates - * with standard Angular syntax. For example: + * be used in templates with standard Angular syntax. For example: * * ``` * @Directive({ * selector: '[tooltip]', - * properties: { - * 'text': 'tooltip' - * } + * properties: [ + * 'text: tooltip' + * ] * }) * class Tooltip { - * set text(text) { - * // This will get called every time the 'tooltip' binding changes with the new value. + * set text(value: string) { + * // This will get called every time with the new value when the 'tooltip' property changes * } * } * ``` * * We can then bind to the `tooltip' property as either an expression (`someExpression`) or as a - * string literal, as - * shown in the HTML template below: + * string literal, as shown in the HTML template below: * * ```html *
...
@@ -508,27 +507,24 @@ export class Directive extends Injectable { * Whenever the `someExpression` expression changes, the `properties` declaration instructs * Angular to update the `Tooltip`'s `text` property. * - * - * * ## Bindings With Pipes * * You can also use pipes when writing binding definitions for a directive. * * For example, we could write a binding that updates the directive on structural changes, rather - * than on reference - * changes, as normally occurs in change detection. + * than on reference changes, as normally occurs in change detection. * * See {@link Pipe} and {@link keyValDiff} documentation for more details. * * ``` * @Directive({ * selector: '[class-set]', - * properties: { - * 'classChanges': 'classSet | keyValDiff' - * } + * properties: [ + * 'classChanges: classSet | keyValDiff' + * ] * }) * class ClassSet { - * set classChanges(changes:KeyValueChanges) { + * set classChanges(changes: KeyValueChanges) { * // This will get called every time the `class-set` expressions changes its structure. * } * } @@ -544,7 +540,7 @@ export class Directive extends Injectable { * keyValDiff`. * */ - properties: StringMap; + properties: List; /** * Enumerates the set of emitted events. @@ -756,7 +752,7 @@ export class Directive extends Injectable { hostActions, lifecycle, hostInjector, compileChildren = true, }: { selector?: string, - properties?: any, + properties?: List, events?: List, hostListeners?: StringMap, hostProperties?: StringMap, @@ -981,7 +977,7 @@ export class Component extends Directive { hostActions, appInjector, lifecycle, hostInjector, viewInjector, changeDetection = DEFAULT, compileChildren = true}: { selector?: string, - properties?: Object, + properties?: List, events?: List, hostListeners?: Map, hostProperties?: any, @@ -1053,10 +1049,10 @@ export const onDestroy = CONST_EXPR(new LifecycleEvent("onDestroy")); * ``` * @Directive({ * selector: '[class-set]', - * properties: { - * 'propA': 'propA' - * 'propB': 'propB' - * }, + * properties: [ + * 'propA', + * 'propB' + * ], * lifecycle: [onChange] * }) * class ClassSet { diff --git a/modules/angular2/src/core/annotations_impl/visibility.ts b/modules/angular2/src/core/annotations_impl/visibility.ts index 9d8e1cb298..c6912414e8 100644 --- a/modules/angular2/src/core/annotations_impl/visibility.ts +++ b/modules/angular2/src/core/annotations_impl/visibility.ts @@ -21,9 +21,9 @@ export class Visibility extends DependencyAnnotation { * ``` * @Directive({ * selector: '[dependency]', - * properties: { - * 'id':'dependency' - * } + * properties: [ + * 'id: dependency' + * ] * }) * class Dependency { * id:string; @@ -66,9 +66,9 @@ export var self = new Self(); * ``` * @Directive({ * selector: '[dependency]', - * properties: { - * 'id':'dependency' - * } + * properties: [ + * 'id: dependency' + * ] * }) * class Dependency { * id:string; @@ -118,9 +118,9 @@ export class Parent extends Visibility { * ``` * @Directive({ * selector: '[dependency]', - * properties: { - * 'id':'dependency' - * } + * properties: [ + * 'id: dependency' + * ] * }) * class Dependency { * id:string; @@ -178,9 +178,9 @@ export class Ancestor extends Visibility { * ``` * @Directive({ * selector: '[dependency]', - * properties: { - * 'id':'dependency' - * } + * properties: [ + * 'id: dependency' + * ] * }) * class Dependency { * id:string; diff --git a/modules/angular2/src/core/compiler/element_injector.ts b/modules/angular2/src/core/compiler/element_injector.ts index df7d326aec..59c51e9d1a 100644 --- a/modules/angular2/src/core/compiler/element_injector.ts +++ b/modules/angular2/src/core/compiler/element_injector.ts @@ -300,7 +300,7 @@ export class DirectiveBinding extends ResolvedBinding { isPresent(ann.hostAttributes) ? MapWrapper.createFromStringMap(ann.hostAttributes) : null, hostActions: isPresent(ann.hostActions) ? MapWrapper.createFromStringMap(ann.hostActions) : null, - properties: isPresent(ann.properties) ? MapWrapper.createFromStringMap(ann.properties) : null, + properties: ann.properties, readAttributes: DirectiveBinding._readAttributes(deps), callOnDestroy: hasLifecycleHook(onDestroy, rb.key.token, ann), diff --git a/modules/angular2/src/directives/class.ts b/modules/angular2/src/directives/class.ts index 87517a3f70..889d8fb7f2 100644 --- a/modules/angular2/src/directives/class.ts +++ b/modules/angular2/src/directives/class.ts @@ -4,7 +4,7 @@ import {ElementRef} from 'angular2/core'; import {isPresent} from 'angular2/src/facade/lang'; import {DOM} from 'angular2/src/dom/dom_adapter'; -@Directive({selector: '[class]', properties: {'iterableChanges': 'class | keyValDiff'}}) +@Directive({selector: '[class]', properties: ['iterableChanges: class | keyValDiff']}) export class CSSClass { _domEl; constructor(ngEl: ElementRef) { this._domEl = ngEl.domElement; } diff --git a/modules/angular2/src/directives/ng_for.ts b/modules/angular2/src/directives/ng_for.ts index f2192c46d6..6241eba0c1 100644 --- a/modules/angular2/src/directives/ng_for.ts +++ b/modules/angular2/src/directives/ng_for.ts @@ -36,7 +36,7 @@ import {ListWrapper} from 'angular2/src/facade/collection'; * @exportedAs angular2/directives */ @Directive( - {selector: '[ng-for][ng-for-of]', properties: {'iterableChanges': 'ngForOf | iterableDiff'}}) + {selector: '[ng-for][ng-for-of]', properties: ['iterableChanges: ngForOf | iterableDiff']}) export class NgFor { viewContainer: ViewContainerRef; protoViewRef: ProtoViewRef; diff --git a/modules/angular2/src/directives/ng_if.ts b/modules/angular2/src/directives/ng_if.ts index c132e9ddb1..348f273ca8 100644 --- a/modules/angular2/src/directives/ng_if.ts +++ b/modules/angular2/src/directives/ng_if.ts @@ -27,7 +27,7 @@ import {isBlank} from 'angular2/src/facade/lang'; * * @exportedAs angular2/directives */ -@Directive({selector: '[ng-if]', properties: {'ngIf': 'ngIf'}}) +@Directive({selector: '[ng-if]', properties: ['ngIf']}) export class NgIf { viewContainer: ViewContainerRef; protoViewRef: ProtoViewRef; diff --git a/modules/angular2/src/directives/ng_switch.ts b/modules/angular2/src/directives/ng_switch.ts index 03c6bb1660..cdbb8ac43c 100644 --- a/modules/angular2/src/directives/ng_switch.ts +++ b/modules/angular2/src/directives/ng_switch.ts @@ -44,7 +44,7 @@ export class SwitchView { * * @exportedAs angular2/directives */ -@Directive({selector: '[ng-switch]', properties: {'ngSwitch': 'ngSwitch'}}) +@Directive({selector: '[ng-switch]', properties: ['ngSwitch']}) export class NgSwitch { _switchValue: any; _useDefault: boolean; @@ -153,7 +153,7 @@ export class NgSwitch { * * @exportedAs angular2/directives */ -@Directive({selector: '[ng-switch-when]', properties: {'ngSwitchWhen': 'ngSwitchWhen'}}) +@Directive({selector: '[ng-switch-when]', properties: ['ngSwitchWhen']}) export class NgSwitchWhen { _value: any; _switch: NgSwitch; diff --git a/modules/angular2/src/forms/directives.ts b/modules/angular2/src/forms/directives.ts index c9ecd0560a..6f6c8d6639 100644 --- a/modules/angular2/src/forms/directives.ts +++ b/modules/angular2/src/forms/directives.ts @@ -73,7 +73,7 @@ function _lookupControl(groupDirective: ControlGroupDirective, controlOrName: an * * @exportedAs angular2/forms */ -@Directive({selector: '[control-group]', properties: {'controlOrName': 'control-group'}}) +@Directive({selector: '[control-group]', properties: ['controlOrName: control-group']}) export class ControlGroupDirective { _groupDirective: ControlGroupDirective; _directives: List; @@ -133,7 +133,7 @@ export class ControlGroupDirective { * * @exportedAs angular2/forms */ -@Directive({selector: '[control]', properties: {'controlOrName': 'control'}}) +@Directive({selector: '[control]', properties: ['controlOrName: control']}) export class ControlDirective { _groupDirective: ControlGroupDirective; diff --git a/modules/angular2/src/render/api.ts b/modules/angular2/src/render/api.ts index c4c57cc387..2132ab0396 100644 --- a/modules/angular2/src/render/api.ts +++ b/modules/angular2/src/render/api.ts @@ -133,7 +133,7 @@ export class DirectiveMetadata { hostProperties: Map; hostAttributes: Map; hostActions: Map; - properties: Map; + properties: List; readAttributes: List; type: number; callOnDestroy: boolean; @@ -153,7 +153,7 @@ export class DirectiveMetadata { hostProperties?: Map, hostAttributes?: Map, hostActions?: Map, - properties?: Map, + properties?: List, readAttributes?: List, type?: number, callOnDestroy?: boolean, diff --git a/modules/angular2/src/render/dom/compiler/directive_parser.ts b/modules/angular2/src/render/dom/compiler/directive_parser.ts index ad12ac4fc8..aae3b6df98 100644 --- a/modules/angular2/src/render/dom/compiler/directive_parser.ts +++ b/modules/angular2/src/render/dom/compiler/directive_parser.ts @@ -89,8 +89,8 @@ import { var directiveBinderBuilder = elementBinder.bindDirective(directiveIndex); current.compileChildren = current.compileChildren && directive.compileChildren; if (isPresent(directive.properties)) { - MapWrapper.forEach(directive.properties, (bindConfig, dirProperty) => { - this._bindDirectiveProperty(dirProperty, bindConfig, current, directiveBinderBuilder); + ListWrapper.forEach(directive.properties, (bindConfig) => { + this._bindDirectiveProperty(bindConfig, current, directiveBinderBuilder); }); } if (isPresent(directive.hostListeners)) { @@ -121,10 +121,27 @@ import { }); } - _bindDirectiveProperty(dirProperty: string, bindConfig: string, compileElement: CompileElement, + _bindDirectiveProperty(bindConfig: string, compileElement: CompileElement, directiveBinderBuilder: DirectiveBuilder) { - var pipes = this._splitBindConfig(bindConfig); - var elProp = ListWrapper.removeAt(pipes, 0); + // Name of the property on the directive + let dirProperty: string; + // Name of the property on the element + let elProp: string; + let pipes: List; + let assignIndex: number = bindConfig.indexOf(':'); + + if (assignIndex > -1) { + // canonical syntax: `dirProp: elProp | pipe0 | ... | pipeN` + dirProperty = StringWrapper.substring(bindConfig, 0, assignIndex).trim(); + pipes = this._splitBindConfig(StringWrapper.substring(bindConfig, assignIndex + 1)); + elProp = ListWrapper.removeAt(pipes, 0); + } else { + // shorthand syntax when the name of the property on the directive and on the element is the + // same, ie `property` + dirProperty = bindConfig; + elProp = bindConfig; + pipes = []; + } var bindingAst = MapWrapper.get(compileElement.bindElement().propertyBindings, dashCaseToCamelCase(elProp)); diff --git a/modules/angular2/src/render/dom/convert.ts b/modules/angular2/src/render/dom/convert.ts index 14c533e784..80cf3a2c55 100644 --- a/modules/angular2/src/render/dom/convert.ts +++ b/modules/angular2/src/render/dom/convert.ts @@ -36,7 +36,7 @@ export function directiveMetadataFromMap(map: Map): DirectiveMetada hostProperties:>_cloneIfPresent(MapWrapper.get(map, 'hostProperties')), hostActions:>_cloneIfPresent(MapWrapper.get(map, 'hostActions')), hostAttributes:>_cloneIfPresent(MapWrapper.get(map, 'hostAttributes')), - properties:>_cloneIfPresent(MapWrapper.get(map, 'properties')), + properties:>_cloneIfPresent(MapWrapper.get(map, 'properties')), readAttributes:>_cloneIfPresent(MapWrapper.get(map, 'readAttributes')), type:MapWrapper.get(map, 'type') }); diff --git a/modules/angular2/src/router/router_link.js b/modules/angular2/src/router/router_link.js index 7523579f27..d16ddbb893 100644 --- a/modules/angular2/src/router/router_link.js +++ b/modules/angular2/src/router/router_link.js @@ -31,10 +31,10 @@ import {Location} from './location'; */ @Directive({ selector: '[router-link]', - properties: { - 'route': 'routerLink', - 'params': 'routerParams' - }, + properties: [ + 'route: routerLink', + 'params: routerParams' + ], lifecycle: [onAllChangesDone] }) export class RouterLink { diff --git a/modules/angular2/src/transform/common/directive_metadata_reader.dart b/modules/angular2/src/transform/common/directive_metadata_reader.dart index 1f0787eba4..9b2f89c04c 100644 --- a/modules/angular2/src/transform/common/directive_metadata_reader.dart +++ b/modules/angular2/src/transform/common/directive_metadata_reader.dart @@ -56,7 +56,7 @@ class _DirectiveMetadataVisitor extends Object meta = new DirectiveMetadata( type: type, compileChildren: true, - properties: {}, + properties: [], hostListeners: {}, hostProperties: {}, hostAttributes: {}, diff --git a/modules/angular2/test/core/compiler/compiler_spec.ts b/modules/angular2/test/core/compiler/compiler_spec.ts index 5b3ebcc772..0a1a5af1c9 100644 --- a/modules/angular2/test/core/compiler/compiler_spec.ts +++ b/modules/angular2/test/core/compiler/compiler_spec.ts @@ -219,7 +219,7 @@ export function main() { it('should set directive.bind', inject([AsyncTestCompleter], (async) => { captureDirective(DirectiveWithBind) .then((renderDir) => { - expect(renderDir.properties).toEqual(MapWrapper.createFromStringMap({'a': 'b'})); + expect(renderDir.properties).toEqual(['a: b']); async.done(); }); })); @@ -478,7 +478,7 @@ class DirectiveWithEvents { class DirectiveWithProperties { } -@Directive({properties: {'a': 'b'}}) +@Directive({properties: ['a: b']}) class DirectiveWithBind { } diff --git a/modules/angular2/test/core/compiler/integration_dart_spec.dart b/modules/angular2/test/core/compiler/integration_dart_spec.dart index 1322f98448..63555cb211 100644 --- a/modules/angular2/test/core/compiler/integration_dart_spec.dart +++ b/modules/angular2/test/core/compiler/integration_dart_spec.dart @@ -191,7 +191,7 @@ class NoPropertyAccess { selector: 'on-change', // TODO: needed because of https://github.com/angular/angular/issues/2120 lifecycle: const [onChange], - properties: const { 'prop': 'prop' } + properties: const ['prop'] ) @View(template: '') class OnChangeComponent implements OnChange { diff --git a/modules/angular2/test/core/compiler/integration_spec.ts b/modules/angular2/test/core/compiler/integration_spec.ts index c5eaf07542..ca9eb57c87 100644 --- a/modules/angular2/test/core/compiler/integration_spec.ts +++ b/modules/angular2/test/core/compiler/integration_spec.ts @@ -1173,14 +1173,14 @@ class DynamicViewport { } } -@Directive({selector: '[my-dir]', properties: {'dirProp': 'elprop'}}) +@Directive({selector: '[my-dir]', properties: ['dirProp: elprop']}) @Injectable() class MyDir { dirProp: string; constructor() { this.dirProp = ''; } } -@Component({selector: 'push-cmp', properties: {'prop': 'prop'}, changeDetection: ON_PUSH}) +@Component({selector: 'push-cmp', properties: ['prop'], changeDetection: ON_PUSH}) @View({template: '{{field}}'}) @Injectable() class PushCmp { @@ -1195,7 +1195,7 @@ class PushCmp { } } -@Component({selector: 'push-cmp-with-ref', properties: {'prop': 'prop'}, changeDetection: ON_PUSH}) +@Component({selector: 'push-cmp-with-ref', properties: ['prop'], changeDetection: ON_PUSH}) @View({template: '{{field}}'}) @Injectable() class PushCmpWithRef { @@ -1230,7 +1230,7 @@ class MyComp { } } -@Component({selector: 'component-with-pipes', properties: {"prop": "prop | double"}}) +@Component({selector: 'component-with-pipes', properties: ["prop: prop | double"]}) @View({template: ''}) @Injectable() class ComponentWithPipes { @@ -1412,7 +1412,7 @@ class DirectiveListeningDomEventNoPrevent { onEvent(event) { return true; } } -@Directive({selector: '[id]', properties: {'id': 'id'}}) +@Directive({selector: '[id]', properties: ['id']}) @Injectable() class IdDir { id: string; @@ -1459,7 +1459,7 @@ class ToolbarPart { } } -@Directive({selector: '[toolbar-vc]', properties: {'toolbarVc': 'toolbarVc'}}) +@Directive({selector: '[toolbar-vc]', properties: ['toolbarVc']}) @Injectable() class ToolbarViewContainer { vc: ViewContainerRef; @@ -1487,7 +1487,7 @@ class ToolbarComponent { } } -@Directive({selector: '[two-way]', properties: {value: 'control'}, events: ['control']}) +@Directive({selector: '[two-way]', properties: ['value: control'], events: ['control']}) @Injectable() class DirectiveWithTwoWayBinding { control: EventEmitter; diff --git a/modules/angular2/test/core/compiler/query_integration_spec.ts b/modules/angular2/test/core/compiler/query_integration_spec.ts index 8994618027..a3f190e5d7 100644 --- a/modules/angular2/test/core/compiler/query_integration_spec.ts +++ b/modules/angular2/test/core/compiler/query_integration_spec.ts @@ -87,7 +87,7 @@ export function main() { }); } -@Directive({selector: '[text]', properties: {'text': 'text'}}) +@Directive({selector: '[text]', properties: ['text']}) @Injectable() class TextDirective { text: string; diff --git a/modules/angular2/test/core/directive_lifecycle_integration_spec.ts b/modules/angular2/test/core/directive_lifecycle_integration_spec.ts index 03eee424f9..de60dd3b4f 100644 --- a/modules/angular2/test/core/directive_lifecycle_integration_spec.ts +++ b/modules/angular2/test/core/directive_lifecycle_integration_spec.ts @@ -48,11 +48,8 @@ export function main() { } -@Directive({ - selector: "[lifecycle]", - properties: {'field': 'field'}, - lifecycle: [onChange, onCheck, onInit] -}) +@Directive( + {selector: "[lifecycle]", properties: ['field'], lifecycle: [onChange, onCheck, onInit]}) class LifecycleDir { field; log: List; @@ -69,4 +66,4 @@ class LifecycleDir { @Component({selector: 'my-comp'}) @View({directives: []}) class MyComp { -} \ No newline at end of file +} diff --git a/modules/angular2/test/render/dom/compiler/directive_parser_spec.ts b/modules/angular2/test/render/dom/compiler/directive_parser_spec.ts index f1ea8096e6..3f88755277 100644 --- a/modules/angular2/test/render/dom/compiler/directive_parser_spec.ts +++ b/modules/angular2/test/render/dom/compiler/directive_parser_spec.ts @@ -239,8 +239,7 @@ var decoratorWithMultipleAttrs = new DirectiveMetadata({ var someDirectiveWithProps = new DirectiveMetadata({ selector: '[some-decor-props]', - properties: - MapWrapper.createFromStringMap({'dirProp': 'elProp', 'doubleProp': 'elProp | double'}), + properties: ['dirProp: elProp', 'doubleProp: elProp | double'], readAttributes: ['some-attr'] }); diff --git a/modules/angular2/test/render/dom/convert_spec.ts b/modules/angular2/test/render/dom/convert_spec.ts index 30a7c86572..b810c2847a 100644 --- a/modules/angular2/test/render/dom/convert_spec.ts +++ b/modules/angular2/test/render/dom/convert_spec.ts @@ -12,7 +12,7 @@ export function main() { hostProperties: MapWrapper.createFromPairs([['hostPropKey', 'hostPropVal']]), hostActions: MapWrapper.createFromPairs([['hostActionKey', 'hostActionVal']]), id: 'someComponent', - properties: MapWrapper.createFromPairs([['propKey', 'propVal']]), + properties: ['propKey: propVal'], readAttributes: ['read1', 'read2'], selector: 'some-comp', type: DirectiveMetadata.COMPONENT_TYPE @@ -26,8 +26,7 @@ export function main() { expect(MapWrapper.get(map, 'hostActions')) .toEqual(MapWrapper.createFromPairs([['hostActionKey', 'hostActionVal']])); expect(MapWrapper.get(map, 'id')).toEqual('someComponent'); - expect(MapWrapper.get(map, 'properties')) - .toEqual(MapWrapper.createFromPairs([['propKey', 'propVal']])); + expect(MapWrapper.get(map, 'properties')).toEqual(['propKey: propVal']); expect(MapWrapper.get(map, 'readAttributes')).toEqual(['read1', 'read2']); expect(MapWrapper.get(map, 'selector')).toEqual('some-comp'); expect(MapWrapper.get(map, 'type')).toEqual(DirectiveMetadata.COMPONENT_TYPE); @@ -40,7 +39,7 @@ export function main() { ['hostProperties', MapWrapper.createFromPairs([['hostPropKey', 'hostPropVal']])], ['hostActions', MapWrapper.createFromPairs([['hostActionKey', 'hostActionVal']])], ['id', 'testId'], - ['properties', MapWrapper.createFromPairs([['propKey', 'propVal']])], + ['properties', ['propKey: propVal']], ['readAttributes', ['readTest1', 'readTest2']], ['selector', 'testSelector'], ['type', DirectiveMetadata.DIRECTIVE_TYPE] @@ -53,7 +52,7 @@ export function main() { expect(meta.hostActions) .toEqual(MapWrapper.createFromPairs([['hostActionKey', 'hostActionVal']])); expect(meta.id).toEqual('testId'); - expect(meta.properties).toEqual(MapWrapper.createFromPairs([['propKey', 'propVal']])); + expect(meta.properties).toEqual(['propKey: propVal']); expect(meta.readAttributes).toEqual(['readTest1', 'readTest2']); expect(meta.selector).toEqual('testSelector'); expect(meta.type).toEqual(DirectiveMetadata.DIRECTIVE_TYPE); diff --git a/modules/angular2/test/test_lib/test_component_builder_spec.ts b/modules/angular2/test/test_lib/test_component_builder_spec.ts index af06130bbf..1b61168005 100644 --- a/modules/angular2/test/test_lib/test_component_builder_spec.ts +++ b/modules/angular2/test/test_lib/test_component_builder_spec.ts @@ -43,7 +43,7 @@ class Logger { add(thing: string) { ListWrapper.push(this.log, thing); } } -@Directive({selector: '[message]', properties: {'message': 'message'}}) +@Directive({selector: '[message]', properties: ['message']}) @Injectable() class MessageDir { logger: Logger; diff --git a/modules/angular2/test/transform/bind_generator/basic_bind_files/bar.ng_deps.dart b/modules/angular2/test/transform/bind_generator/basic_bind_files/bar.ng_deps.dart index 21966e3d05..17b1ad3360 100644 --- a/modules/angular2/test/transform/bind_generator/basic_bind_files/bar.ng_deps.dart +++ b/modules/angular2/test/transform/bind_generator/basic_bind_files/bar.ng_deps.dart @@ -13,7 +13,7 @@ void initReflector(reflector) { 'parameters': const [], 'annotations': const [ const Directive( - selector: '[tool-tip]', properties: const {'text': 'tool-tip'}) + selector: '[tool-tip]', properties: const ['text: tool-tip']) ] }); } diff --git a/modules/angular2/test/transform/bind_generator/basic_bind_files/expected/bar.ng_deps.dart b/modules/angular2/test/transform/bind_generator/basic_bind_files/expected/bar.ng_deps.dart index b9ea985e1c..cc36760266 100644 --- a/modules/angular2/test/transform/bind_generator/basic_bind_files/expected/bar.ng_deps.dart +++ b/modules/angular2/test/transform/bind_generator/basic_bind_files/expected/bar.ng_deps.dart @@ -13,7 +13,7 @@ void initReflector(reflector) { 'parameters': const [], 'annotations': const [ const Directive( - selector: '[tool-tip]', properties: const {'text': 'tool-tip'}) + selector: '[tool-tip]', properties: const ['text: tool-tip']) ] }) ..registerSetters({'text': (o, v) => o.text = v}); diff --git a/modules/angular2/test/transform/bind_generator/duplicate_bind_name_files/expected/soup.ng_deps.dart b/modules/angular2/test/transform/bind_generator/duplicate_bind_name_files/expected/soup.ng_deps.dart index b2ceb84a58..ad00f2e2fb 100644 --- a/modules/angular2/test/transform/bind_generator/duplicate_bind_name_files/expected/soup.ng_deps.dart +++ b/modules/angular2/test/transform/bind_generator/duplicate_bind_name_files/expected/soup.ng_deps.dart @@ -14,13 +14,13 @@ void initReflector(reflector) { 'annotations': const [ const Component( componentServices: const [SaladComponent], - properties: const {'menu': 'menu'}) + properties: const ['menu']) ] }) ..registerType(SaladComponent, { 'factory': () => new SaladComponent(), 'parameters': const [], - 'annotations': const [const Component(properties: const {'menu': 'menu'})] + 'annotations': const [const Component(properties: const ['menu'])] }) ..registerSetters({'menu': (o, v) => o.menu = v}); } diff --git a/modules/angular2/test/transform/bind_generator/duplicate_bind_name_files/soup.ng_deps.dart b/modules/angular2/test/transform/bind_generator/duplicate_bind_name_files/soup.ng_deps.dart index e4c7563c3a..76f45bc991 100644 --- a/modules/angular2/test/transform/bind_generator/duplicate_bind_name_files/soup.ng_deps.dart +++ b/modules/angular2/test/transform/bind_generator/duplicate_bind_name_files/soup.ng_deps.dart @@ -14,12 +14,12 @@ void initReflector(reflector) { 'annotations': const [ const Component( componentServices: const [SaladComponent], - properties: const {'menu': 'menu'}) + properties: const ['menu']) ] }) ..registerType(SaladComponent, { 'factory': () => new SaladComponent(), 'parameters': const [], - 'annotations': const [const Component(properties: const {'menu': 'menu'})] + 'annotations': const [const Component(properties: const ['menu'])] }); } diff --git a/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/properties.ng_deps.dart b/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/properties.ng_deps.dart index 38fe4ee1c9..1d552bd94d 100644 --- a/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/properties.ng_deps.dart +++ b/modules/angular2/test/transform/directive_metadata_extractor/directive_metadata_files/properties.ng_deps.dart @@ -13,7 +13,7 @@ void initReflector(reflector) { 'factory': () => new HelloCmp(), 'parameters': const [const []], 'annotations': const [ - const Component(properties: const {'key1': 'val1', 'key2': 'val2'}) + const Component(properties: const ['key1: val1', 'key2: val2']) ] }); } diff --git a/modules/angular2_material/src/components/button/button.ts b/modules/angular2_material/src/components/button/button.ts index be01e2e910..d44eadbeb1 100644 --- a/modules/angular2_material/src/components/button/button.ts +++ b/modules/angular2_material/src/components/button/button.ts @@ -11,7 +11,7 @@ export class MdButton { @Component({ selector: '[md-button][href]', - properties: {'disabled': 'disabled'}, + properties: ['disabled'], hostListeners: {'click': 'onClick($event)'}, hostProperties: {'tabIndex': 'tabIndex'}, lifecycle: [onChange] diff --git a/modules/angular2_material/src/components/checkbox/checkbox.ts b/modules/angular2_material/src/components/checkbox/checkbox.ts index 98adabd271..465d0cc502 100644 --- a/modules/angular2_material/src/components/checkbox/checkbox.ts +++ b/modules/angular2_material/src/components/checkbox/checkbox.ts @@ -6,7 +6,7 @@ import {NumberWrapper} from 'angular2/src/facade/lang'; @Component({ selector: 'md-checkbox', - properties: {'checked': 'checked', 'disabled': 'disabled'}, + properties: ['checked', 'disabled'], hostListeners: {'keydown': 'onKeydown($event)'}, hostProperties: { 'tabindex': 'tabindex', diff --git a/modules/angular2_material/src/components/grid_list/grid_list.ts b/modules/angular2_material/src/components/grid_list/grid_list.ts index 9d9fdd4224..ed8a6b8d7e 100644 --- a/modules/angular2_material/src/components/grid_list/grid_list.ts +++ b/modules/angular2_material/src/components/grid_list/grid_list.ts @@ -19,7 +19,7 @@ import {Math} from 'angular2/src/facade/math'; @Component({ selector: 'md-grid-list', - properties: {'cols': 'cols', 'rowHeight': 'row-height', 'gutterSize': 'gutter-size'}, + properties: ['cols', 'rowHeight', 'gutterSize'], lifecycle: [onAllChangesDone] }) @View({templateUrl: 'angular2_material/src/components/grid_list/grid_list.html'}) @@ -217,7 +217,7 @@ export class MdGridList { @Component({ selector: 'md-grid-tile', - properties: {'rowspan': 'rowspan', 'colspan': 'colspan'}, + properties: ['rowspan', 'colspan'], hostProperties: { 'styleHeight': 'style.height', 'styleWidth': 'style.width', diff --git a/modules/angular2_material/src/components/progress-linear/progress_linear.ts b/modules/angular2_material/src/components/progress-linear/progress_linear.ts index c83d386a14..0bd780db99 100644 --- a/modules/angular2_material/src/components/progress-linear/progress_linear.ts +++ b/modules/angular2_material/src/components/progress-linear/progress_linear.ts @@ -6,7 +6,7 @@ import {Math} from 'angular2/src/facade/math'; @Component({ selector: 'md-progress-linear', lifecycle: [onChange], - properties: {'value': 'value', 'bufferValue': 'buffer-value'}, + properties: ['value', 'bufferValue'], hostProperties: { 'role': 'attr.role', 'ariaValuemin': 'attr.aria-valuemin', diff --git a/modules/angular2_material/src/components/radio/radio_button.ts b/modules/angular2_material/src/components/radio/radio_button.ts index e95959f08a..30dfd56144 100644 --- a/modules/angular2_material/src/components/radio/radio_button.ts +++ b/modules/angular2_material/src/components/radio/radio_button.ts @@ -26,7 +26,7 @@ var _uniqueIdCounter: number = 0; selector: 'md-radio-group', lifecycle: [onChange], events: ['change'], - properties: {'disabled': 'disabled', 'value': 'value'}, + properties: ['disabled', 'value'], hostListeners: { // TODO(jelbourn): Remove ^ when event retargeting is fixed. '^keydown': 'onKeydown($event)' @@ -186,8 +186,7 @@ export class MdRadioGroup { @Component({ selector: 'md-radio-button', lifecycle: [onChange], - properties: - {'id': 'id', 'name': 'name', 'value': 'value', 'checked': 'checked', 'disabled': 'disabled'}, + properties: ['id', 'name', 'value', 'checked', 'disabled'], hostListeners: {'keydown': 'onKeydown($event)'}, hostProperties: { 'id': 'id', diff --git a/modules/angular2_material/src/components/switcher/switch.ts b/modules/angular2_material/src/components/switcher/switch.ts index e3b107d34a..501e3a6d52 100644 --- a/modules/angular2_material/src/components/switcher/switch.ts +++ b/modules/angular2_material/src/components/switcher/switch.ts @@ -8,7 +8,7 @@ import {NumberWrapper} from 'angular2/src/facade/lang'; @Component({ selector: 'md-switch', - properties: {'checked': 'checked', 'disabled': 'disabled'}, + properties: ['checked', 'disabled'], hostListeners: {'keydown': 'onKeydown($event)'}, hostProperties: {'checked': 'attr.aria-checked', 'disabled_': 'attr.aria-disabled', 'role': 'attr.role'} diff --git a/modules/benchmarks/src/compiler/compiler_benchmark.js b/modules/benchmarks/src/compiler/compiler_benchmark.js index aba6648fb7..2b07a74855 100644 --- a/modules/benchmarks/src/compiler/compiler_benchmark.js +++ b/modules/benchmarks/src/compiler/compiler_benchmark.js @@ -81,17 +81,17 @@ export function main() { @Directive({ selector: '[dir0]', - properties: { - 'prop': 'attr0' - } + properties: [ + 'prop: attr0' + ] }) class Dir0 {} @Directive({ selector: '[dir1]', - properties: { - 'prop': 'attr1' - } + properties: [ + 'prop: attr1' + ] }) class Dir1 { constructor(dir0:Dir0) {} @@ -99,9 +99,9 @@ class Dir1 { @Directive({ selector: '[dir2]', - properties: { - 'prop': 'attr2' - } + properties: [ + 'prop: attr2' + ] }) class Dir2 { constructor(dir1:Dir1) {} @@ -109,9 +109,9 @@ class Dir2 { @Directive({ selector: '[dir3]', - properties: { - 'prop': 'attr3' - } + properties: [ + 'prop: attr3' + ] }) class Dir3 { constructor(dir2:Dir2) {} @@ -119,9 +119,9 @@ class Dir3 { @Directive({ selector: '[dir4]', - properties: { - 'prop': 'attr4' - } + properties: [ + 'prop: attr4' + ] }) class Dir4 { constructor(dir3:Dir3) {} diff --git a/modules/benchmarks/src/largetable/largetable_benchmark.js b/modules/benchmarks/src/largetable/largetable_benchmark.js index 2bc96b5f2d..a90d6ee859 100644 --- a/modules/benchmarks/src/largetable/largetable_benchmark.js +++ b/modules/benchmarks/src/largetable/largetable_benchmark.js @@ -233,10 +233,10 @@ class AppComponent { @Component({ selector: 'largetable', - properties: { - 'data': 'data', - 'benchmarkType': 'benchmarktype' - } + properties: [ + 'data', + 'benchmarkType' + ] }) @View({ directives: [NgFor, NgSwitch, NgSwitchWhen, NgSwitchDefault], diff --git a/modules/benchmarks/src/naive_infinite_scroll/cells.js b/modules/benchmarks/src/naive_infinite_scroll/cells.js index ee3641fef9..cb73db0265 100644 --- a/modules/benchmarks/src/naive_infinite_scroll/cells.js +++ b/modules/benchmarks/src/naive_infinite_scroll/cells.js @@ -22,10 +22,10 @@ export class HasStyle { @Component({ selector: 'company-name', - properties: { - 'width': 'cell-width', - 'company': 'company' - } + properties: [ + 'width: cell-width', + 'company' + ] }) @View({ directives: [], @@ -37,10 +37,10 @@ export class CompanyNameComponent extends HasStyle { @Component({ selector: 'opportunity-name', - properties: { - 'width': 'cell-width', - 'opportunity': 'opportunity' - } + properties: [ + 'width: cell-width', + 'opportunity' + ] }) @View({ directives: [], @@ -52,10 +52,10 @@ export class OpportunityNameComponent extends HasStyle { @Component({ selector: 'offering-name', - properties: { - 'width': 'cell-width', - 'offering': 'offering' - } + properties: [ + 'width: cell-width', + 'offering' + ] }) @View({ directives: [], @@ -74,10 +74,10 @@ export class Stage { @Component({ selector: 'stage-buttons', - properties: { - 'width': 'cell-width', - 'offering': 'offering' - } + properties: [ + 'width: cell-width', + 'offering' + ] }) @View({ directives: [NgFor], @@ -133,10 +133,10 @@ export class StageButtonsComponent extends HasStyle { @Component({ selector: 'account-cell', - properties: { - 'width': 'cell-width', - 'account': 'account' - } + properties: [ + 'width: cell-width', + 'account' + ] }) @View({ directives: [], @@ -153,10 +153,10 @@ export class AccountCellComponent extends HasStyle { @Component({ selector: 'formatted-cell', - properties: { - 'width': 'cell-width', - 'value': 'value' - } + properties: [ + 'width: cell-width', + 'value' + ] }) @View({ directives: [], diff --git a/modules/benchmarks/src/naive_infinite_scroll/scroll_item.js b/modules/benchmarks/src/naive_infinite_scroll/scroll_item.js index 9a4719ec35..cd3bcfa873 100644 --- a/modules/benchmarks/src/naive_infinite_scroll/scroll_item.js +++ b/modules/benchmarks/src/naive_infinite_scroll/scroll_item.js @@ -15,9 +15,9 @@ import {Offering, ITEM_HEIGHT, COMPANY_NAME_WIDTH, OPPORTUNITY_NAME_WIDTH, @Component({ selector: 'scroll-item', - properties: { - 'offering': 'offering' - } + properties: [ + 'offering' + ] }) @View({ directives: [ diff --git a/modules/benchmarks/src/tree/tree_benchmark.js b/modules/benchmarks/src/tree/tree_benchmark.js index c203711b63..c4f7c2048a 100644 --- a/modules/benchmarks/src/tree/tree_benchmark.js +++ b/modules/benchmarks/src/tree/tree_benchmark.js @@ -242,7 +242,7 @@ class AppComponent { @Component({ selector: 'tree', - properties: {'data': 'data'} + properties: ['data'] }) @View({ directives: [TreeComponent, NgIf], diff --git a/modules/examples/src/forms/index.ts b/modules/examples/src/forms/index.ts index a69d53729d..cc9cdddf8b 100644 --- a/modules/examples/src/forms/index.ts +++ b/modules/examples/src/forms/index.ts @@ -16,7 +16,7 @@ import {print} from 'angular2/src/facade/lang'; // // // This component is self-contained and can be tested in isolation. -@Component({selector: 'survey-header', properties: {"header": "header"}}) +@Component({selector: 'survey-header', properties: ['header']}) @View({ template: `
@@ -62,11 +62,7 @@ class HeaderFields { // // SurveyQuestion uses EventEmitter to fire the delete action. // This component is self-contained and can be tested in isolation. -@Component({ - selector: 'survey-question', - events: ['destroy'], - properties: {"question": "question", "index": "index"} -}) +@Component({selector: 'survey-question', events: ['destroy'], properties: ['question', 'index']}) @View({ template: `

Question #{{index}}

diff --git a/modules/examples/src/material/dialog/index.js b/modules/examples/src/material/dialog/index.js index b3fcda18b4..f33e9db36b 100644 --- a/modules/examples/src/material/dialog/index.js +++ b/modules/examples/src/material/dialog/index.js @@ -62,7 +62,7 @@ class DemoApp { @Component({ selector: 'simple-dialog', - properties: {'numCoconuts': 'numCoconuts'} + properties: ['numCoconuts'] }) @View({ template: `