1+ /**
2+ * @ngdoc filter
3+ * @name angular.filter.currency
4+ * @function
5+ *
6+ * @description
7+ * Formats a number as a currency (ie $1,234.56).
8+ *
9+ * @param {number } amout Input to filter.
10+ * @returns {string } Formated number.
11+ *
12+ * @css ng-format-negative
13+ * When the value is negative, this css class is applied to the binding making it by default red.
14+ *
15+ * @example
16+ * <input type="text" name="amount" value="1234.56"/> <br/>
17+ * {{amount | currency}}
18+ *
19+ * @scenario
20+ * it('should init with 1234.56', function(){
21+ * expect(bind('amount')).toEqual('$1,234.56');
22+ * });
23+ * it('should update', function(){
24+ * element(':input[name=amount]').value('-1234');
25+ * expect(bind('amount')).toEqual('-$1,234.00');
26+ * expect(bind('amount')).toHaveColor('red');
27+ * });
28+ */
129angularFilter . currency = function ( amount ) {
230 this . $element . toggleClass ( 'ng-format-negative' , amount < 0 ) ;
331 return '$' + angularFilter [ 'number' ] . apply ( this , [ amount , 2 ] ) ;
432} ;
533
6- angularFilter . number = function ( amount , fractionSize ) {
7- if ( isNaN ( amount ) || ! isFinite ( amount ) ) {
34+
35+ /**
36+ * @ngdoc filter
37+ * @name angular.filter.number
38+ * @function
39+ *
40+ * @description
41+ * Formats a number as text.
42+ *
43+ * If the input is not a number empty string is returned.
44+ *
45+ * @param {(number|string) } number Number to format.
46+ * @param {(number|string)= } fractionSize Number of decimal places to round the number to. Default 2.
47+ * @returns {string } Number rounded to decimalPlaces and places a “,” after each third digit.
48+ *
49+ * @example
50+ * <span ng:non-bindable="true">{{1234.56789|number}}</span>: {{1234.56789|number}}<br/>
51+ * <span ng:non-bindable="true">{{1234.56789|number:0}}</span>: {{1234.56789|number:0}}<br/>
52+ * <span ng:non-bindable="true">{{1234.56789|number:2}}</span>: {{1234.56789|number:2}}<br/>
53+ * <span ng:non-bindable="true">{{-1234.56789|number:4}}</span>: {{-1234.56789|number:4}}
54+ *
55+ * @scenario
56+ * it('should format numbers', function(){
57+ * expect(element('span[ng\\:bind="1234.56789|number"]').val()).toBe('1,234.57');
58+ * expect(element('span[ng\\:bind="1234.56789|number:0"]').val()).toBe('1,234');
59+ * expect(element('span[ng\\:bind="1234.56789|number:2"]').val()).toBe('1,234.56');
60+ * expect(element('span[ng\\:bind="-1234.56789|number:4"]').val()).toBe('-1,234.56789');
61+ * });
62+ */
63+ angularFilter . number = function ( number , fractionSize ) {
64+ if ( isNaN ( number ) || ! isFinite ( number ) ) {
865 return '' ;
966 }
1067 fractionSize = typeof fractionSize == $undefined ? 2 : fractionSize ;
11- var isNegative = amount < 0 ;
12- amount = Math . abs ( amount ) ;
68+ var isNegative = number < 0 ;
69+ number = Math . abs ( number ) ;
1370 var pow = Math . pow ( 10 , fractionSize ) ;
14- var text = "" + Math . round ( amount * pow ) ;
71+ var text = "" + Math . round ( number * pow ) ;
1572 var whole = text . substring ( 0 , text . length - fractionSize ) ;
1673 whole = whole || '0' ;
1774 var frc = text . substring ( text . length - fractionSize ) ;
@@ -30,6 +87,8 @@ angularFilter.number = function(amount, fractionSize){
3087 }
3188 return text ;
3289} ;
90+
91+
3392function padNumber ( num , digits , trim ) {
3493 var neg = '' ;
3594 if ( num < 0 ) {
@@ -42,6 +101,8 @@ function padNumber(num, digits, trim) {
42101 num = num . substr ( num . length - digits ) ;
43102 return neg + num ;
44103}
104+
105+
45106function dateGetter ( name , size , offset , trim ) {
46107 return function ( date ) {
47108 var value = date [ 'get' + name ] ( ) ;
@@ -51,6 +112,8 @@ function dateGetter(name, size, offset, trim) {
51112 return padNumber ( value , size , trim ) ;
52113 } ;
53114}
115+
116+
54117var DATE_FORMATS = {
55118 yyyy : dateGetter ( 'FullYear' , 4 ) ,
56119 yy : dateGetter ( 'FullYear' , 2 , 0 , true ) ,
@@ -66,15 +129,32 @@ var DATE_FORMATS = {
66129 m : dateGetter ( 'Minutes' , 1 ) ,
67130 ss : dateGetter ( 'Seconds' , 2 ) ,
68131 s : dateGetter ( 'Seconds' , 1 ) ,
69- a : function ( date ) { return date . getHours ( ) < 12 ? 'am' : 'pm' ; } ,
132+ a : function ( date ) { return date . getHours ( ) < 12 ? 'am' : 'pm' ; } ,
70133 Z : function ( date ) {
71134 var offset = date . getTimezoneOffset ( ) ;
72135 return padNumber ( offset / 60 , 2 ) + padNumber ( Math . abs ( offset % 60 ) , 2 ) ;
73136 }
74137} ;
138+
139+
75140var DATE_FORMATS_SPLIT = / ( [ ^ y M d H h m s a Z ] * ) ( y + | M + | d + | H + | h + | m + | s + | a | Z ) ( .* ) / ;
76141var NUMBER_STRING = / ^ \d + $ / ;
77142
143+
144+ /**
145+ * @ngdoc filter
146+ * @name angular.filter.date
147+ * @function
148+ *
149+ * @description
150+ * Formats `date` to a string based on the requested `format`.
151+ *
152+ * @param {(Date|number|string) } date Date to format either as Date object or milliseconds.
153+ * @param {string= } format Formatting rules. If not specified, Date#toLocaleDateString is used.
154+ * @returns {string } Formatted string or the input if input is not recognized as date/millis.
155+ *
156+ * //TODO example + scenario
157+ */
78158angularFilter . date = function ( date , format ) {
79159 if ( isString ( date ) && NUMBER_STRING . test ( date ) ) {
80160 date = parseInt ( date , 10 ) ;
@@ -102,23 +182,101 @@ angularFilter.date = function(date, format) {
102182 return text ;
103183} ;
104184
185+
186+ /**
187+ * @ngdoc filter
188+ * @name angular.filter.json
189+ * @function
190+ *
191+ * @description
192+ * Allows you to convert a JavaScript object into JSON string.
193+ *
194+ * This filter is mostly useful for debugging. When using the double curly {{value}} notation
195+ * the binding is automatically converted to JSON.
196+ *
197+ * @param {* } object Any JavaScript object (including arrays and primitive types) to filter.
198+ * @returns {string } JSON string.
199+ *
200+ * @css ng-monospace Always applied to the encapsulating element.
201+ *
202+ * @example
203+ * <span ng:non-bindable>{{ {a:1, b:[]} | json }}</span>: <pre>{{ {a:1, b:[]} | json }}</pre>
204+ *
205+ * @scenario
206+ * it('should jsonify filtered objects', function() {
207+ * expect(element('pre[ng\\:bind-template="{{ {a:1, b:[]} | json }}"]').val()).toBe(
208+ * '{\n "a":1,\n "b":[]}'
209+ * );
210+ * }
211+ *
212+ */
105213angularFilter . json = function ( object ) {
106214 this . $element . addClass ( "ng-monospace" ) ;
107215 return toJson ( object , true ) ;
108216} ;
109217
218+
219+ /**
220+ * @ngdoc filter
221+ * @name angular.filter.lowercase
222+ * @function
223+ *
224+ * @see angular.lowercase
225+ */
110226angularFilter . lowercase = lowercase ;
111227
228+
229+ /**
230+ * @ngdoc filter
231+ * @name angular.filter.uppercase
232+ * @function
233+ *
234+ * @see angular.uppercase
235+ */
112236angularFilter . uppercase = uppercase ;
113237
114- /**</>
115- * @exportedAs filter:html
116- * @param {string= } option if 'unsafe' then do not sanitize the HTML input
238+
239+ /**
240+ * @ngdoc filter
241+ * @name angular.filter.html
242+ * @function
243+ *
244+ * @description
245+ * Prevents the input from getting escaped by angular. By default the input is sanitized and
246+ * inserted into the DOM as is.
247+ *
248+ * The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are
249+ * then serialized back to properly escaped html string. This means that no unsafe input can make
250+ * it into the returned string, however since our parser is more strict than a typical browser
251+ * parser, it's possible that some obscure input, which would be recognized as valid HTML by a
252+ * browser, won't make it through the sanitizer.
253+ *
254+ * If you hate your users, you may call the filter with optional 'unsafe' argument, which bypasses
255+ * the html sanitizer, but makes your application vulnerable to XSS and other attacks. Using this
256+ * option is strongly discouraged and should be used only if you absolutely trust the input being
257+ * filtered and you can't get the content through the sanitizer.
258+ *
259+ * @param {string } html Html input.
260+ * @param {string= } option If 'unsafe' then do not sanitize the HTML input.
261+ * @returns {string } Sanitized or raw html.
117262 */
118263angularFilter . html = function ( html , option ) {
119264 return new HTML ( html , option ) ;
120265} ;
121266
267+
268+ /**
269+ * @ngdoc filter
270+ * @name angular.filter.linky
271+ * @function
272+ *
273+ * @description
274+ * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto links.
275+ *
276+ * @param {string } text Input text.
277+ * @returns {string } Html-linkified text.
278+ */
279+ //TODO: externalize all regexps
122280angularFilter . linky = function ( text ) {
123281 if ( ! text ) return text ;
124282 function regExpEscape ( text ) {
0 commit comments