Skip to content

Commit

Permalink
feat(pipes): support arguments in transform function
Browse files Browse the repository at this point in the history
  • Loading branch information
piloopin authored and vsavkin committed Jul 1, 2015
1 parent f0e962c commit 600d53c
Show file tree
Hide file tree
Showing 19 changed files with 74 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ export class ChangeDetectorJITGenerator {

_genPipeCheck(r: ProtoRecord): string {
var context = this._localNames[r.contextIndex];
var argString = r.args.map((arg) => this._localNames[arg]).join(", ");

var oldValue = this._fieldNames[r.selfIndex];
var newValue = this._localNames[r.selfIndex];
var change = this._changeNames[r.selfIndex];
Expand All @@ -259,7 +261,7 @@ export class ChangeDetectorJITGenerator {
${pipe} = ${PIPE_REGISTRY_ACCESSOR}.get('${pipeType}', ${context}, ${cdRef});
}
${newValue} = ${pipe}.transform(${context});
${newValue} = ${pipe}.transform(${context}, [${argString}]);
if (${oldValue} !== ${newValue}) {
${newValue} = ${UTIL}.unwrapValue(${newValue});
${change} = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,11 @@ export class DynamicChangeDetector extends AbstractChangeDetector {

_pipeCheck(proto: ProtoRecord, throwOnChange: boolean) {
var context = this._readContext(proto);
var args = this._readArgs(proto);

var pipe = this._pipeFor(proto, context);
var prevValue = this._readSelf(proto);

var currValue = pipe.transform(context);
var currValue = pipe.transform(context, args);

if (!isSame(prevValue, currValue)) {
currValue = ChangeDetectionUtil.unwrapValue(currValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ import {
} from 'angular2/src/facade/lang';

import {WrappedValue, Pipe, BasePipe, PipeFactory} from './pipe';
import {ChangeDetectorRef} from '../change_detector_ref';

@CONST()
export class IterableChangesFactory implements PipeFactory {
supports(obj): boolean { return IterableChanges.supportsObj(obj); }

create(cdRef): Pipe { return new IterableChanges(); }
create(cdRef: ChangeDetectorRef): Pipe { return new IterableChanges(); }
}

/**
Expand Down Expand Up @@ -89,7 +90,7 @@ export class IterableChanges extends BasePipe {
}
}

transform(collection): any {
transform(collection, args: List<any> = null): any {
if (this.check(collection)) {
return WrappedValue.wrap(this);
} else {
Expand Down
7 changes: 4 additions & 3 deletions modules/angular2/src/change_detection/pipes/json_pipe.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {isBlank, isPresent, Json, CONST} from 'angular2/src/facade/lang';
import {Pipe, BasePipe, PipeFactory} from './pipe';
import {ChangeDetectorRef} from '../change_detector_ref';

/**
* Implements json transforms to any object.
Expand Down Expand Up @@ -27,8 +28,8 @@ import {Pipe, BasePipe, PipeFactory} from './pipe';
* @exportedAs angular2/pipes
*/
@CONST()
export class JsonPipe extends BasePipe {
transform(value): string { return Json.stringify(value); }
export class JsonPipe extends BasePipe implements PipeFactory {
transform(value, args: List<any> = null): string { return Json.stringify(value); }

create(cdRef): Pipe { return this }
create(cdRef: ChangeDetectorRef): Pipe { return this }
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import {stringify, looseIdentical, isJsObject, CONST} from 'angular2/src/facade/lang';

import {ChangeDetectorRef} from '../change_detector_ref';
import {WrappedValue, BasePipe, Pipe, PipeFactory} from './pipe';

/**
Expand All @@ -10,7 +10,7 @@ import {WrappedValue, BasePipe, Pipe, PipeFactory} from './pipe';
export class KeyValueChangesFactory implements PipeFactory {
supports(obj): boolean { return KeyValueChanges.supportsObj(obj); }

create(cdRef): Pipe { return new KeyValueChanges(); }
create(cdRef: ChangeDetectorRef): Pipe { return new KeyValueChanges(); }
}

/**
Expand All @@ -31,7 +31,7 @@ export class KeyValueChanges extends BasePipe {

supports(obj): boolean { return KeyValueChanges.supportsObj(obj); }

transform(map): any {
transform(map, args: List<any> = null): any {
if (this.check(map)) {
return WrappedValue.wrap(this);
} else {
Expand Down
9 changes: 5 additions & 4 deletions modules/angular2/src/change_detection/pipes/lowercase_pipe.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {isString, StringWrapper, CONST} from 'angular2/src/facade/lang';
import {Pipe} from './pipe';
import {Pipe, PipeFactory} from './pipe';
import {ChangeDetectorRef} from '../change_detector_ref';

/**
* Implements lowercase transforms to text.
Expand Down Expand Up @@ -30,7 +31,7 @@ export class LowerCasePipe implements Pipe {

onDestroy(): void { this._latestValue = null; }

transform(value: string): string {
transform(value: string, args: List<any> = null): string {
if (this._latestValue !== value) {
this._latestValue = value;
return StringWrapper.toLowerCase(value);
Expand All @@ -44,8 +45,8 @@ export class LowerCasePipe implements Pipe {
* @exportedAs angular2/pipes
*/
@CONST()
export class LowerCaseFactory {
export class LowerCaseFactory implements PipeFactory {
supports(str): boolean { return isString(str); }

create(): Pipe { return new LowerCasePipe(); }
create(cdRef: ChangeDetectorRef): Pipe { return new LowerCasePipe(); }
}
5 changes: 3 additions & 2 deletions modules/angular2/src/change_detection/pipes/null_pipe.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {isBlank, CONST} from 'angular2/src/facade/lang';
import {Pipe, BasePipe, WrappedValue, PipeFactory} from './pipe';
import {ChangeDetectorRef} from '../change_detector_ref';

/**
* @exportedAs angular2/pipes
Expand All @@ -8,7 +9,7 @@ import {Pipe, BasePipe, WrappedValue, PipeFactory} from './pipe';
export class NullPipeFactory implements PipeFactory {
supports(obj): boolean { return NullPipe.supportsObj(obj); }

create(cdRef): Pipe { return new NullPipe(); }
create(cdRef: ChangeDetectorRef): Pipe { return new NullPipe(); }
}

/**
Expand All @@ -21,7 +22,7 @@ export class NullPipe extends BasePipe {

supports(obj): boolean { return NullPipe.supportsObj(obj); }

transform(value): WrappedValue {
transform(value, args: List<any> = null): WrappedValue {
if (!this.called) {
this.called = true;
return WrappedValue.wrap(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class ObservablePipe implements Pipe {
}
}

transform(obs: Observable): any {
transform(obs: Observable, args: List<any> = null): any {
if (isBlank(this._subscription)) {
this._subscribe(obs);
return null;
Expand Down Expand Up @@ -94,5 +94,5 @@ export class ObservablePipe implements Pipe {
export class ObservablePipeFactory implements PipeFactory {
supports(obs): boolean { return ObservableWrapper.isObservable(obs); }

create(cdRef): Pipe { return new ObservablePipe(cdRef); }
create(cdRef: ChangeDetectorRef): Pipe { return new ObservablePipe(cdRef); }
}
9 changes: 5 additions & 4 deletions modules/angular2/src/change_detection/pipes/pipe.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {ABSTRACT, BaseException, CONST} from 'angular2/src/facade/lang';
import {ChangeDetectorRef} from '../change_detector_ref';

/**
* Indicates that the result of a {@link Pipe} transformation has changed even though the reference
Expand Down Expand Up @@ -43,7 +44,7 @@ var _wrappedIndex = 0;
*
* onDestroy() {}
*
* transform(value) {
* transform(value, args = []) {
* return `${value}${value}`;
* }
* }
Expand All @@ -54,7 +55,7 @@ var _wrappedIndex = 0;
export interface Pipe {
supports(obj): boolean;
onDestroy(): void;
transform(value: any): any;
transform(value: any, args: List<any>): any;
}

/**
Expand All @@ -74,12 +75,12 @@ export interface Pipe {
export class BasePipe implements Pipe {
supports(obj): boolean { return true; }
onDestroy(): void {}
transform(value: any): any { return _abstract(); }
transform(value: any, args: List<any>): any { return _abstract(); }
}

export interface PipeFactory {
supports(obs): boolean;
create(cdRef): Pipe;
create(cdRef: ChangeDetectorRef): Pipe;
}

function _abstract() {
Expand Down
8 changes: 4 additions & 4 deletions modules/angular2/src/change_detection/pipes/promise_pipe.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
import {isBlank, isPresent, isPromise, CONST} from 'angular2/src/facade/lang';
import {Pipe, WrappedValue} from './pipe';
import {Pipe, PipeFactory, WrappedValue} from './pipe';
import {ChangeDetectorRef} from '../change_detector_ref';

/**
Expand Down Expand Up @@ -45,7 +45,7 @@ export class PromisePipe implements Pipe {
}
}

transform(promise: Promise<any>): any {
transform(promise: Promise<any>, args: List<any> = null): any {
if (isBlank(this._sourcePromise)) {
this._sourcePromise = promise;
promise.then((val) => {
Expand Down Expand Up @@ -81,8 +81,8 @@ export class PromisePipe implements Pipe {
* @exportedAs angular2/pipes
*/
@CONST()
export class PromisePipeFactory {
export class PromisePipeFactory implements PipeFactory {
supports(promise): boolean { return isPromise(promise); }

create(cdRef): Pipe { return new PromisePipe(cdRef); }
create(cdRef: ChangeDetectorRef): Pipe { return new PromisePipe(cdRef); }
}
9 changes: 5 additions & 4 deletions modules/angular2/src/change_detection/pipes/uppercase_pipe.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {isString, StringWrapper, CONST} from 'angular2/src/facade/lang';
import {Pipe} from './pipe';
import {Pipe, PipeFactory} from './pipe';
import {ChangeDetectorRef} from '../change_detector_ref';

/**
* Implements uppercase transforms to text.
Expand Down Expand Up @@ -30,7 +31,7 @@ export class UpperCasePipe implements Pipe {

onDestroy(): void { this._latestValue = null; }

transform(value: string): string {
transform(value: string, args: List<any> = null): string {
if (this._latestValue !== value) {
this._latestValue = value;
return StringWrapper.toUpperCase(value);
Expand All @@ -44,8 +45,8 @@ export class UpperCasePipe implements Pipe {
* @exportedAs angular2/pipes
*/
@CONST()
export class UpperCaseFactory {
export class UpperCaseFactory implements PipeFactory {
supports(str): boolean { return isString(str); }

create(): Pipe { return new UpperCasePipe(); }
create(cdRef: ChangeDetectorRef): Pipe { return new UpperCasePipe(); }
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ class _ConvertAstIntoProtoRecords implements AstVisitor {

visitPipe(ast: BindingPipe): number {
var value = ast.exp.visit(this);
return this._addRecord(RecordType.PIPE, ast.name, ast.name, [], null, value);
var args = this._visitAll(ast.args);
return this._addRecord(RecordType.PIPE, ast.name, ast.name, args, null, value);
}

visitKeyedAccess(ast: KeyedAccess): number {
Expand Down
2 changes: 1 addition & 1 deletion modules/angular2/src/directives/class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class CSSClass {
}

onCheck(): void {
var diff = this._pipe.transform(this._rawClass);
var diff = this._pipe.transform(this._rawClass, null);
if (isPresent(diff) && isPresent(diff.wrapped)) {
if (diff.wrapped instanceof IterableChanges) {
this._applyArrayChanges(diff.wrapped);
Expand Down
2 changes: 1 addition & 1 deletion modules/angular2/src/directives/ng_for.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class NgFor {
}

onCheck() {
var diff = this._pipe.transform(this._ngForOf);
var diff = this._pipe.transform(this._ngForOf, null);
if (isPresent(diff)) this._applyChanges(diff.wrapped);
}

Expand Down
2 changes: 1 addition & 1 deletion modules/angular2/src/directives/ng_style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class NgStyle {
}

onCheck() {
var diff = this._pipe.transform(this._rawStyle);
var diff = this._pipe.transform(this._rawStyle, null);
if (isPresent(diff) && isPresent(diff.wrapped)) {
this._applyChanges(diff.wrapped);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ class _CodegenState {

String _genPipeCheck(ProtoRecord r) {
var context = _localNames[r.contextIndex];
var argString = r.args.map((arg) => this._localNames[arg]).join(", ");

var oldValue = _fieldNames[r.selfIndex];
var newValue = _localNames[r.selfIndex];
var change = _changeNames[r.selfIndex];
Expand All @@ -322,7 +324,7 @@ class _CodegenState {
$pipe = $_PIPE_REGISTRY_ACCESSOR.get('$pipeType', $context, $cdRef);
}
$newValue = $pipe.transform($context);
$newValue = $pipe.transform($context, [$argString]);
if (!$_IDENTICAL_CHECK_FN($oldValue, $newValue)) {
$newValue = $_UTIL.unwrapValue($newValue);
$change = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ var _availableDefinitions = [
'{z: 1}',
'{z: a}',
'name | pipe',
"name | pipe:'one':address.city",
'value',
'a',
'address.city',
Expand Down
28 changes: 24 additions & 4 deletions modules/angular2/test/change_detection/change_detector_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,15 @@ export function main() {
val.changeDetector.detectChanges();
expect(val.dispatcher.loggedValues).toEqual(['bob state:0']);
});

it('should support arguments in pipes', () => {
var registry = new FakePipeRegistry('pipe', () => new MultiArgPipe());
var address = new Address('two');
var person = new Person('value', address);
var val = _createChangeDetector("name | pipe:'one':address.city", person, registry);
val.changeDetector.detectChanges();
expect(val.dispatcher.loggedValues).toEqual(['value one two default']);
});
});

it('should notify the dispatcher on all changes done', () => {
Expand Down Expand Up @@ -861,7 +870,7 @@ class CountingPipe implements Pipe {

supports(newValue) { return true; }

transform(value) { return `${value} state:${this.state ++}`; }
transform(value, args = null) { return `${value} state:${this.state ++}`; }
}

class OncePipe implements Pipe {
Expand All @@ -872,7 +881,7 @@ class OncePipe implements Pipe {

onDestroy() { this.destroyCalled = true; }

transform(value) {
transform(value, args = null) {
this.called = true;
return value;
}
Expand All @@ -883,15 +892,26 @@ class IdentityPipe implements Pipe {

onDestroy() {}

transform(value) { return value; }
transform(value, args = null) { return value; }
}

class WrappedPipe implements Pipe {
supports(obj): boolean { return true; }

onDestroy() {}

transform(value) { return WrappedValue.wrap(value); }
transform(value, args = null) { return WrappedValue.wrap(value); }
}

class MultiArgPipe implements Pipe {
transform(value, args = null) {
var arg1 = args[0];
var arg2 = args[1];
var arg3 = args.length > 2 ? args[2] : 'default';
return `${value} ${arg1} ${arg2} ${arg3}`;
}
supports(obj): boolean { return true; }
onDestroy(): void {}
}

class FakePipeRegistry extends PipeRegistry {
Expand Down
2 changes: 1 addition & 1 deletion modules/angular2/test/core/compiler/integration_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1473,7 +1473,7 @@ class DoublePipe implements Pipe {

supports(obj) { return true; }

transform(value) { return `${value}${value}`; }
transform(value, args = null) { return `${value}${value}`; }
}

@Injectable()
Expand Down

0 comments on commit 600d53c

Please sign in to comment.