sugar-rails 1.3.7 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/README.md +3 -50
- data/{vendor → app}/assets/javascripts/sugar-development.js +1914 -1225
- data/app/assets/javascripts/sugar-full.js +200 -0
- data/app/assets/javascripts/sugar.js +132 -0
- data/copy_release.sh +4 -7
- data/lib/sugar/rails/version.rb +2 -2
- metadata +16 -58
- data/.rvmrc +0 -1
- data/lib/generators/sugar/build/build_generator.rb +0 -107
- data/lib/generators/sugar/install/install_generator.rb +0 -35
- data/vendor/assets/javascripts/precompiled/development/array.js +0 -1203
- data/vendor/assets/javascripts/precompiled/development/core.js +0 -365
- data/vendor/assets/javascripts/precompiled/development/date.js +0 -2267
- data/vendor/assets/javascripts/precompiled/development/date_locales.js +0 -1179
- data/vendor/assets/javascripts/precompiled/development/date_ranges.js +0 -208
- data/vendor/assets/javascripts/precompiled/development/es5.js +0 -474
- data/vendor/assets/javascripts/precompiled/development/function.js +0 -224
- data/vendor/assets/javascripts/precompiled/development/inflections.js +0 -410
- data/vendor/assets/javascripts/precompiled/development/language.js +0 -383
- data/vendor/assets/javascripts/precompiled/development/number.js +0 -428
- data/vendor/assets/javascripts/precompiled/development/object.js +0 -419
- data/vendor/assets/javascripts/precompiled/development/regexp.js +0 -92
- data/vendor/assets/javascripts/precompiled/development/string.js +0 -894
- data/vendor/assets/javascripts/precompiled/minified/array.js +0 -18
- data/vendor/assets/javascripts/precompiled/minified/core.js +0 -9
- data/vendor/assets/javascripts/precompiled/minified/date.js +0 -44
- data/vendor/assets/javascripts/precompiled/minified/date_locales.js +0 -49
- data/vendor/assets/javascripts/precompiled/minified/date_ranges.js +0 -4
- data/vendor/assets/javascripts/precompiled/minified/es5.js +0 -8
- data/vendor/assets/javascripts/precompiled/minified/function.js +0 -4
- data/vendor/assets/javascripts/precompiled/minified/inflections.js +0 -11
- data/vendor/assets/javascripts/precompiled/minified/language.js +0 -19
- data/vendor/assets/javascripts/precompiled/minified/number.js +0 -5
- data/vendor/assets/javascripts/precompiled/minified/object.js +0 -6
- data/vendor/assets/javascripts/precompiled/minified/regexp.js +0 -2
- data/vendor/assets/javascripts/precompiled/minified/string.js +0 -12
- data/vendor/assets/javascripts/precompiled/readme.txt +0 -3
- data/vendor/assets/javascripts/sugar-full.js +0 -199
- data/vendor/assets/javascripts/sugar.js +0 -120
@@ -1,894 +0,0 @@
|
|
1
|
-
|
2
|
-
/***
|
3
|
-
* @package String
|
4
|
-
* @dependency core
|
5
|
-
* @description String manupulation, escaping, encoding, truncation, and:conversion.
|
6
|
-
*
|
7
|
-
***/
|
8
|
-
|
9
|
-
function getAcronym(word) {
|
10
|
-
var inflector = string.Inflector;
|
11
|
-
var word = inflector && inflector.acronyms[word];
|
12
|
-
if(isString(word)) {
|
13
|
-
return word;
|
14
|
-
}
|
15
|
-
}
|
16
|
-
|
17
|
-
function padString(str, p, left, right) {
|
18
|
-
var padding = string(p);
|
19
|
-
if(padding != p) {
|
20
|
-
padding = '';
|
21
|
-
}
|
22
|
-
if(!isNumber(left)) left = 1;
|
23
|
-
if(!isNumber(right)) right = 1;
|
24
|
-
return padding.repeat(left) + str + padding.repeat(right);
|
25
|
-
}
|
26
|
-
|
27
|
-
function chr(num) {
|
28
|
-
return string.fromCharCode(num);
|
29
|
-
}
|
30
|
-
|
31
|
-
var btoa, atob;
|
32
|
-
|
33
|
-
function buildBase64(key) {
|
34
|
-
if(this.btoa) {
|
35
|
-
btoa = this.btoa;
|
36
|
-
atob = this.atob;
|
37
|
-
return;
|
38
|
-
}
|
39
|
-
var base64reg = /[^A-Za-z0-9\+\/\=]/g;
|
40
|
-
btoa = function(str) {
|
41
|
-
var output = '';
|
42
|
-
var chr1, chr2, chr3;
|
43
|
-
var enc1, enc2, enc3, enc4;
|
44
|
-
var i = 0;
|
45
|
-
do {
|
46
|
-
chr1 = str.charCodeAt(i++);
|
47
|
-
chr2 = str.charCodeAt(i++);
|
48
|
-
chr3 = str.charCodeAt(i++);
|
49
|
-
enc1 = chr1 >> 2;
|
50
|
-
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
51
|
-
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
52
|
-
enc4 = chr3 & 63;
|
53
|
-
if (isNaN(chr2)) {
|
54
|
-
enc3 = enc4 = 64;
|
55
|
-
} else if (isNaN(chr3)) {
|
56
|
-
enc4 = 64;
|
57
|
-
}
|
58
|
-
output = output + key.charAt(enc1) + key.charAt(enc2) + key.charAt(enc3) + key.charAt(enc4);
|
59
|
-
chr1 = chr2 = chr3 = '';
|
60
|
-
enc1 = enc2 = enc3 = enc4 = '';
|
61
|
-
} while (i < str.length);
|
62
|
-
return output;
|
63
|
-
}
|
64
|
-
atob = function(input) {
|
65
|
-
var output = '';
|
66
|
-
var chr1, chr2, chr3;
|
67
|
-
var enc1, enc2, enc3, enc4;
|
68
|
-
var i = 0;
|
69
|
-
if(input.match(base64reg)) {
|
70
|
-
throw new Error('String contains invalid base64 characters');
|
71
|
-
}
|
72
|
-
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
|
73
|
-
do {
|
74
|
-
enc1 = key.indexOf(input.charAt(i++));
|
75
|
-
enc2 = key.indexOf(input.charAt(i++));
|
76
|
-
enc3 = key.indexOf(input.charAt(i++));
|
77
|
-
enc4 = key.indexOf(input.charAt(i++));
|
78
|
-
chr1 = (enc1 << 2) | (enc2 >> 4);
|
79
|
-
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
80
|
-
chr3 = ((enc3 & 3) << 6) | enc4;
|
81
|
-
output = output + chr(chr1);
|
82
|
-
if (enc3 != 64) {
|
83
|
-
output = output + chr(chr2);
|
84
|
-
}
|
85
|
-
if (enc4 != 64) {
|
86
|
-
output = output + chr(chr3);
|
87
|
-
}
|
88
|
-
chr1 = chr2 = chr3 = '';
|
89
|
-
enc1 = enc2 = enc3 = enc4 = '';
|
90
|
-
} while (i < input.length);
|
91
|
-
return output;
|
92
|
-
}
|
93
|
-
}
|
94
|
-
|
95
|
-
|
96
|
-
extend(string, true, function(reg) { return isRegExp(reg) || arguments.length > 2; }, {
|
97
|
-
|
98
|
-
/***
|
99
|
-
* @method startsWith(<find>, [pos] = 0, [case] = true)
|
100
|
-
* @returns Boolean
|
101
|
-
* @short Returns true if the string starts with <find>.
|
102
|
-
* @extra <find> may be either a string or regex. Search begins at [pos], which defaults to the entire string. Case sensitive if [case] is true.
|
103
|
-
* @example
|
104
|
-
*
|
105
|
-
* 'hello'.startsWith('hell') -> true
|
106
|
-
* 'hello'.startsWith(/[a-h]/) -> true
|
107
|
-
* 'hello'.startsWith('HELL') -> false
|
108
|
-
* 'hello'.startsWith('ell', 1) -> true
|
109
|
-
* 'hello'.startsWith('HELL', 0, false) -> true
|
110
|
-
*
|
111
|
-
***/
|
112
|
-
'startsWith': function(reg, pos, c) {
|
113
|
-
var str = this, source;
|
114
|
-
if(pos) str = str.slice(pos);
|
115
|
-
if(isUndefined(c)) c = true;
|
116
|
-
source = isRegExp(reg) ? reg.source.replace('^', '') : escapeRegExp(reg);
|
117
|
-
return regexp('^' + source, c ? '' : 'i').test(str);
|
118
|
-
},
|
119
|
-
|
120
|
-
/***
|
121
|
-
* @method endsWith(<find>, [pos] = length, [case] = true)
|
122
|
-
* @returns Boolean
|
123
|
-
* @short Returns true if the string ends with <find>.
|
124
|
-
* @extra <find> may be either a string or regex. Search ends at [pos], which defaults to the entire string. Case sensitive if [case] is true.
|
125
|
-
* @example
|
126
|
-
*
|
127
|
-
* 'jumpy'.endsWith('py') -> true
|
128
|
-
* 'jumpy'.endsWith(/[q-z]/) -> true
|
129
|
-
* 'jumpy'.endsWith('MPY') -> false
|
130
|
-
* 'jumpy'.endsWith('mp', 4) -> false
|
131
|
-
* 'jumpy'.endsWith('MPY', 5, false) -> true
|
132
|
-
*
|
133
|
-
***/
|
134
|
-
'endsWith': function(reg, pos, c) {
|
135
|
-
var str = this, source;
|
136
|
-
if(isDefined(pos)) str = str.slice(0, pos);
|
137
|
-
if(isUndefined(c)) c = true;
|
138
|
-
source = isRegExp(reg) ? reg.source.replace('$', '') : escapeRegExp(reg);
|
139
|
-
return regexp(source + '$', c ? '' : 'i').test(str);
|
140
|
-
}
|
141
|
-
|
142
|
-
});
|
143
|
-
|
144
|
-
|
145
|
-
extend(string, true, false, {
|
146
|
-
|
147
|
-
/***
|
148
|
-
* @method escapeRegExp()
|
149
|
-
* @returns String
|
150
|
-
* @short Escapes all RegExp tokens in the string.
|
151
|
-
* @example
|
152
|
-
*
|
153
|
-
* 'really?'.escapeRegExp() -> 'really\?'
|
154
|
-
* 'yes.'.escapeRegExp() -> 'yes\.'
|
155
|
-
* '(not really)'.escapeRegExp() -> '\(not really\)'
|
156
|
-
*
|
157
|
-
***/
|
158
|
-
'escapeRegExp': function() {
|
159
|
-
return escapeRegExp(this);
|
160
|
-
},
|
161
|
-
|
162
|
-
/***
|
163
|
-
* @method escapeURL([param] = false)
|
164
|
-
* @returns String
|
165
|
-
* @short Escapes characters in a string to make a valid URL.
|
166
|
-
* @extra If [param] is true, it will also escape valid URL characters for use as a URL parameter.
|
167
|
-
* @example
|
168
|
-
*
|
169
|
-
* 'http://foo.com/"bar"'.escapeURL() -> 'http://foo.com/%22bar%22'
|
170
|
-
* 'http://foo.com/"bar"'.escapeURL(true) -> 'http%3A%2F%2Ffoo.com%2F%22bar%22'
|
171
|
-
*
|
172
|
-
***/
|
173
|
-
'escapeURL': function(param) {
|
174
|
-
return param ? encodeURIComponent(this) : encodeURI(this);
|
175
|
-
},
|
176
|
-
|
177
|
-
/***
|
178
|
-
* @method unescapeURL([partial] = false)
|
179
|
-
* @returns String
|
180
|
-
* @short Restores escaped characters in a URL escaped string.
|
181
|
-
* @extra If [partial] is true, it will only unescape non-valid URL characters. [partial] is included here for completeness, but should very rarely be needed.
|
182
|
-
* @example
|
183
|
-
*
|
184
|
-
* 'http%3A%2F%2Ffoo.com%2Fthe%20bar'.unescapeURL() -> 'http://foo.com/the bar'
|
185
|
-
* 'http%3A%2F%2Ffoo.com%2Fthe%20bar'.unescapeURL(true) -> 'http%3A%2F%2Ffoo.com%2Fthe bar'
|
186
|
-
*
|
187
|
-
***/
|
188
|
-
'unescapeURL': function(param) {
|
189
|
-
return param ? decodeURI(this) : decodeURIComponent(this);
|
190
|
-
},
|
191
|
-
|
192
|
-
/***
|
193
|
-
* @method escapeHTML()
|
194
|
-
* @returns String
|
195
|
-
* @short Converts HTML characters to their entity equivalents.
|
196
|
-
* @example
|
197
|
-
*
|
198
|
-
* '<p>some text</p>'.escapeHTML() -> '<p>some text</p>'
|
199
|
-
* 'one & two'.escapeHTML() -> 'one & two'
|
200
|
-
*
|
201
|
-
***/
|
202
|
-
'escapeHTML': function() {
|
203
|
-
return this.replace(/&/g, '&' )
|
204
|
-
.replace(/</g, '<' )
|
205
|
-
.replace(/>/g, '>' )
|
206
|
-
.replace(/"/g, '"')
|
207
|
-
.replace(/'/g, ''')
|
208
|
-
.replace(/\//g, '/');
|
209
|
-
},
|
210
|
-
|
211
|
-
/***
|
212
|
-
* @method unescapeHTML([partial] = false)
|
213
|
-
* @returns String
|
214
|
-
* @short Restores escaped HTML characters.
|
215
|
-
* @example
|
216
|
-
*
|
217
|
-
* '<p>some text</p>'.unescapeHTML() -> '<p>some text</p>'
|
218
|
-
* 'one & two'.unescapeHTML() -> 'one & two'
|
219
|
-
*
|
220
|
-
***/
|
221
|
-
'unescapeHTML': function() {
|
222
|
-
return this.replace(/&/g, '&')
|
223
|
-
.replace(/</g, '<')
|
224
|
-
.replace(/>/g, '>')
|
225
|
-
.replace(/"/g, '"')
|
226
|
-
.replace(/'/g, "'")
|
227
|
-
.replace(///g, '/');
|
228
|
-
},
|
229
|
-
|
230
|
-
/***
|
231
|
-
* @method encodeBase64()
|
232
|
-
* @returns String
|
233
|
-
* @short Encodes the string into base64 encoding.
|
234
|
-
* @extra This method wraps the browser native %btoa% when available, and uses a custom implementation when not available.
|
235
|
-
* @example
|
236
|
-
*
|
237
|
-
* 'gonna get encoded!'.encodeBase64() -> 'Z29ubmEgZ2V0IGVuY29kZWQh'
|
238
|
-
* 'http://twitter.com/'.encodeBase64() -> 'aHR0cDovL3R3aXR0ZXIuY29tLw=='
|
239
|
-
*
|
240
|
-
***/
|
241
|
-
'encodeBase64': function() {
|
242
|
-
return btoa(this);
|
243
|
-
},
|
244
|
-
|
245
|
-
/***
|
246
|
-
* @method decodeBase64()
|
247
|
-
* @returns String
|
248
|
-
* @short Decodes the string from base64 encoding.
|
249
|
-
* @extra This method wraps the browser native %atob% when available, and uses a custom implementation when not available.
|
250
|
-
* @example
|
251
|
-
*
|
252
|
-
* 'aHR0cDovL3R3aXR0ZXIuY29tLw=='.decodeBase64() -> 'http://twitter.com/'
|
253
|
-
* 'anVzdCBnb3QgZGVjb2RlZA=='.decodeBase64() -> 'just got decoded!'
|
254
|
-
*
|
255
|
-
***/
|
256
|
-
'decodeBase64': function() {
|
257
|
-
return atob(this);
|
258
|
-
},
|
259
|
-
|
260
|
-
/***
|
261
|
-
* @method each([search] = single character, [fn])
|
262
|
-
* @returns Array
|
263
|
-
* @short Runs callback [fn] against each occurence of [search].
|
264
|
-
* @extra Returns an array of matches. [search] may be either a string or regex, and defaults to every character in the string.
|
265
|
-
* @example
|
266
|
-
*
|
267
|
-
* 'jumpy'.each() -> ['j','u','m','p','y']
|
268
|
-
* 'jumpy'.each(/[r-z]/) -> ['u','y']
|
269
|
-
* 'jumpy'.each(/[r-z]/, function(m) {
|
270
|
-
* // Called twice: "u", "y"
|
271
|
-
* });
|
272
|
-
*
|
273
|
-
***/
|
274
|
-
'each': function(search, fn) {
|
275
|
-
var match, i;
|
276
|
-
if(isFunction(search)) {
|
277
|
-
fn = search;
|
278
|
-
search = /[\s\S]/g;
|
279
|
-
} else if(!search) {
|
280
|
-
search = /[\s\S]/g
|
281
|
-
} else if(isString(search)) {
|
282
|
-
search = regexp(escapeRegExp(search), 'gi');
|
283
|
-
} else if(isRegExp(search)) {
|
284
|
-
search = regexp(search.source, getRegExpFlags(search, 'g'));
|
285
|
-
}
|
286
|
-
match = this.match(search) || [];
|
287
|
-
if(fn) {
|
288
|
-
for(i = 0; i < match.length; i++) {
|
289
|
-
match[i] = fn.call(this, match[i], i, match) || match[i];
|
290
|
-
}
|
291
|
-
}
|
292
|
-
return match;
|
293
|
-
},
|
294
|
-
|
295
|
-
/***
|
296
|
-
* @method shift(<n>)
|
297
|
-
* @returns Array
|
298
|
-
* @short Shifts each character in the string <n> places in the character map.
|
299
|
-
* @example
|
300
|
-
*
|
301
|
-
* 'a'.shift(1) -> 'b'
|
302
|
-
* 'ク'.shift(1) -> 'グ'
|
303
|
-
*
|
304
|
-
***/
|
305
|
-
'shift': function(n) {
|
306
|
-
var result = '';
|
307
|
-
n = n || 0;
|
308
|
-
this.codes(function(c) {
|
309
|
-
result += chr(c + n);
|
310
|
-
});
|
311
|
-
return result;
|
312
|
-
},
|
313
|
-
|
314
|
-
/***
|
315
|
-
* @method codes([fn])
|
316
|
-
* @returns Array
|
317
|
-
* @short Runs callback [fn] against each character code in the string. Returns an array of character codes.
|
318
|
-
* @example
|
319
|
-
*
|
320
|
-
* 'jumpy'.codes() -> [106,117,109,112,121]
|
321
|
-
* 'jumpy'.codes(function(c) {
|
322
|
-
* // Called 5 times: 106, 117, 109, 112, 121
|
323
|
-
* });
|
324
|
-
*
|
325
|
-
***/
|
326
|
-
'codes': function(fn) {
|
327
|
-
var codes = [];
|
328
|
-
for(var i=0; i<this.length; i++) {
|
329
|
-
var code = this.charCodeAt(i);
|
330
|
-
codes.push(code);
|
331
|
-
if(fn) fn.call(this, code, i);
|
332
|
-
}
|
333
|
-
return codes;
|
334
|
-
},
|
335
|
-
|
336
|
-
/***
|
337
|
-
* @method chars([fn])
|
338
|
-
* @returns Array
|
339
|
-
* @short Runs callback [fn] against each character in the string. Returns an array of characters.
|
340
|
-
* @example
|
341
|
-
*
|
342
|
-
* 'jumpy'.chars() -> ['j','u','m','p','y']
|
343
|
-
* 'jumpy'.chars(function(c) {
|
344
|
-
* // Called 5 times: "j","u","m","p","y"
|
345
|
-
* });
|
346
|
-
*
|
347
|
-
***/
|
348
|
-
'chars': function(fn) {
|
349
|
-
return this.each(fn);
|
350
|
-
},
|
351
|
-
|
352
|
-
/***
|
353
|
-
* @method words([fn])
|
354
|
-
* @returns Array
|
355
|
-
* @short Runs callback [fn] against each word in the string. Returns an array of words.
|
356
|
-
* @extra A "word" here is defined as any sequence of non-whitespace characters.
|
357
|
-
* @example
|
358
|
-
*
|
359
|
-
* 'broken wear'.words() -> ['broken','wear']
|
360
|
-
* 'broken wear'.words(function(w) {
|
361
|
-
* // Called twice: "broken", "wear"
|
362
|
-
* });
|
363
|
-
*
|
364
|
-
***/
|
365
|
-
'words': function(fn) {
|
366
|
-
return this.trim().each(/\S+/g, fn);
|
367
|
-
},
|
368
|
-
|
369
|
-
/***
|
370
|
-
* @method lines([fn])
|
371
|
-
* @returns Array
|
372
|
-
* @short Runs callback [fn] against each line in the string. Returns an array of lines.
|
373
|
-
* @example
|
374
|
-
*
|
375
|
-
* 'broken wear\nand\njumpy jump'.lines() -> ['broken wear','and','jumpy jump']
|
376
|
-
* 'broken wear\nand\njumpy jump'.lines(function(l) {
|
377
|
-
* // Called three times: "broken wear", "and", "jumpy jump"
|
378
|
-
* });
|
379
|
-
*
|
380
|
-
***/
|
381
|
-
'lines': function(fn) {
|
382
|
-
return this.trim().each(/^.*$/gm, fn);
|
383
|
-
},
|
384
|
-
|
385
|
-
/***
|
386
|
-
* @method paragraphs([fn])
|
387
|
-
* @returns Array
|
388
|
-
* @short Runs callback [fn] against each paragraph in the string. Returns an array of paragraphs.
|
389
|
-
* @extra A paragraph here is defined as a block of text bounded by two or more line breaks.
|
390
|
-
* @example
|
391
|
-
*
|
392
|
-
* 'Once upon a time.\n\nIn the land of oz...'.paragraphs() -> ['Once upon a time.','In the land of oz...']
|
393
|
-
* 'Once upon a time.\n\nIn the land of oz...'.paragraphs(function(p) {
|
394
|
-
* // Called twice: "Once upon a time.", "In teh land of oz..."
|
395
|
-
* });
|
396
|
-
*
|
397
|
-
***/
|
398
|
-
'paragraphs': function(fn) {
|
399
|
-
var paragraphs = this.trim().split(/[\r\n]{2,}/);
|
400
|
-
paragraphs = paragraphs.map(function(p) {
|
401
|
-
if(fn) var s = fn.call(p);
|
402
|
-
return s ? s : p;
|
403
|
-
});
|
404
|
-
return paragraphs;
|
405
|
-
},
|
406
|
-
|
407
|
-
/***
|
408
|
-
* @method isBlank()
|
409
|
-
* @returns Boolean
|
410
|
-
* @short Returns true if the string has a length of 0 or contains only whitespace.
|
411
|
-
* @example
|
412
|
-
*
|
413
|
-
* ''.isBlank() -> true
|
414
|
-
* ' '.isBlank() -> true
|
415
|
-
* 'noway'.isBlank() -> false
|
416
|
-
*
|
417
|
-
***/
|
418
|
-
'isBlank': function() {
|
419
|
-
return this.trim().length === 0;
|
420
|
-
},
|
421
|
-
|
422
|
-
/***
|
423
|
-
* @method has(<find>)
|
424
|
-
* @returns Boolean
|
425
|
-
* @short Returns true if the string matches <find>.
|
426
|
-
* @extra <find> may be a string or regex.
|
427
|
-
* @example
|
428
|
-
*
|
429
|
-
* 'jumpy'.has('py') -> true
|
430
|
-
* 'broken'.has(/[a-n]/) -> true
|
431
|
-
* 'broken'.has(/[s-z]/) -> false
|
432
|
-
*
|
433
|
-
***/
|
434
|
-
'has': function(find) {
|
435
|
-
return this.search(isRegExp(find) ? find : escapeRegExp(find)) !== -1;
|
436
|
-
},
|
437
|
-
|
438
|
-
|
439
|
-
/***
|
440
|
-
* @method add(<str>, [index] = length)
|
441
|
-
* @returns String
|
442
|
-
* @short Adds <str> at [index]. Negative values are also allowed.
|
443
|
-
* @extra %insert% is provided as an alias, and is generally more readable when using an index.
|
444
|
-
* @example
|
445
|
-
*
|
446
|
-
* 'schfifty'.add(' five') -> schfifty five
|
447
|
-
* 'dopamine'.insert('e', 3) -> dopeamine
|
448
|
-
* 'spelling eror'.insert('r', -3) -> spelling error
|
449
|
-
*
|
450
|
-
***/
|
451
|
-
'add': function(str, index) {
|
452
|
-
index = isUndefined(index) ? this.length : index;
|
453
|
-
return this.slice(0, index) + str + this.slice(index);
|
454
|
-
},
|
455
|
-
|
456
|
-
/***
|
457
|
-
* @method remove(<f>)
|
458
|
-
* @returns String
|
459
|
-
* @short Removes any part of the string that matches <f>.
|
460
|
-
* @extra <f> can be a string or a regex.
|
461
|
-
* @example
|
462
|
-
*
|
463
|
-
* 'schfifty five'.remove('f') -> 'schity ive'
|
464
|
-
* 'schfifty five'.remove(/[a-f]/g) -> 'shity iv'
|
465
|
-
*
|
466
|
-
***/
|
467
|
-
'remove': function(f) {
|
468
|
-
return this.replace(f, '');
|
469
|
-
},
|
470
|
-
|
471
|
-
/***
|
472
|
-
* @method reverse()
|
473
|
-
* @returns String
|
474
|
-
* @short Reverses the string.
|
475
|
-
* @example
|
476
|
-
*
|
477
|
-
* 'jumpy'.reverse() -> 'ypmuj'
|
478
|
-
* 'lucky charms'.reverse() -> 'smrahc ykcul'
|
479
|
-
*
|
480
|
-
***/
|
481
|
-
'reverse': function() {
|
482
|
-
return this.split('').reverse().join('');
|
483
|
-
},
|
484
|
-
|
485
|
-
/***
|
486
|
-
* @method compact()
|
487
|
-
* @returns String
|
488
|
-
* @short Compacts all white space in the string to a single space and trims the ends.
|
489
|
-
* @example
|
490
|
-
*
|
491
|
-
* 'too \n much \n space'.compact() -> 'too much space'
|
492
|
-
* 'enough \n '.compact() -> 'enought'
|
493
|
-
*
|
494
|
-
***/
|
495
|
-
'compact': function() {
|
496
|
-
return this.trim().replace(/([\r\n\s ])+/g, function(match, whitespace){
|
497
|
-
return whitespace === ' ' ? whitespace : ' ';
|
498
|
-
});
|
499
|
-
},
|
500
|
-
|
501
|
-
/***
|
502
|
-
* @method at(<index>, [loop] = true)
|
503
|
-
* @returns String or Array
|
504
|
-
* @short Gets the character(s) at a given index.
|
505
|
-
* @extra When [loop] is true, overshooting the end of the string (or the beginning) will begin counting from the other end. As an alternate syntax, passing multiple indexes will get the characters at those indexes.
|
506
|
-
* @example
|
507
|
-
*
|
508
|
-
* 'jumpy'.at(0) -> 'j'
|
509
|
-
* 'jumpy'.at(2) -> 'm'
|
510
|
-
* 'jumpy'.at(5) -> 'j'
|
511
|
-
* 'jumpy'.at(5, false) -> ''
|
512
|
-
* 'jumpy'.at(-1) -> 'y'
|
513
|
-
* 'lucky charms'.at(2,4,6,8) -> ['u','k','y',c']
|
514
|
-
*
|
515
|
-
***/
|
516
|
-
'at': function() {
|
517
|
-
return entryAtIndex(this, arguments, true);
|
518
|
-
},
|
519
|
-
|
520
|
-
/***
|
521
|
-
* @method from([index] = 0)
|
522
|
-
* @returns String
|
523
|
-
* @short Returns a section of the string starting from [index].
|
524
|
-
* @example
|
525
|
-
*
|
526
|
-
* 'lucky charms'.from() -> 'lucky charms'
|
527
|
-
* 'lucky charms'.from(7) -> 'harms'
|
528
|
-
*
|
529
|
-
***/
|
530
|
-
'from': function(num) {
|
531
|
-
return this.slice(num);
|
532
|
-
},
|
533
|
-
|
534
|
-
/***
|
535
|
-
* @method to([index] = end)
|
536
|
-
* @returns String
|
537
|
-
* @short Returns a section of the string ending at [index].
|
538
|
-
* @example
|
539
|
-
*
|
540
|
-
* 'lucky charms'.to() -> 'lucky charms'
|
541
|
-
* 'lucky charms'.to(7) -> 'lucky ch'
|
542
|
-
*
|
543
|
-
***/
|
544
|
-
'to': function(num) {
|
545
|
-
if(isUndefined(num)) num = this.length;
|
546
|
-
return this.slice(0, num);
|
547
|
-
},
|
548
|
-
|
549
|
-
/***
|
550
|
-
* @method dasherize()
|
551
|
-
* @returns String
|
552
|
-
* @short Converts underscores and camel casing to hypens.
|
553
|
-
* @example
|
554
|
-
*
|
555
|
-
* 'a_farewell_to_arms'.dasherize() -> 'a-farewell-to-arms'
|
556
|
-
* 'capsLock'.dasherize() -> 'caps-lock'
|
557
|
-
*
|
558
|
-
***/
|
559
|
-
'dasherize': function() {
|
560
|
-
return this.underscore().replace(/_/g, '-');
|
561
|
-
},
|
562
|
-
|
563
|
-
/***
|
564
|
-
* @method underscore()
|
565
|
-
* @returns String
|
566
|
-
* @short Converts hyphens and camel casing to underscores.
|
567
|
-
* @example
|
568
|
-
*
|
569
|
-
* 'a-farewell-to-arms'.underscore() -> 'a_farewell_to_arms'
|
570
|
-
* 'capsLock'.underscore() -> 'caps_lock'
|
571
|
-
*
|
572
|
-
***/
|
573
|
-
'underscore': function() {
|
574
|
-
return this
|
575
|
-
.replace(/[-\s]+/g, '_')
|
576
|
-
.replace(string.Inflector && string.Inflector.acronymRegExp, function(acronym, index) {
|
577
|
-
return (index > 0 ? '_' : '') + acronym.toLowerCase();
|
578
|
-
})
|
579
|
-
.replace(/([A-Z\d]+)([A-Z][a-z])/g,'$1_$2')
|
580
|
-
.replace(/([a-z\d])([A-Z])/g,'$1_$2')
|
581
|
-
.toLowerCase();
|
582
|
-
},
|
583
|
-
|
584
|
-
/***
|
585
|
-
* @method camelize([first] = true)
|
586
|
-
* @returns String
|
587
|
-
* @short Converts underscores and hyphens to camel case. If [first] is true the first letter will also be capitalized.
|
588
|
-
* @extra If the Inflections package is included acryonyms can also be defined that will be used when camelizing.
|
589
|
-
* @example
|
590
|
-
*
|
591
|
-
* 'caps_lock'.camelize() -> 'CapsLock'
|
592
|
-
* 'moz-border-radius'.camelize() -> 'MozBorderRadius'
|
593
|
-
* 'moz-border-radius'.camelize(false) -> 'mozBorderRadius'
|
594
|
-
*
|
595
|
-
***/
|
596
|
-
'camelize': function(first) {
|
597
|
-
return this.underscore().replace(/(^|_)([^_]+)/g, function(match, pre, word, index) {
|
598
|
-
var acronym = getAcronym(word), capitalize = first !== false || index > 0;
|
599
|
-
if(acronym) return capitalize ? acronym : acronym.toLowerCase();
|
600
|
-
return capitalize ? word.capitalize() : word;
|
601
|
-
});
|
602
|
-
},
|
603
|
-
|
604
|
-
/***
|
605
|
-
* @method spacify()
|
606
|
-
* @returns String
|
607
|
-
* @short Converts camel case, underscores, and hyphens to a properly spaced string.
|
608
|
-
* @example
|
609
|
-
*
|
610
|
-
* 'camelCase'.spacify() -> 'camel case'
|
611
|
-
* 'an-ugly-string'.spacify() -> 'an ugly string'
|
612
|
-
* 'oh-no_youDid-not'.spacify().capitalize(true) -> 'something else'
|
613
|
-
*
|
614
|
-
***/
|
615
|
-
'spacify': function() {
|
616
|
-
return this.underscore().replace(/_/g, ' ');
|
617
|
-
},
|
618
|
-
|
619
|
-
/***
|
620
|
-
* @method stripTags([tag1], [tag2], ...)
|
621
|
-
* @returns String
|
622
|
-
* @short Strips all HTML tags from the string.
|
623
|
-
* @extra Tags to strip may be enumerated in the parameters, otherwise will strip all.
|
624
|
-
* @example
|
625
|
-
*
|
626
|
-
* '<p>just <b>some</b> text</p>'.stripTags() -> 'just some text'
|
627
|
-
* '<p>just <b>some</b> text</p>'.stripTags('p') -> 'just <b>some</b> text'
|
628
|
-
*
|
629
|
-
***/
|
630
|
-
'stripTags': function() {
|
631
|
-
var str = this, args = arguments.length > 0 ? arguments : [''];
|
632
|
-
flattenedArgs(args, function(tag) {
|
633
|
-
str = str.replace(regexp('<\/?' + escapeRegExp(tag) + '[^<>]*>', 'gi'), '');
|
634
|
-
});
|
635
|
-
return str;
|
636
|
-
},
|
637
|
-
|
638
|
-
/***
|
639
|
-
* @method removeTags([tag1], [tag2], ...)
|
640
|
-
* @returns String
|
641
|
-
* @short Removes all HTML tags and their contents from the string.
|
642
|
-
* @extra Tags to remove may be enumerated in the parameters, otherwise will remove all.
|
643
|
-
* @example
|
644
|
-
*
|
645
|
-
* '<p>just <b>some</b> text</p>'.removeTags() -> ''
|
646
|
-
* '<p>just <b>some</b> text</p>'.removeTags('b') -> '<p>just text</p>'
|
647
|
-
*
|
648
|
-
***/
|
649
|
-
'removeTags': function() {
|
650
|
-
var str = this, args = arguments.length > 0 ? arguments : ['\\S+'];
|
651
|
-
flattenedArgs(args, function(t) {
|
652
|
-
var reg = regexp('<(' + t + ')[^<>]*(?:\\/>|>.*?<\\/\\1>)', 'gi');
|
653
|
-
str = str.replace(reg, '');
|
654
|
-
});
|
655
|
-
return str;
|
656
|
-
},
|
657
|
-
|
658
|
-
/***
|
659
|
-
* @method truncate(<length>, [split] = true, [from] = 'right', [ellipsis] = '...')
|
660
|
-
* @returns Object
|
661
|
-
* @short Truncates a string.
|
662
|
-
* @extra If [split] is %false%, will not split words up, and instead discard the word where the truncation occurred. [from] can also be %"middle"% or %"left"%.
|
663
|
-
* @example
|
664
|
-
*
|
665
|
-
* 'just sittin on the dock of the bay'.truncate(20) -> 'just sittin on the do...'
|
666
|
-
* 'just sittin on the dock of the bay'.truncate(20, false) -> 'just sittin on the...'
|
667
|
-
* 'just sittin on the dock of the bay'.truncate(20, true, 'middle') -> 'just sitt...of the bay'
|
668
|
-
* 'just sittin on the dock of the bay'.truncate(20, true, 'left') -> '...the dock of the bay'
|
669
|
-
*
|
670
|
-
***/
|
671
|
-
'truncate': function(length, split, from, ellipsis) {
|
672
|
-
var pos,
|
673
|
-
prepend = '',
|
674
|
-
append = '',
|
675
|
-
str = this.toString(),
|
676
|
-
chars = '[' + getTrimmableCharacters() + ']+',
|
677
|
-
space = '[^' + getTrimmableCharacters() + ']*',
|
678
|
-
reg = regexp(chars + space + '$');
|
679
|
-
ellipsis = isUndefined(ellipsis) ? '...' : string(ellipsis);
|
680
|
-
if(str.length <= length) {
|
681
|
-
return str;
|
682
|
-
}
|
683
|
-
switch(from) {
|
684
|
-
case 'left':
|
685
|
-
pos = str.length - length;
|
686
|
-
prepend = ellipsis;
|
687
|
-
str = str.slice(pos);
|
688
|
-
reg = regexp('^' + space + chars);
|
689
|
-
break;
|
690
|
-
case 'middle':
|
691
|
-
pos = floor(length / 2);
|
692
|
-
append = ellipsis + str.slice(str.length - pos).trimLeft();
|
693
|
-
str = str.slice(0, pos);
|
694
|
-
break;
|
695
|
-
default:
|
696
|
-
pos = length;
|
697
|
-
append = ellipsis;
|
698
|
-
str = str.slice(0, pos);
|
699
|
-
}
|
700
|
-
if(split === false && this.slice(pos, pos + 1).match(/\S/)) {
|
701
|
-
str = str.remove(reg);
|
702
|
-
}
|
703
|
-
return prepend + str + append;
|
704
|
-
},
|
705
|
-
|
706
|
-
/***
|
707
|
-
* @method pad[Side](<padding> = '', [num] = 1)
|
708
|
-
* @returns String
|
709
|
-
* @short Pads either/both sides of the string.
|
710
|
-
* @extra [num] is the number of characters on each side, and [padding] is the character to pad with.
|
711
|
-
*
|
712
|
-
* @set
|
713
|
-
* pad
|
714
|
-
* padLeft
|
715
|
-
* padRight
|
716
|
-
*
|
717
|
-
* @example
|
718
|
-
*
|
719
|
-
* 'wasabi'.pad('-') -> '-wasabi-'
|
720
|
-
* 'wasabi'.pad('-', 2) -> '--wasabi--'
|
721
|
-
* 'wasabi'.padLeft('-', 2) -> '--wasabi'
|
722
|
-
* 'wasabi'.padRight('-', 2) -> 'wasabi--'
|
723
|
-
*
|
724
|
-
***/
|
725
|
-
'pad': function(padding, num) {
|
726
|
-
return repeatString(num, padding) + this + repeatString(num, padding);
|
727
|
-
},
|
728
|
-
|
729
|
-
'padLeft': function(padding, num) {
|
730
|
-
return repeatString(num, padding) + this;
|
731
|
-
},
|
732
|
-
|
733
|
-
'padRight': function(padding, num) {
|
734
|
-
return this + repeatString(num, padding);
|
735
|
-
},
|
736
|
-
|
737
|
-
/***
|
738
|
-
* @method first([n] = 1)
|
739
|
-
* @returns String
|
740
|
-
* @short Returns the first [n] characters of the string.
|
741
|
-
* @example
|
742
|
-
*
|
743
|
-
* 'lucky charms'.first() -> 'l'
|
744
|
-
* 'lucky charms'.first(3) -> 'luc'
|
745
|
-
*
|
746
|
-
***/
|
747
|
-
'first': function(num) {
|
748
|
-
if(isUndefined(num)) num = 1;
|
749
|
-
return this.substr(0, num);
|
750
|
-
},
|
751
|
-
|
752
|
-
/***
|
753
|
-
* @method last([n] = 1)
|
754
|
-
* @returns String
|
755
|
-
* @short Returns the last [n] characters of the string.
|
756
|
-
* @example
|
757
|
-
*
|
758
|
-
* 'lucky charms'.last() -> 's'
|
759
|
-
* 'lucky charms'.last(3) -> 'rms'
|
760
|
-
*
|
761
|
-
***/
|
762
|
-
'last': function(num) {
|
763
|
-
if(isUndefined(num)) num = 1;
|
764
|
-
var start = this.length - num < 0 ? 0 : this.length - num;
|
765
|
-
return this.substr(start);
|
766
|
-
},
|
767
|
-
|
768
|
-
/***
|
769
|
-
* @method repeat([num] = 0)
|
770
|
-
* @returns String
|
771
|
-
* @short Returns the string repeated [num] times.
|
772
|
-
* @example
|
773
|
-
*
|
774
|
-
* 'jumpy'.repeat(2) -> 'jumpyjumpy'
|
775
|
-
* 'a'.repeat(5) -> 'aaaaa'
|
776
|
-
* 'a'.repeat(0) -> ''
|
777
|
-
*
|
778
|
-
***/
|
779
|
-
'repeat': function(num) {
|
780
|
-
var result = '', str = this;
|
781
|
-
if(!isNumber(num) || num < 1) return '';
|
782
|
-
while (num) {
|
783
|
-
if (num & 1) {
|
784
|
-
result += str;
|
785
|
-
}
|
786
|
-
if (num >>= 1) {
|
787
|
-
str += str;
|
788
|
-
}
|
789
|
-
}
|
790
|
-
return result;
|
791
|
-
},
|
792
|
-
|
793
|
-
/***
|
794
|
-
* @method toNumber([base] = 10)
|
795
|
-
* @returns Number
|
796
|
-
* @short Converts the string into a number.
|
797
|
-
* @extra Any value with a "." fill be converted to a floating point value, otherwise an integer.
|
798
|
-
* @example
|
799
|
-
*
|
800
|
-
* '153'.toNumber() -> 153
|
801
|
-
* '12,000'.toNumber() -> 12000
|
802
|
-
* '10px'.toNumber() -> 10
|
803
|
-
* 'ff'.toNumber(16) -> 255
|
804
|
-
*
|
805
|
-
***/
|
806
|
-
'toNumber': function(base) {
|
807
|
-
var str = this.replace(/,/g, '');
|
808
|
-
return str.match(/\./) ? parseFloat(str) : parseInt(str, base || 10);
|
809
|
-
},
|
810
|
-
|
811
|
-
/***
|
812
|
-
* @method capitalize([all] = false)
|
813
|
-
* @returns String
|
814
|
-
* @short Capitalizes the first character in the string.
|
815
|
-
* @extra If [all] is true, all words in the string will be capitalized.
|
816
|
-
* @example
|
817
|
-
*
|
818
|
-
* 'hello'.capitalize() -> 'Hello'
|
819
|
-
* 'hello kitty'.capitalize() -> 'Hello kitty'
|
820
|
-
* 'hello kitty'.capitalize(true) -> 'Hello Kitty'
|
821
|
-
*
|
822
|
-
*
|
823
|
-
***/
|
824
|
-
'capitalize': function(all) {
|
825
|
-
var lastResponded;
|
826
|
-
return this.toLowerCase().replace(all ? /[\s\S]/g : /^\S/, function(lower) {
|
827
|
-
var upper = lower.toUpperCase(), result;
|
828
|
-
result = lastResponded ? lower : upper;
|
829
|
-
lastResponded = upper !== lower;
|
830
|
-
return result;
|
831
|
-
});
|
832
|
-
},
|
833
|
-
|
834
|
-
/***
|
835
|
-
* @method assign(<obj1>, <obj2>, ...)
|
836
|
-
* @returns String
|
837
|
-
* @short Assigns variables to tokens in a string.
|
838
|
-
* @extra If an object is passed, it's properties can be assigned using the object's keys. If a non-object (string, number, etc.) is passed it can be accessed by the argument number beginning with 1 (as with regex tokens). Multiple objects can be passed and will be merged together (original objects are unaffected).
|
839
|
-
* @example
|
840
|
-
*
|
841
|
-
* 'Welcome, Mr. {name}.'.assign({ name: 'Franklin' }) -> 'Welcome, Mr. Franklin.'
|
842
|
-
* 'You are {1} years old today.'.assign(14) -> 'You are 14 years old today.'
|
843
|
-
* '{n} and {r}'.assign({ n: 'Cheech' }, { r: 'Chong' }) -> 'Cheech and Chong'
|
844
|
-
*
|
845
|
-
***/
|
846
|
-
'assign': function() {
|
847
|
-
var assign = {};
|
848
|
-
multiArgs(arguments, function(a, i) {
|
849
|
-
if(isObject(a)) {
|
850
|
-
simpleMerge(assign, a);
|
851
|
-
} else {
|
852
|
-
assign[i + 1] = a;
|
853
|
-
}
|
854
|
-
});
|
855
|
-
return this.replace(/\{([^{]+?)\}/g, function(m, key) {
|
856
|
-
return hasOwnProperty(assign, key) ? assign[key] : m;
|
857
|
-
});
|
858
|
-
},
|
859
|
-
|
860
|
-
/***
|
861
|
-
* @method namespace([init] = global)
|
862
|
-
* @returns Mixed
|
863
|
-
* @short Finds the namespace or property indicated by the string.
|
864
|
-
* @extra [init] can be passed to provide a starting context, otherwise the global context will be used. If any level returns a falsy value, that will be the final result.
|
865
|
-
* @example
|
866
|
-
*
|
867
|
-
* 'Path.To.Namespace'.namespace() -> Path.To.Namespace
|
868
|
-
* '$.fn'.namespace() -> $.fn
|
869
|
-
*
|
870
|
-
***/
|
871
|
-
'namespace': function(context) {
|
872
|
-
context = context || globalContext;
|
873
|
-
iterateOverObject(this.split('.'), function(i,s) {
|
874
|
-
return !!(context = context[s]);
|
875
|
-
});
|
876
|
-
return context;
|
877
|
-
}
|
878
|
-
});
|
879
|
-
|
880
|
-
|
881
|
-
// Aliases
|
882
|
-
|
883
|
-
extend(string, true, false, {
|
884
|
-
|
885
|
-
/***
|
886
|
-
* @method insert()
|
887
|
-
* @alias add
|
888
|
-
*
|
889
|
-
***/
|
890
|
-
'insert': string.prototype.add
|
891
|
-
});
|
892
|
-
|
893
|
-
buildBase64('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=');
|
894
|
-
|