diff --git a/modules/angular2/src/core/facade/collection.dart b/modules/angular2/src/core/facade/collection.dart index e58c310be2..9f566806bf 100644 --- a/modules/angular2/src/core/facade/collection.dart +++ b/modules/angular2/src/core/facade/collection.dart @@ -182,11 +182,13 @@ class ListWrapper { } static List slice(List l, [int from = 0, int to]) { + from = _startOffset(l, from); + to = _endOffset(l, to); //in JS if from > to an empty array is returned if(to != null && from > to) { return []; } - return l.sublist(_startOffset(l, from), _endOffset(l, to)); + return l.sublist(from, to); } static List splice(List l, int from, int length) { @@ -213,7 +215,7 @@ class ListWrapper { // the end of the list static int _startOffset(List l, int start) { int len = l.length; - return start = start < 0 ? max(len + start, 0) : min(start, len); + return start < 0 ? max(len + start, 0) : min(start, len); } // JS splice, slice, fill functions can take end < 0 which indicates a position relative to diff --git a/modules/angular2/src/core/facade/lang.dart b/modules/angular2/src/core/facade/lang.dart index fa7d3096ac..3939834ec5 100644 --- a/modules/angular2/src/core/facade/lang.dart +++ b/modules/angular2/src/core/facade/lang.dart @@ -95,11 +95,13 @@ class StringWrapper { } static String slice(String s, [int start = 0, int end]) { + start = _startOffset(s, start); + end = _endOffset(s, end); //in JS if start > end an empty string is returned if(end != null && start > end) { return ""; } - return s.substring(_startOffset(s, start), _endOffset(s, end)); + return s.substring(start, end); } static String substring(String s, int start, [int end]) { @@ -120,7 +122,7 @@ class StringWrapper { // the end of the string static int _startOffset(String s, int start) { int len = s.length; - return start = start < 0 ? math.max(len + start, 0) : math.min(start, len); + return start < 0 ? math.max(len + start, 0) : math.min(start, len); } // JS slice function can take end < 0 which indicates a position relative to diff --git a/modules/angular2/src/core/pipes.ts b/modules/angular2/src/core/pipes.ts index 2b918fe845..8487d3ef89 100644 --- a/modules/angular2/src/core/pipes.ts +++ b/modules/angular2/src/core/pipes.ts @@ -8,7 +8,7 @@ export {AsyncPipe} from './pipes/async_pipe'; export {DatePipe} from './pipes/date_pipe'; export {DEFAULT_PIPES, DEFAULT_PIPES_TOKEN} from './pipes/default_pipes'; export {JsonPipe} from './pipes/json_pipe'; -export {LimitToPipe} from './pipes/limit_to_pipe'; +export {SlicePipe} from './pipes/slice_pipe'; export {LowerCasePipe} from './pipes/lowercase_pipe'; export {NumberPipe, DecimalPipe, PercentPipe, CurrencyPipe} from './pipes/number_pipe'; export {UpperCasePipe} from './pipes/uppercase_pipe'; diff --git a/modules/angular2/src/core/pipes/default_pipes.ts b/modules/angular2/src/core/pipes/default_pipes.ts index c95d9c2312..7ab1b07df2 100644 --- a/modules/angular2/src/core/pipes/default_pipes.ts +++ b/modules/angular2/src/core/pipes/default_pipes.ts @@ -2,7 +2,7 @@ import {AsyncPipe} from './async_pipe'; import {UpperCasePipe} from './uppercase_pipe'; import {LowerCasePipe} from './lowercase_pipe'; import {JsonPipe} from './json_pipe'; -import {LimitToPipe} from './limit_to_pipe'; +import {SlicePipe} from './slice_pipe'; import {DatePipe} from './date_pipe'; import {DecimalPipe, PercentPipe, CurrencyPipe} from './number_pipe'; @@ -14,7 +14,7 @@ const DEFAULT_PIPES_LIST = CONST_EXPR([ UpperCasePipe, LowerCasePipe, JsonPipe, - LimitToPipe, + SlicePipe, DecimalPipe, PercentPipe, CurrencyPipe, diff --git a/modules/angular2/src/core/pipes/limit_to_pipe.ts b/modules/angular2/src/core/pipes/limit_to_pipe.ts deleted file mode 100644 index c375e62edd..0000000000 --- a/modules/angular2/src/core/pipes/limit_to_pipe.ts +++ /dev/null @@ -1,73 +0,0 @@ -import {isBlank, isString, isArray, StringWrapper, CONST} from 'angular2/src/core/facade/lang'; -import {BaseException, WrappedException} from 'angular2/src/core/facade/exceptions'; -import {ListWrapper} from 'angular2/src/core/facade/collection'; -import {Math} from 'angular2/src/core/facade/math'; -import {PipeTransform, WrappedValue} from 'angular2/src/core/change_detection'; -import {Injectable} from 'angular2/src/core/di'; -import {Pipe} from 'angular2/src/core/metadata'; -import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception'; - -/** - * Creates a new Array or String containing only a prefix/suffix of the - * elements. - * - * The number of elements to return is specified by the `limitTo` parameter. - * - * # Usage - * - * expression | limitTo:number - * - * Where the input expression is a [Array] or [String], and `limitTo` is: - * - * - **a positive integer**: return _number_ items from the beginning of the list or string - * expression. - * - **a negative integer**: return _number_ items from the end of the list or string expression. - * - **`|limitTo|` greater than the size of the expression**: return the entire expression. - * - * When operating on a [Array], the returned list is always a copy even when all - * the elements are being returned. - * - * # Examples - * - * ## Array Example - * - * Assuming `var collection = ['a', 'b', 'c']`, this `ng-for` directive: - * - *
  • {{i}}
  • - * - * produces the following: - * - *
  • a
  • - *
  • b
  • - * - * ## String Examples - * - * {{ 'abcdefghij' | limitTo: 4 }} // output is 'abcd' - * {{ 'abcdefghij' | limitTo: -4 }} // output is 'ghij' - * {{ 'abcdefghij' | limitTo: -100 }} // output is 'abcdefghij' - */ -@Pipe({name: 'limitTo'}) -@Injectable() -export class LimitToPipe implements PipeTransform { - supports(obj: any): boolean { return isString(obj) || isArray(obj); } - - transform(value: any, args: any[] = null): any { - if (isBlank(args) || args.length == 0) { - throw new BaseException('limitTo pipe requires one argument'); - } - if (!this.supports(value)) { - throw new InvalidPipeArgumentException(LimitToPipe, value); - } - if (isBlank(value)) return value; - var limit: number = args[0]; - var left = 0, right = Math.min(limit, value.length); - if (limit < 0) { - left = Math.max(0, value.length + limit); - right = value.length; - } - if (isString(value)) { - return StringWrapper.substring(value, left, right); - } - return ListWrapper.slice(value, left, right); - } -} diff --git a/modules/angular2/src/core/pipes/slice_pipe.ts b/modules/angular2/src/core/pipes/slice_pipe.ts index 81adc32c3b..240064fc65 100644 --- a/modules/angular2/src/core/pipes/slice_pipe.ts +++ b/modules/angular2/src/core/pipes/slice_pipe.ts @@ -3,9 +3,9 @@ import { isString, isArray, StringWrapper, - BaseException, CONST } from 'angular2/src/core/facade/lang'; +import {BaseException} from 'angular2/src/core/facade/exceptions'; import {ListWrapper} from 'angular2/src/core/facade/collection'; import {Injectable} from 'angular2/di'; @@ -76,7 +76,7 @@ import {Pipe} from '../metadata'; @Pipe({name: 'slice'}) @Injectable() export class SlicePipe implements PipeTransform { - transform(value: any, args: List = null): any { + transform(value: any, args: any[] = null): any { if (isBlank(args) || args.length == 0) { throw new BaseException('Slice pipe requires one argument'); } @@ -85,7 +85,7 @@ export class SlicePipe implements PipeTransform { } if (isBlank(value)) return value; var start: number = args[0]; - var end: number = args.length > 1 ? args[1] : value.length; + var end: number = args.length > 1 ? args[1] : null; if (isString(value)) { return StringWrapper.slice(value, start, end); } diff --git a/modules/angular2/test/core/facade/collection_spec.ts b/modules/angular2/test/core/facade/collection_spec.ts index bd3d2c3786..8ef1eb325c 100644 --- a/modules/angular2/test/core/facade/collection_spec.ts +++ b/modules/angular2/test/core/facade/collection_spec.ts @@ -63,8 +63,10 @@ export function main() { it('should support negative end', () => { expect(ListWrapper.slice(l, -3, -1)).toEqual([2, 3]); }); - it('should return empty list if start is greater than end', - () => { expect(ListWrapper.slice(l, 4, 2)).toEqual([]); }); + it('should return empty list if start is greater than end', () => { + expect(ListWrapper.slice(l, 4, 2)).toEqual([]); + expect(ListWrapper.slice(l, -2, -4)).toEqual([]); + }); }); describe('indexOf', () => { diff --git a/modules/angular2/test/core/facade/lang_spec.ts b/modules/angular2/test/core/facade/lang_spec.ts index 6799ccd6a9..8cdd7f1569 100644 --- a/modules/angular2/test/core/facade/lang_spec.ts +++ b/modules/angular2/test/core/facade/lang_spec.ts @@ -76,8 +76,10 @@ export function main() { it('should support negative end', () => { expect(StringWrapper.slice(s, -3, -1)).toEqual("hi"); }); - it('should return empty string if start is greater than end', - () => { expect(StringWrapper.slice(s, 4, 2)).toEqual(""); }); + it('should return empty string if start is greater than end', () => { + expect(StringWrapper.slice(s, 4, 2)).toEqual(""); + expect(StringWrapper.slice(s, -2, -4)).toEqual(""); + }); }); }); diff --git a/modules/angular2/test/core/pipes/limit_to_pipe_spec.ts b/modules/angular2/test/core/pipes/limit_to_pipe_spec.ts deleted file mode 100644 index a57498e315..0000000000 --- a/modules/angular2/test/core/pipes/limit_to_pipe_spec.ts +++ /dev/null @@ -1,57 +0,0 @@ -import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib'; - -import {LimitToPipe} from 'angular2/core'; - -export function main() { - describe("LimitToPipe", () => { - var list; - var str; - var pipe; - - beforeEach(() => { - list = [1, 2, 3, 4, 5]; - str = 'tuvwxyz'; - pipe = new LimitToPipe(); - }); - - describe("supports", () => { - it("should support strings", () => { expect(pipe.supports(str)).toBe(true); }); - it("should support lists", () => { expect(pipe.supports(list)).toBe(true); }); - - it("should not support other objects", () => { - expect(pipe.supports(new Object())).toBe(false); - expect(pipe.supports(null)).toBe(false); - }); - }); - - describe("transform", () => { - - it('should return the first X items when X is positive', () => { - expect(pipe.transform(list, [3])).toEqual([1, 2, 3]); - expect(pipe.transform(str, [3])).toEqual('tuv'); - }); - - it('should return the last X items when X is negative', () => { - expect(pipe.transform(list, [-3])).toEqual([3, 4, 5]); - expect(pipe.transform(str, [-3])).toEqual('xyz'); - }); - - it('should return a copy of input array if X is exceeds array length', () => { - expect(pipe.transform(list, [20])).toEqual(list); - expect(pipe.transform(list, [-20])).toEqual(list); - }); - - it('should return the entire string if X exceeds input length', () => { - expect(pipe.transform(str, [20])).toEqual(str); - expect(pipe.transform(str, [-20])).toEqual(str); - }); - - it('should not modify the input list', () => { - expect(pipe.transform(list, [3])).toEqual([1, 2, 3]); - expect(list).toEqual([1, 2, 3, 4, 5]); - }); - - }); - - }); -}