1 if(!dojo._hasResource["dojox.dtl.filter.strings"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dojox.dtl.filter.strings"] = true;
3 dojo.provide("dojox.dtl.filter.strings");
5 dojo.require("dojox.dtl.filter.htmlstrings");
6 dojo.require("dojox.string.sprintf");
7 dojo.require("dojox.string.tokenize");
9 dojo.mixin(dojox.dtl.filter.strings, {
10 _urlquote: function(/*String*/ url, /*String?*/ safe){
14 return dojox.string.tokenize(url, /([^\w-_.])/g, function(token){
15 if(safe.indexOf(token) == -1){
19 return "%" + token.charCodeAt(0).toString(16).toUpperCase();
25 addslashes: function(value){
26 // summary: Adds slashes - useful for passing strings to JavaScript, for example.
27 return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/'/g, "\\'");
29 capfirst: function(value){
30 // summary: Capitalizes the first character of the value
32 return value.charAt(0).toUpperCase() + value.substring(1);
34 center: function(value, arg){
35 // summary: Centers the value in a field of a given width
36 arg = arg || value.length;
38 var diff = arg - value.length;
43 for(var i = 0; i < diff; i += 2){
44 value = " " + value + " ";
48 cut: function(value, arg){
49 // summary: Removes all values of arg from the given string
52 return value.replace(new RegExp(arg, "g"), "");
54 _fix_ampersands: /&(?!(\w+|#\d+);)/g,
55 fix_ampersands: function(value){
56 // summary: Replaces ampersands with ``&`` entities
57 return value.replace(dojox.dtl.filter.strings._fix_ampersands, "&");
59 floatformat: function(value, arg){
60 // summary: Format a number according to arg
62 // If called without an argument, displays a floating point
63 // number as 34.2 -- but only if there's a point to be displayed.
64 // With a positive numeric argument, it displays that many decimal places
66 // With a negative numeric argument, it will display that many decimal
67 // places -- but only if there's places to be displayed.
68 arg = parseInt(arg || -1);
69 value = parseFloat(value);
70 var m = value - value.toFixed(0);
72 return value.toFixed();
74 value = value.toFixed(Math.abs(arg));
75 return (arg < 0) ? parseFloat(value) + "" : value;
77 iriencode: function(value){
78 return dojox.dtl.filter.strings._urlquote(value, "/#%[]=:;$&()+,!");
80 linenumbers: function(value){
81 // summary: Displays text with line numbers
82 var df = dojox.dtl.filter;
83 var lines = value.split("\n");
85 var width = (lines.length + "").length;
86 for(var i = 0, line; i < lines.length; i++){
88 output.push(df.strings.ljust(i + 1, width) + ". " + df.htmlstrings.escape(line));
90 return output.join("\n");
92 ljust: function(value, arg){
95 while(value.length < arg){
100 lower: function(value){
101 // summary: Converts a string into all lowercase
102 return (value + "").toLowerCase();
104 make_list: function(value){
106 // Returns the value turned into a list. For an integer, it's a list of
107 // digits. For a string, it's a list of characters.
109 if(typeof value == "number"){
113 for(var i = 0; i < value.length; i++){
114 output.push(value.charAt(i));
118 if(typeof value == "object"){
119 for(var key in value){
120 output.push(value[key]);
126 rjust: function(value, arg){
129 while(value.length < arg){
134 slugify: function(value){
135 // summary: Converts to lowercase, removes
136 // non-alpha chars and converts spaces to hyphens
137 value = value.replace(/[^\w\s-]/g, "").toLowerCase();
138 return value.replace(/[\-\s]+/g, "-");
141 stringformat: function(value, arg){
143 // Formats the variable according to the argument, a string formatting specifier.
144 // This specifier uses Python string formating syntax, with the exception that
145 // the leading "%" is dropped.
147 var strings = dojox.dtl.filter.strings._strings;
149 strings[arg] = new dojox.string.sprintf.Formatter("%" + arg);
151 return strings[arg].format(value);
153 title: function(value){
154 // summary: Converts a string into titlecase
155 var last, title = "";
156 for(var i = 0, current; i < value.length; i++){
157 current = value.charAt(i);
158 if(last == " " || last == "\n" || last == "\t" || !last){
159 title += current.toUpperCase();
161 title += current.toLowerCase();
167 _truncatewords: /[ \n\r\t]/,
168 truncatewords: function(value, arg){
169 // summary: Truncates a string after a certain number of words
171 // Number of words to truncate after
177 for(var i = 0, j = value.length, count = 0, current, last; i < value.length; i++){
178 current = value.charAt(i);
179 if(dojox.dtl.filter.strings._truncatewords.test(last)){
180 if(!dojox.dtl.filter.strings._truncatewords.test(current)){
183 return value.substring(0, j + 1);
186 }else if(!dojox.dtl.filter.strings._truncatewords.test(current)){
193 _truncate_words: /(&.*?;|<.*?>|(\w[\w\-]*))/g,
194 _truncate_tag: /<(\/)?([^ ]+?)(?: (\/)| .*?)?>/,
195 _truncate_singlets: { br: true, col: true, link: true, base: true, img: true, param: true, area: true, hr: true, input: true },
196 truncatewords_html: function(value, arg){
203 var strings = dojox.dtl.filter.strings;
207 var output = dojox.string.tokenize(value, strings._truncate_words, function(all, word){
209 // It's an actual non-HTML word
213 }else if(words == arg){
214 return word + " ...";
218 var tag = all.match(strings._truncate_tag);
219 if(!tag || words >= arg){
220 // Don't worry about non tags or tags after our truncate point
223 var closing = tag[1];
224 var tagname = tag[2].toLowerCase();
225 var selfclosing = tag[3];
226 if(closing || strings._truncate_singlets[tagname]){
228 var i = dojo.indexOf(open, tagname);
230 open = open.slice(i + 1);
233 open.unshift(tagname);
238 output = output.replace(/\s+$/g, "");
240 for(var i = 0, tag; tag = open[i]; i++){
241 output += "</" + tag + ">";
246 upper: function(value){
247 return value.toUpperCase();
249 urlencode: function(value){
250 return dojox.dtl.filter.strings._urlquote(value);
252 _urlize: /^((?:[(>]|<)*)(.*?)((?:[.,)>\n]|>)*)$/,
253 _urlize2: /^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$/,
254 urlize: function(value){
255 return dojox.dtl.filter.strings.urlizetrunc(value);
257 urlizetrunc: function(value, arg){
259 return dojox.string.tokenize(value, /(\S+)/g, function(word){
260 var matches = dojox.dtl.filter.strings._urlize.exec(word);
264 var lead = matches[1];
265 var middle = matches[2];
266 var trail = matches[3];
268 var startsWww = middle.indexOf("www.") == 0;
269 var hasAt = middle.indexOf("@") != -1;
270 var hasColon = middle.indexOf(":") != -1;
271 var startsHttp = middle.indexOf("http://") == 0;
272 var startsHttps = middle.indexOf("https://") == 0;
273 var firstAlpha = /[a-zA-Z0-9]/.test(middle.charAt(0));
274 var last4 = middle.substring(middle.length - 4);
276 var trimmed = middle;
278 trimmed = trimmed.substring(0, arg - 3) + "...";
281 if(startsWww || (!hasAt && !startsHttp && middle.length && firstAlpha && (last4 == ".org" || last4 == ".net" || last4 == ".com"))){
282 return '<a href="http://' + middle + '" rel="nofollow">' + trimmed + '</a>';
283 }else if(startsHttp || startsHttps){
284 return '<a href="' + middle + '" rel="nofollow">' + trimmed + '</a>';
285 }else if(hasAt && !startsWww && !hasColon && dojox.dtl.filter.strings._urlize2.test(middle)){
286 return '<a href="mailto:' + middle + '">' + middle + '</a>';
291 wordcount: function(value){
292 return dojox.dtl.text.pySplit(value).length;
294 wordwrap: function(value, arg){
296 // summary: Wraps words at specified line length
298 var parts = value.split(/ /g);
300 var word = parts.shift();
302 var pos = word.length - word.lastIndexOf("\n") - 1;
303 for(var i = 0; i < parts.length; i++){
305 if(word.indexOf("\n") != -1){
306 var lines = word.split(/\n/g);
310 pos += lines[0].length + 1;
311 if(arg && pos > arg){
313 pos = lines[lines.length - 1].length;
316 if(lines.length > 1){
317 pos = lines[lines.length - 1].length;
323 return output.join("");