diff options
| author | Misko Hevery | 2011-11-03 14:36:22 -0700 | 
|---|---|---|
| committer | Misko Hevery | 2011-11-14 16:39:34 -0800 | 
| commit | 6022f3df399a5d98830dfe7904f0ad2baaa308c7 (patch) | |
| tree | 9951448c3023fd1dd00e73f30b8eeb0c5eb9e7d6 /src/filters.js | |
| parent | 7c11531902986405e9443c30dd0c654f86c31ca3 (diff) | |
| download | angular.js-6022f3df399a5d98830dfe7904f0ad2baaa308c7.tar.bz2 | |
move(filters): appease the History God
Diffstat (limited to 'src/filters.js')
| -rw-r--r-- | src/filters.js | 647 | 
1 files changed, 0 insertions, 647 deletions
| diff --git a/src/filters.js b/src/filters.js deleted file mode 100644 index b9c3d2ef..00000000 --- a/src/filters.js +++ /dev/null @@ -1,647 +0,0 @@ -'use strict'; - -/** - * @ngdoc overview - * @name angular.filter - * @description - * - * Filters are used for formatting data displayed to the user. - * - * The general syntax in templates is as follows: - * - *         {{ expression | [ filter_name ] }} - * - * Following is the list of built-in angular filters: - * - * * {@link angular.filter.currency currency} - * * {@link angular.filter.date date} - * * {@link angular.filter.html html} - * * {@link angular.filter.json json} - * * {@link angular.filter.linky linky} - * * {@link angular.filter.lowercase lowercase} - * * {@link angular.filter.number number} - * * {@link angular.filter.uppercase uppercase} - * - * For more information about how angular filters work, and how to create your own filters, see - * {@link guide/dev_guide.templates.filters Understanding Angular Filters} in the angular Developer - * Guide. - */ - -/** - * @ngdoc filter - * @name angular.filter.currency - * @function - * - * @description - * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default - * symbol for current locale is used. - * - * @param {number} amount Input to filter. - * @param {string=} symbol Currency symbol or identifier to be displayed. - * @returns {string} Formatted number. - * - * @css ng-format-negative - *   When the value is negative, this css class is applied to the binding making it (by default) red. - * - * @example -   <doc:example> -     <doc:source> -       <script> -         function Ctrl() { -           this.amount = 1234.56; -         } -       </script> -       <div ng:controller="Ctrl"> -         <input type="number" ng:model="amount"/> <br/> -         default currency symbol ($): {{amount | currency}}<br/> -         custom currency identifier (USD$): {{amount | currency:"USD$"}} -       </div> -     </doc:source> -     <doc:scenario> -       it('should init with 1234.56', function() { -         expect(binding('amount | currency')).toBe('$1,234.56'); -         expect(binding('amount | currency:"USD$"')).toBe('USD$1,234.56'); -       }); -       it('should update', function() { -         input('amount').enter('-1234'); -         expect(binding('amount | currency')).toBe('($1,234.00)'); -         expect(binding('amount | currency:"USD$"')).toBe('(USD$1,234.00)'); -         expect(element('.doc-example-live .ng-binding').prop('className')). -           toMatch(/ng-format-negative/); -       }); -     </doc:scenario> -   </doc:example> - */ -angularFilter.currency = function(amount, currencySymbol){ -  var formats = this.$service('$locale').NUMBER_FORMATS; -  this.$element.toggleClass('ng-format-negative', amount < 0); -  if (isUndefined(currencySymbol)) currencySymbol = formats.CURRENCY_SYM; -  return formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, 2). -              replace(/\u00A4/g, currencySymbol); -}; - -/** - * @ngdoc filter - * @name angular.filter.number - * @function - * - * @description - * Formats a number as text. - * - * If the input is not a number an empty string is returned. - * - * @param {number|string} number Number to format. - * @param {(number|string)=} [fractionSize=2] Number of decimal places to round the number to. - * @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit. - * - * @example -   <doc:example> -     <doc:source> -       <script> -         function Ctrl() { -           this.val = 1234.56789; -         } -       </script> -       <div ng:controller="Ctrl"> -         Enter number: <input ng:model='val'><br/> -         Default formatting: {{val | number}}<br/> -         No fractions: {{val | number:0}}<br/> -         Negative number: {{-val | number:4}} -       </div> -     </doc:source> -     <doc:scenario> -       it('should format numbers', function() { -         expect(binding('val | number')).toBe('1,234.568'); -         expect(binding('val | number:0')).toBe('1,235'); -         expect(binding('-val | number:4')).toBe('-1,234.5679'); -       }); - -       it('should update', function() { -         input('val').enter('3374.333'); -         expect(binding('val | number')).toBe('3,374.333'); -         expect(binding('val | number:0')).toBe('3,374'); -         expect(binding('-val | number:4')).toBe('-3,374.3330'); -       }); -     </doc:scenario> -   </doc:example> - */ - -var DECIMAL_SEP = '.'; - -angularFilter.number = function(number, fractionSize) { -  var formats = this.$service('$locale').NUMBER_FORMATS; -  return formatNumber(number, formats.PATTERNS[0], formats.GROUP_SEP, -                                                  formats.DECIMAL_SEP, fractionSize); -}; - -function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { -  if (isNaN(number) || !isFinite(number)) return ''; - -  var isNegative = number < 0; -  number = Math.abs(number); -  var numStr = number + '', -      formatedText = '', -      parts = []; - -  if (numStr.indexOf('e') !== -1) { -    formatedText = numStr; -  } else { -    var fractionLen = (numStr.split(DECIMAL_SEP)[1] || '').length; - -    // determine fractionSize if it is not specified -    if (isUndefined(fractionSize)) { -      fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac); -    } - -    var pow = Math.pow(10, fractionSize); -    number = Math.round(number * pow) / pow; -    var fraction = ('' + number).split(DECIMAL_SEP); -    var whole = fraction[0]; -    fraction = fraction[1] || ''; - -    var pos = 0, -        lgroup = pattern.lgSize, -        group = pattern.gSize; - -    if (whole.length >= (lgroup + group)) { -      pos = whole.length - lgroup; -      for (var i = 0; i < pos; i++) { -        if ((pos - i)%group === 0 && i !== 0) { -          formatedText += groupSep; -        } -        formatedText += whole.charAt(i); -      } -    } - -    for (i = pos; i < whole.length; i++) { -      if ((whole.length - i)%lgroup === 0 && i !== 0) { -        formatedText += groupSep; -      } -      formatedText += whole.charAt(i); -    } - -    // format fraction part. -    while(fraction.length < fractionSize) { -      fraction += '0'; -    } - -    if (fractionSize) formatedText += decimalSep + fraction.substr(0, fractionSize); -  } - -  parts.push(isNegative ? pattern.negPre : pattern.posPre); -  parts.push(formatedText); -  parts.push(isNegative ? pattern.negSuf : pattern.posSuf); -  return parts.join(''); -} - -function padNumber(num, digits, trim) { -  var neg = ''; -  if (num < 0) { -    neg =  '-'; -    num = -num; -  } -  num = '' + num; -  while(num.length < digits) num = '0' + num; -  if (trim) -    num = num.substr(num.length - digits); -  return neg + num; -} - - -function dateGetter(name, size, offset, trim) { -  return function(date) { -    var value = date['get' + name](); -    if (offset > 0 || value > -offset) -      value += offset; -    if (value === 0 && offset == -12 ) value = 12; -    return padNumber(value, size, trim); -  }; -} - -function dateStrGetter(name, shortForm) { -  return function(date, formats) { -    var value = date['get' + name](); -    var get = uppercase(shortForm ? ('SHORT' + name) : name); - -    return formats[get][value]; -  }; -} - -function timeZoneGetter(date) { -  var offset = date.getTimezoneOffset(); -  return padNumber(offset / 60, 2) + padNumber(Math.abs(offset % 60), 2); -} - -function ampmGetter(date, formats) { -  return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1]; -} - -var DATE_FORMATS = { -  yyyy: dateGetter('FullYear', 4), -    yy: dateGetter('FullYear', 2, 0, true), -     y: dateGetter('FullYear', 1), -  MMMM: dateStrGetter('Month'), -   MMM: dateStrGetter('Month', true), -    MM: dateGetter('Month', 2, 1), -     M: dateGetter('Month', 1, 1), -    dd: dateGetter('Date', 2), -     d: dateGetter('Date', 1), -    HH: dateGetter('Hours', 2), -     H: dateGetter('Hours', 1), -    hh: dateGetter('Hours', 2, -12), -     h: dateGetter('Hours', 1, -12), -    mm: dateGetter('Minutes', 2), -     m: dateGetter('Minutes', 1), -    ss: dateGetter('Seconds', 2), -     s: dateGetter('Seconds', 1), -  EEEE: dateStrGetter('Day'), -   EEE: dateStrGetter('Day', true), -     a: ampmGetter, -     Z: timeZoneGetter -}; - -var GET_TIME_ZONE = /[A-Z]{3}(?![+\-])/, -    DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/, -    OPERA_TOSTRING_PATTERN = /^[\d].*Z$/, -    NUMBER_STRING = /^\d+$/; - -/** - * @ngdoc filter - * @name angular.filter.date - * @function - * - * @description - *   Formats `date` to a string based on the requested `format`. - * - *   `format` string can be composed of the following elements: - * - *   * `'yyyy'`: 4 digit representation of year (e.g. AD 1 => 0001, AD 2010 => 2010) - *   * `'yy'`: 2 digit representation of year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10) - *   * `'y'`: 1 digit representation of year, e.g. (AD 1 => 1, AD 199 => 199) - *   * `'MMMM'`: Month in year (January-December) - *   * `'MMM'`: Month in year (Jan-Dec) - *   * `'MM'`: Month in year, padded (01-12) - *   * `'M'`: Month in year (1-12) - *   * `'dd'`: Day in month, padded (01-31) - *   * `'d'`: Day in month (1-31) - *   * `'EEEE'`: Day in Week,(Sunday-Saturday) - *   * `'EEE'`: Day in Week, (Sun-Sat) - *   * `'HH'`: Hour in day, padded (00-23) - *   * `'H'`: Hour in day (0-23) - *   * `'hh'`: Hour in am/pm, padded (01-12) - *   * `'h'`: Hour in am/pm, (1-12) - *   * `'mm'`: Minute in hour, padded (00-59) - *   * `'m'`: Minute in hour (0-59) - *   * `'ss'`: Second in minute, padded (00-59) - *   * `'s'`: Second in minute (0-59) - *   * `'a'`: am/pm marker - *   * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-1200) - * - *   `format` string can also be one of the following predefined - *   {@link guide/dev_guide.i18n localizable formats}: - * - *   * `'medium'`: equivalent to `'MMM d, y h:mm:ss a'` for en_US locale - *     (e.g. Sep 3, 2010 12:05:08 pm) - *   * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US  locale (e.g. 9/3/10 12:05 pm) - *   * `'fullDate'`: equivalent to `'EEEE, MMMM d,y'` for en_US  locale - *     (e.g. Friday, September 3, 2010) - *   * `'longDate'`: equivalent to `'MMMM d, y'` for en_US  locale (e.g. September 3, 2010 - *   * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US  locale (e.g. Sep 3, 2010) - *   * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10) - *   * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 pm) - *   * `'shortTime'`: equivalent to `'h:mm a'` for en_US locale (e.g. 12:05 pm) - * - *   `format` string can contain literal values. These need to be quoted with single quotes (e.g. - *   `"h 'in the morning'"`). In order to output single quote, use two single quotes in a sequence - *   (e.g. `"h o''clock"`). - * - * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or - *    number) or ISO 8601 extended datetime string (yyyy-MM-ddTHH:mm:ss.SSSZ). - * @param {string=} format Formatting rules (see Description). If not specified, - *    `mediumDate` is used. - * @returns {string} Formatted string or the input if input is not recognized as date/millis. - * - * @example -   <doc:example> -     <doc:source> -       <span ng:non-bindable>{{1288323623006 | date:'medium'}}</span>: -           {{1288323623006 | date:'medium'}}<br/> -       <span ng:non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>: -          {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}<br/> -       <span ng:non-bindable>{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}</span>: -          {{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}<br/> -     </doc:source> -     <doc:scenario> -       it('should format date', function() { -         expect(binding("1288323623006 | date:'medium'")). -            toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/); -         expect(binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")). -            toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} \-?\d{4}/); -         expect(binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")). -            toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/); -       }); -     </doc:scenario> -   </doc:example> - */ -angularFilter.date = function(date, format) { -  var $locale = this.$service('$locale'), -      text = '', -      parts = [], -      fn, match; - -  format = format || 'mediumDate' -  format = $locale.DATETIME_FORMATS[format] || format; -  if (isString(date)) { -    if (NUMBER_STRING.test(date)) { -      date = parseInt(date, 10); -    } else { -      date = angularString.toDate(date); -    } -  } - -  if (isNumber(date)) { -    date = new Date(date); -  } - -  if (!isDate(date)) { -    return date; -  } - -  while(format) { -    match = DATE_FORMATS_SPLIT.exec(format); -    if (match) { -      parts = concat(parts, match, 1); -      format = parts.pop(); -    } else { -      parts.push(format); -      format = null; -    } -  } - -  forEach(parts, function(value){ -    fn = DATE_FORMATS[value]; -    text += fn ? fn(date, $locale.DATETIME_FORMATS) -               : value.replace(/(^'|'$)/g, '').replace(/''/g, "'"); -  }); - -  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: -   <doc:example> -     <doc:source> -       <pre>{{ {'name':'value'} | json }}</pre> -     </doc:source> -     <doc:scenario> -       it('should jsonify filtered objects', function() { -         expect(binding('| json')).toBe('{\n  "name":"value"}'); -       }); -     </doc:scenario> -   </doc:example> - * - */ -angularFilter.json = function(object) { -  this.$element.addClass("ng-monospace"); -  return toJson(object, true, /^(\$|this$)/); -}; - - -/** - * @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; - - -/** - * @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. - * - * @example -   <doc:example> -     <doc:source> -       <script> -         function Ctrl() { -           this.snippet = -             '<p style="color:blue">an html\n' + -             '<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' + -             'snippet</p>'; -         } -       </script> -       <div ng:controller="Ctrl"> -          Snippet: <textarea ng:model="snippet" cols="60" rows="3"></textarea> -           <table> -             <tr> -               <td>Filter</td> -               <td>Source</td> -               <td>Rendered</td> -             </tr> -             <tr id="html-filter"> -               <td>html filter</td> -               <td> -                 <pre><div ng:bind="snippet | html"><br/></div></pre> -               </td> -               <td> -                 <div ng:bind="snippet | html"></div> -               </td> -             </tr> -             <tr id="escaped-html"> -               <td>no filter</td> -               <td><pre><div ng:bind="snippet"><br/></div></pre></td> -               <td><div ng:bind="snippet"></div></td> -             </tr> -             <tr id="html-unsafe-filter"> -               <td>unsafe html filter</td> -               <td><pre><div ng:bind="snippet | html:'unsafe'"><br/></div></pre></td> -               <td><div ng:bind="snippet | html:'unsafe'"></div></td> -             </tr> -           </table> -         </div> -     </doc:source> -     <doc:scenario> -       it('should sanitize the html snippet ', function() { -         expect(using('#html-filter').binding('snippet | html')). -           toBe('<p>an html\n<em>click here</em>\nsnippet</p>'); -       }); - -       it('should escape snippet without any filter', function() { -         expect(using('#escaped-html').binding('snippet')). -           toBe("<p style=\"color:blue\">an html\n" + -                "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + -                "snippet</p>"); -       }); - -       it('should inline raw snippet if filtered as unsafe', function() { -         expect(using('#html-unsafe-filter').binding("snippet | html:'unsafe'")). -           toBe("<p style=\"color:blue\">an html\n" + -                "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + -                "snippet</p>"); -       }); - -       it('should update', function() { -         input('snippet').enter('new <b>text</b>'); -         expect(using('#html-filter').binding('snippet | html')).toBe('new <b>text</b>'); -         expect(using('#escaped-html').binding('snippet')).toBe("new <b>text</b>"); -         expect(using('#html-unsafe-filter').binding("snippet | html:'unsafe'")).toBe('new <b>text</b>'); -       }); -     </doc:scenario> -   </doc:example> - */ -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 and - *   plain email address links. - * - * @param {string} text Input text. - * @returns {string} Html-linkified text. - * - * @example -   <doc:example> -     <doc:source> -       <script> -         function Ctrl() { -           this.snippet = -             'Pretty text with some links:\n'+ -             'http://angularjs.org/,\n'+ -             'mailto:us@somewhere.org,\n'+ -             'another@somewhere.org,\n'+ -             'and one more: ftp://127.0.0.1/.'; -         } -       </script> -       <div ng:controller="Ctrl"> -       Snippet: <textarea ng:model="snippet" cols="60" rows="3"></textarea> -       <table> -         <tr> -           <td>Filter</td> -           <td>Source</td> -           <td>Rendered</td> -         </tr> -         <tr id="linky-filter"> -           <td>linky filter</td> -           <td> -             <pre><div ng:bind="snippet | linky"><br/></div></pre> -           </td> -           <td> -             <div ng:bind="snippet | linky"></div> -           </td> -         </tr> -         <tr id="escaped-html"> -           <td>no filter</td> -           <td><pre><div ng:bind="snippet"><br/></div></pre></td> -           <td><div ng:bind="snippet"></div></td> -         </tr> -       </table> -     </doc:source> -     <doc:scenario> -       it('should linkify the snippet with urls', function() { -         expect(using('#linky-filter').binding('snippet | linky')). -           toBe('Pretty text with some links:\n' + -                '<a href="http://angularjs.org/">http://angularjs.org/</a>,\n' + -                '<a href="mailto:us@somewhere.org">us@somewhere.org</a>,\n' + -                '<a href="mailto:another@somewhere.org">another@somewhere.org</a>,\n' + -                'and one more: <a href="ftp://127.0.0.1/">ftp://127.0.0.1/</a>.'); -       }); - -       it ('should not linkify snippet without the linky filter', function() { -         expect(using('#escaped-html').binding('snippet')). -           toBe("Pretty text with some links:\n" + -                "http://angularjs.org/,\n" + -                "mailto:us@somewhere.org,\n" + -                "another@somewhere.org,\n" + -                "and one more: ftp://127.0.0.1/."); -       }); - -       it('should update', function() { -         input('snippet').enter('new http://link.'); -         expect(using('#linky-filter').binding('snippet | linky')). -           toBe('new <a href="http://link">http://link</a>.'); -         expect(using('#escaped-html').binding('snippet')).toBe('new http://link.'); -       }); -     </doc:scenario> -   </doc:example> - */ -var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/, -    MAILTO_REGEXP = /^mailto:/; - -angularFilter.linky = function(text) { -  if (!text) return text; -  var match; -  var raw = text; -  var html = []; -  var writer = htmlSanitizeWriter(html); -  var url; -  var i; -  while ((match = raw.match(LINKY_URL_REGEXP))) { -    // We can not end in these as they are sometimes found at the end of the sentence -    url = match[0]; -    // if we did not match ftp/http/mailto then assume mailto -    if (match[2] == match[3]) url = 'mailto:' + url; -    i = match.index; -    writer.chars(raw.substr(0, i)); -    writer.start('a', {href:url}); -    writer.chars(match[0].replace(MAILTO_REGEXP, '')); -    writer.end('a'); -    raw = raw.substring(i + match[0].length); -  } -  writer.chars(raw); -  return new HTML(html.join('')); -}; | 
