diff --git a/modules/change_detection/src/record.js b/modules/change_detection/src/record.js index 6fc5b5fc0b..262cb85038 100644 --- a/modules/change_detection/src/record.js +++ b/modules/change_detection/src/record.js @@ -16,6 +16,7 @@ export const PROTO_RECORD_PROPERTY = 'property'; export class ProtoRecord { @FIELD('final watchGroup:wg.ProtoWatchGroup') @FIELD('final context:Object') + @FIELD('final funcOrValue:Object') @FIELD('final arity:int') @FIELD('final dest') diff --git a/modules/change_detection/src/watch_group.js b/modules/change_detection/src/watch_group.js index ffad34e384..84911b0dd3 100644 --- a/modules/change_detection/src/watch_group.js +++ b/modules/change_detection/src/watch_group.js @@ -1,12 +1,14 @@ import {ProtoRecord, Record, PROTO_RECORD_CONST, PROTO_RECORD_FUNC, PROTO_RECORD_PROPERTY} from './record'; import {FIELD, IMPLEMENTS, isBlank, isPresent, int, toBool, autoConvertAdd, BaseException} from 'facade/lang'; import {ListWrapper} from 'facade/collection'; -import {AST, AccessMember, ImplicitReceiver, AstVisitor, LiteralPrimitive, Binary} from './parser/ast'; +import {AST, AccessMember, ImplicitReceiver, AstVisitor, LiteralPrimitive, Binary, Formatter} from './parser/ast'; export class ProtoWatchGroup { @FIELD('headRecord:ProtoRecord') @FIELD('tailRecord:ProtoRecord') - constructor() { + constructor(formatters) { + this.formatters = formatters; + this.headRecord = null; this.tailRecord = null; } @@ -179,6 +181,15 @@ class ProtoRecordCreator { this.add(record); } + visitFormatter(ast:Formatter, dest) { + var formatter = this.protoWatchGroup.formatters[ast.name]; + var record = this.construct(PROTO_RECORD_FUNC, formatter, ast.allArgs.length, dest); + for (var i = 0; i < ast.allArgs.length; ++i) { + ast.allArgs[i].visit(this, new Destination(record, i)); + } + this.add(record); + } + createRecordsFromAST(ast:AST, memento){ ast.visit(this, memento); } diff --git a/modules/change_detection/test/change_detector_spec.js b/modules/change_detection/test/change_detector_spec.js index 690e5e15c8..00c82c4ba5 100644 --- a/modules/change_detection/test/change_detector_spec.js +++ b/modules/change_detection/test/change_detector_spec.js @@ -21,8 +21,8 @@ export function main() { return parser.parseBinding(exp); } - function createChangeDetector(memo:string, exp:string, context = null) { - var pwg = new ProtoWatchGroup(); + function createChangeDetector(memo:string, exp:string, context = null, formatters = null) { + var pwg = new ProtoWatchGroup(formatters); pwg.watch(ast(exp), memo, false); var dispatcher = new LoggingDispatcher(); @@ -34,8 +34,8 @@ export function main() { return {"changeDetector" : cd, "dispatcher" : dispatcher}; } - function executeWatch(memo:string, exp:string, context = null) { - var res = createChangeDetector(memo, exp, context); + function executeWatch(memo:string, exp:string, context = null, formatters = null) { + var res = createChangeDetector(memo, exp, context, formatters); res["changeDetector"].detectChanges(); return res["dispatcher"].log; } @@ -61,7 +61,7 @@ export function main() { expect(dispatcher.log).toEqual(['name=Misko']); }); - it('should watch chained properties', () => { + it('should support chained properties', () => { var address = new Address('Grenoble'); var person = new Person('Victor', address); @@ -69,11 +69,11 @@ export function main() { .toEqual(['address.city=Grenoble']); }); - it("should watch literals", () => { + it("should support literals", () => { expect(executeWatch('const', '10')).toEqual(['const=10']); }); - it("should watch binary operations", () => { + it("should support binary operations", () => { expect(executeWatch('exp', '10 + 2')).toEqual(['exp=12']); expect(executeWatch('exp', '10 - 2')).toEqual(['exp=8']); @@ -104,6 +104,15 @@ export function main() { expect(executeWatch('exp', 'true || false')).toEqual(['exp=true']); expect(executeWatch('exp', 'false || false')).toEqual(['exp=false']); }); + + it("should support formatters", () => { + var formatters = { + "uppercase" : (v) => v.toUpperCase(), + "wrap" : (v, before, after) => `${before}${v}${after}` + }; + expect(executeWatch('str', '"aBc" | uppercase', null, formatters)).toEqual(['str=ABC']); + expect(executeWatch('str', '"b" | wrap:"a":"c"', null, formatters)).toEqual(['str=abc']); + }); }); }); } diff --git a/modules/core/test/compiler/view_spec.js b/modules/core/test/compiler/view_spec.js index 1ad1da2214..1151ca7d3a 100644 --- a/modules/core/test/compiler/view_spec.js +++ b/modules/core/test/compiler/view_spec.js @@ -100,7 +100,7 @@ export function main() { beforeEach(() => { var template = DOM.createTemplate(tempalteWithThreeTypesOfBindings); var pv = new ProtoView(template, templateElementBinders(), - new ProtoWatchGroup(), false); + new ProtoWatchGroup(null), false); view = pv.instantiate(null, null); }); @@ -142,7 +142,12 @@ export function main() { describe('react to watch group changes', () => { var view, cd, ctx; - function createView(protoView) { + var protoWatchGroup = new ProtoWatchGroup(); + protoWatchGroup.watch(oneFieldAst('foo'), memento); + + var pv = new ProtoView(template, templateElementBinders(), + protoWatchGroup, false); + ctx = new MyEvaluationContext(); view = protoView.instantiate(ctx, null); cd = new ChangeDetector(view.watchGroup);