Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / src / core / src / lang / String.js
1 /**
2  * @class Ext.String
3  *
4  * A collection of useful static methods to deal with strings
5  * @singleton
6  */
7
8 Ext.String = {
9     trimRegex: /^[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+|[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+$/g,
10     escapeRe: /('|\\)/g,
11     formatRe: /\{(\d+)\}/g,
12     escapeRegexRe: /([-.*+?^${}()|[\]\/\\])/g,
13
14     /**
15      * Convert certain characters (&, <, >, and ') to their HTML character equivalents for literal display in web pages.
16      * @param {String} value The string to encode
17      * @return {String} The encoded text
18      * @method
19      */
20     htmlEncode: (function() {
21         var entities = {
22             '&': '&amp;',
23             '>': '&gt;',
24             '<': '&lt;',
25             '"': '&quot;'
26         }, keys = [], p, regex;
27         
28         for (p in entities) {
29             keys.push(p);
30         }
31         
32         regex = new RegExp('(' + keys.join('|') + ')', 'g');
33         
34         return function(value) {
35             return (!value) ? value : String(value).replace(regex, function(match, capture) {
36                 return entities[capture];    
37             });
38         };
39     })(),
40
41     /**
42      * Convert certain characters (&, <, >, and ') from their HTML character equivalents.
43      * @param {String} value The string to decode
44      * @return {String} The decoded text
45      * @method
46      */
47     htmlDecode: (function() {
48         var entities = {
49             '&amp;': '&',
50             '&gt;': '>',
51             '&lt;': '<',
52             '&quot;': '"'
53         }, keys = [], p, regex;
54         
55         for (p in entities) {
56             keys.push(p);
57         }
58         
59         regex = new RegExp('(' + keys.join('|') + '|&#[0-9]{1,5};' + ')', 'g');
60         
61         return function(value) {
62             return (!value) ? value : String(value).replace(regex, function(match, capture) {
63                 if (capture in entities) {
64                     return entities[capture];
65                 } else {
66                     return String.fromCharCode(parseInt(capture.substr(2), 10));
67                 }
68             });
69         };
70     })(),
71
72     /**
73      * Appends content to the query string of a URL, handling logic for whether to place
74      * a question mark or ampersand.
75      * @param {String} url The URL to append to.
76      * @param {String} string The content to append to the URL.
77      * @return (String) The resulting URL
78      */
79     urlAppend : function(url, string) {
80         if (!Ext.isEmpty(string)) {
81             return url + (url.indexOf('?') === -1 ? '?' : '&') + string;
82         }
83
84         return url;
85     },
86
87     /**
88      * Trims whitespace from either end of a string, leaving spaces within the string intact.  Example:
89      * @example
90 var s = '  foo bar  ';
91 alert('-' + s + '-');         //alerts "- foo bar -"
92 alert('-' + Ext.String.trim(s) + '-');  //alerts "-foo bar-"
93
94      * @param {String} string The string to escape
95      * @return {String} The trimmed string
96      */
97     trim: function(string) {
98         return string.replace(Ext.String.trimRegex, "");
99     },
100
101     /**
102      * Capitalize the given string
103      * @param {String} string
104      * @return {String}
105      */
106     capitalize: function(string) {
107         return string.charAt(0).toUpperCase() + string.substr(1);
108     },
109
110     /**
111      * Truncate a string and add an ellipsis ('...') to the end if it exceeds the specified length
112      * @param {String} value The string to truncate
113      * @param {Number} length The maximum length to allow before truncating
114      * @param {Boolean} word True to try to find a common word break
115      * @return {String} The converted text
116      */
117     ellipsis: function(value, len, word) {
118         if (value && value.length > len) {
119             if (word) {
120                 var vs = value.substr(0, len - 2),
121                 index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
122                 if (index !== -1 && index >= (len - 15)) {
123                     return vs.substr(0, index) + "...";
124                 }
125             }
126             return value.substr(0, len - 3) + "...";
127         }
128         return value;
129     },
130
131     /**
132      * Escapes the passed string for use in a regular expression
133      * @param {String} string
134      * @return {String}
135      */
136     escapeRegex: function(string) {
137         return string.replace(Ext.String.escapeRegexRe, "\\$1");
138     },
139
140     /**
141      * Escapes the passed string for ' and \
142      * @param {String} string The string to escape
143      * @return {String} The escaped string
144      */
145     escape: function(string) {
146         return string.replace(Ext.String.escapeRe, "\\$1");
147     },
148
149     /**
150      * Utility function that allows you to easily switch a string between two alternating values.  The passed value
151      * is compared to the current string, and if they are equal, the other value that was passed in is returned.  If
152      * they are already different, the first value passed in is returned.  Note that this method returns the new value
153      * but does not change the current string.
154      * <pre><code>
155     // alternate sort directions
156     sort = Ext.String.toggle(sort, 'ASC', 'DESC');
157
158     // instead of conditional logic:
159     sort = (sort == 'ASC' ? 'DESC' : 'ASC');
160        </code></pre>
161      * @param {String} string The current string
162      * @param {String} value The value to compare to the current string
163      * @param {String} other The new value to use if the string already equals the first value passed in
164      * @return {String} The new value
165      */
166     toggle: function(string, value, other) {
167         return string === value ? other : value;
168     },
169
170     /**
171      * Pads the left side of a string with a specified character.  This is especially useful
172      * for normalizing number and date strings.  Example usage:
173      *
174      * <pre><code>
175 var s = Ext.String.leftPad('123', 5, '0');
176 // s now contains the string: '00123'
177        </code></pre>
178      * @param {String} string The original string
179      * @param {Number} size The total length of the output string
180      * @param {String} character (optional) The character with which to pad the original string (defaults to empty string " ")
181      * @return {String} The padded string
182      */
183     leftPad: function(string, size, character) {
184         var result = String(string);
185         character = character || " ";
186         while (result.length < size) {
187             result = character + result;
188         }
189         return result;
190     },
191
192     /**
193      * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens.  Each
194      * token must be unique, and must increment in the format {0}, {1}, etc.  Example usage:
195      * <pre><code>
196 var cls = 'my-class', text = 'Some text';
197 var s = Ext.String.format('&lt;div class="{0}">{1}&lt;/div>', cls, text);
198 // s now contains the string: '&lt;div class="my-class">Some text&lt;/div>'
199        </code></pre>
200      * @param {String} string The tokenized string to be formatted
201      * @param {String} value1 The value to replace token {0}
202      * @param {String} value2 Etc...
203      * @return {String} The formatted string
204      */
205     format: function(format) {
206         var args = Ext.Array.toArray(arguments, 1);
207         return format.replace(Ext.String.formatRe, function(m, i) {
208             return args[i];
209         });
210     }
211 };