From 1fe7e3a1302e948a31ab80d02ede6975c3bddd58 Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Mon, 1 Nov 2010 13:44:39 -0700 Subject: add jsdocs for angular and filter namespaces + all filters --- src/filters.js | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 167 insertions(+), 9 deletions(-) (limited to 'src/filters.js') diff --git a/src/filters.js b/src/filters.js index 4ab2b32c..ed824f93 100644 --- a/src/filters.js +++ b/src/filters.js @@ -1,17 +1,74 @@ +/** + * @ngdoc filter + * @name angular.filter.currency + * @function + * + * @description + * Formats a number as a currency (ie $1,234.56). + * + * @param {number} amout Input to filter. + * @returns {string} Formated number. + * + * @css ng-format-negative + * When the value is negative, this css class is applied to the binding making it by default red. + * + * @example + *
+ * {{amount | currency}} + * + * @scenario + * it('should init with 1234.56', function(){ + * expect(bind('amount')).toEqual('$1,234.56'); + * }); + * it('should update', function(){ + * element(':input[name=amount]').value('-1234'); + * expect(bind('amount')).toEqual('-$1,234.00'); + * expect(bind('amount')).toHaveColor('red'); + * }); + */ angularFilter.currency = function(amount){ this.$element.toggleClass('ng-format-negative', amount < 0); return '$' + angularFilter['number'].apply(this, [amount, 2]); }; -angularFilter.number = function(amount, fractionSize){ - if (isNaN(amount) || !isFinite(amount)) { + +/** + * @ngdoc filter + * @name angular.filter.number + * @function + * + * @description + * Formats a number as text. + * + * If the input is not a number empty string is returned. + * + * @param {(number|string)} number Number to format. + * @param {(number|string)=} fractionSize Number of decimal places to round the number to. Default 2. + * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit. + * + * @example + * {{1234.56789|number}}: {{1234.56789|number}}
+ * {{1234.56789|number:0}}: {{1234.56789|number:0}}
+ * {{1234.56789|number:2}}: {{1234.56789|number:2}}
+ * {{-1234.56789|number:4}}: {{-1234.56789|number:4}} + * + * @scenario + * it('should format numbers', function(){ + * expect(element('span[ng\\:bind="1234.56789|number"]').val()).toBe('1,234.57'); + * expect(element('span[ng\\:bind="1234.56789|number:0"]').val()).toBe('1,234'); + * expect(element('span[ng\\:bind="1234.56789|number:2"]').val()).toBe('1,234.56'); + * expect(element('span[ng\\:bind="-1234.56789|number:4"]').val()).toBe('-1,234.56789'); + * }); + */ +angularFilter.number = function(number, fractionSize){ + if (isNaN(number) || !isFinite(number)) { return ''; } fractionSize = typeof fractionSize == $undefined ? 2 : fractionSize; - var isNegative = amount < 0; - amount = Math.abs(amount); + var isNegative = number < 0; + number = Math.abs(number); var pow = Math.pow(10, fractionSize); - var text = "" + Math.round(amount * pow); + var text = "" + Math.round(number * pow); var whole = text.substring(0, text.length - fractionSize); whole = whole || '0'; var frc = text.substring(text.length - fractionSize); @@ -30,6 +87,8 @@ angularFilter.number = function(amount, fractionSize){ } return text; }; + + function padNumber(num, digits, trim) { var neg = ''; if (num < 0) { @@ -42,6 +101,8 @@ function padNumber(num, digits, trim) { num = num.substr(num.length - digits); return neg + num; } + + function dateGetter(name, size, offset, trim) { return function(date) { var value = date['get' + name](); @@ -51,6 +112,8 @@ function dateGetter(name, size, offset, trim) { return padNumber(value, size, trim); }; } + + var DATE_FORMATS = { yyyy: dateGetter('FullYear', 4), yy: dateGetter('FullYear', 2, 0, true), @@ -66,15 +129,32 @@ var DATE_FORMATS = { m: dateGetter('Minutes', 1), ss: dateGetter('Seconds', 2), s: dateGetter('Seconds', 1), - a: function(date){return date.getHours() < 12 ? 'am' : 'pm'; }, + a: function(date){return date.getHours() < 12 ? 'am' : 'pm';}, Z: function(date){ var offset = date.getTimezoneOffset(); return padNumber(offset / 60, 2) + padNumber(Math.abs(offset % 60), 2); } }; + + var DATE_FORMATS_SPLIT = /([^yMdHhmsaZ]*)(y+|M+|d+|H+|h+|m+|s+|a|Z)(.*)/; var NUMBER_STRING = /^\d+$/; + +/** + * @ngdoc filter + * @name angular.filter.date + * @function + * + * @description + * Formats `date` to a string based on the requested `format`. + * + * @param {(Date|number|string)} date Date to format either as Date object or milliseconds. + * @param {string=} format Formatting rules. If not specified, Date#toLocaleDateString is used. + * @returns {string} Formatted string or the input if input is not recognized as date/millis. + * + * //TODO example + scenario + */ angularFilter.date = function(date, format) { if (isString(date) && NUMBER_STRING.test(date)) { date = parseInt(date, 10); @@ -102,23 +182,101 @@ angularFilter.date = function(date, format) { return text; }; + +/** + * @ngdoc filter + * @name angular.filter.json + * @function + * + * @description + * Allows you to convert a JavaScript object into JSON string. + * + * This filter is mostly useful for debugging. When using the double curly {{value}} notation + * the binding is automatically converted to JSON. + * + * @param {*} object Any JavaScript object (including arrays and primitive types) to filter. + * @returns {string} JSON string. + * + * @css ng-monospace Always applied to the encapsulating element. + * + * @example + * {{ {a:1, b:[]} | json }}:
{{ {a:1, b:[]} | json }}
+ * + * @scenario + * it('should jsonify filtered objects', function() { + * expect(element('pre[ng\\:bind-template="{{ {a:1, b:[]} | json }}"]').val()).toBe( + * '{\n "a":1,\n "b":[]}' + * ); + * } + * + */ angularFilter.json = function(object) { this.$element.addClass("ng-monospace"); return toJson(object, true); }; + +/** + * @ngdoc filter + * @name angular.filter.lowercase + * @function + * + * @see angular.lowercase + */ angularFilter.lowercase = lowercase; + +/** + * @ngdoc filter + * @name angular.filter.uppercase + * @function + * + * @see angular.uppercase + */ angularFilter.uppercase = uppercase; -/** - * @exportedAs filter:html - * @param {string=} option if 'unsafe' then do not sanitize the HTML input + +/** + * @ngdoc filter + * @name angular.filter.html + * @function + * + * @description + * Prevents the input from getting escaped by angular. By default the input is sanitized and + * inserted into the DOM as is. + * + * The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are + * then serialized back to properly escaped html string. This means that no unsafe input can make + * it into the returned string, however since our parser is more strict than a typical browser + * parser, it's possible that some obscure input, which would be recognized as valid HTML by a + * browser, won't make it through the sanitizer. + * + * If you hate your users, you may call the filter with optional 'unsafe' argument, which bypasses + * the html sanitizer, but makes your application vulnerable to XSS and other attacks. Using this + * option is strongly discouraged and should be used only if you absolutely trust the input being + * filtered and you can't get the content through the sanitizer. + * + * @param {string} html Html input. + * @param {string=} option If 'unsafe' then do not sanitize the HTML input. + * @returns {string} Sanitized or raw html. */ angularFilter.html = function(html, option){ return new HTML(html, option); }; + +/** + * @ngdoc filter + * @name angular.filter.linky + * @function + * + * @description + * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto links. + * + * @param {string} text Input text. + * @returns {string} Html-linkified text. + */ +//TODO: externalize all regexps angularFilter.linky = function(text){ if (!text) return text; function regExpEscape(text) { -- cgit v1.2.3