Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

string

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

string - npm Package Compare versions

Comparing version
0.2.2
to
1.0.0
+8
.documentup.json
{
"name": "string.js",
"twitter": [
"jprichardson",
],
"google_analytics": "UA-35069840-1",
"travis": true
}
language: node_js
node_js:
- 0.6
- 0.8
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
<link rel="stylesheet" href="https://raw.github.com/visionmedia/mocha/master/mocha.css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://raw.github.com/visionmedia/mocha/master/mocha.js"></script>
<script src="../lib/string.js"></script>
<script>mocha.setup('bdd')</script>
<script src="string.test.js"></script>
<script>
$(function () {
mocha
.run()
.globals(['S']) // acceptable globals
})
</script>
</head>
<body>
<div id="mocha"></div>
</body>
</html>
(function() {
'use strict';
var S = null;
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined')
S = require('../lib/string');
else {
S = window.S;
}
function T(v) { if (!v) { throw new Error('Should be true.'); } };
function F(v) { if (v) { throw new Error('Should be false.'); } };
function ARY_EQ(a1, a2) {
T (a1.length === a2.length)
for (var i = 0; i < a1.length; ++i)
T (a1[i] === a2[i])
}
/*if (typeof window !== "undefined" && window !== null) {
S = window.S;
} else {
S = require('../lib/string');
}*/
describe('string.js', function() {
describe('- constructor', function() {
it('should should set the internal "s" property', function() {
T (S('helo').s === 'helo')
T (S(5).s === '5')
T (S(new Date(2012, 1, 1)).s.indexOf('2012') != -1)
T (S(new RegExp()).s.substr(0,1) === '/')
T (S({}).s === '[object Object]')
T (S(null).s === null)
T (S(undefined).s === undefined)
})
})
describe('- camelize()', function() {
it('should remove any underscores or dashes and convert a string into camel casing', function() {
T (S('data_rate').camelize().s === 'dataRate');
T (S('background-color').camelize().s === 'backgroundColor');
T (S('-moz-something').camelize().s === 'MozSomething');
T (S('_car_speed_').camelize().s === 'CarSpeed');
T (S('yes_we_can').camelize().s === 'yesWeCan');
})
})
describe('- capitalize()', function() {
it('should capitalize the string', function() {
T (S('jon').capitalize().s === 'Jon');
T (S('JP').capitalize().s === 'Jp');
})
})
describe('- charAt(index)', function() {
it('should return a native JavaScript string with the character at the specified position', function() {
T (S('hi').charAt(1) === 'i')
})
})
describe('+ clobberPrototype()', function() {
it('should extend the String prototype with the extra methods', function() {
S.clobberPrototype();
T (" hello!".endsWith('!'));
S.restorePrototype();
})
})
describe('- collapseWhitespace()', function() {
it('should convert all adjacent whitespace characters to a single space and trim the ends', function() {
T (S(' Strings \t are \n\n\t fun\n! ').collapseWhitespace().s === 'Strings are fun !');
})
})
describe('- contains(substring)', function() {
it('should return true if the string contains the specified input string', function() {
T (S('JavaScript is one of the best languages!').contains('one'));
F (S('What do you think?').contains('YES!'));
})
})
describe('- dasherize()', function() {
it('should convert a camel cased string into a string delimited by dashes', function() {
T (S('dataRate').dasherize().s === 'data-rate');
T (S('CarSpeed').dasherize().s === '-car-speed');
T (S('yesWeCan').dasherize().s === 'yes-we-can');
T (S('backgroundColor').dasherize().s === 'background-color');
})
})
describe('- decodeHtmlEntities()', function() {
it('should decode HTML entities into their proper string representation', function() {
T (S('Ken Thompson &amp; Dennis Ritchie').decodeHtmlEntities().s === 'Ken Thompson & Dennis Ritchie');
T (S('3 &lt; 4').decodeHtmlEntities().s === '3 < 4');
})
})
describe('- endsWith(suffix)', function() {
it("should return true if the string ends with the input string", function() {
T (S("hello jon").endsWith('jon'));
F (S('ffffaaa').endsWith('jon'));
T (S("").endsWith(''));
T (S("hi").endsWith(''));
T (S("hi").endsWith('hi'));
})
})
describe('- escapeHTML()', function() {
it('should escape the html', function() {
T (S('<div>Blah & "blah" & \'blah\'</div>').escapeHTML().s ===
'&lt;div&gt;Blah &amp; &quot;blah&quot; &amp; &apos;blah&apos;&lt;/div&gt;');
T (S('&lt;').escapeHTML().s === '&amp;lt;');
})
})
describe('- include(substring)', function() {
it('should return true if the string contains the specified input string', function() {
T (S('JavaScript is one of the best languages!').include('one'));
F (S('What do you think?').include('YES!'));
})
})
describe('- isAlpha()', function() {
it("should return true if the string contains only letters", function() {
T (S("afaf").isAlpha());
T (S("FJslfjkasfs").isAlpha());
F (S("adflj43faljsdf").isAlpha());
F (S("33").isAlpha());
F (S("TT....TTTafafetstYY").isAlpha());
})
})
describe('- isAlphaNumeric()', function() {
it("should return true if the string contains only letters and digits", function() {
T (S("afaf35353afaf").isAlphaNumeric());
T (S("FFFF99fff").isAlphaNumeric());
T (S("99").isAlphaNumeric());
T (S("afff").isAlphaNumeric());
T (S("Infinity").isAlphaNumeric());
F (S("-Infinity").isAlphaNumeric());
F (S("-33").isAlphaNumeric());
F (S("aaff..").isAlphaNumeric());
})
})
describe('- isEmpty()', function() {
it('should return true if the string is solely composed of whitespace or is null', function() {
T (S(' ').isEmpty());
T (S('\t\t\t ').isEmpty());
T (S('\n\n ').isEmpty());
F (S('hey').isEmpty())
T (S(null).isEmpty())
T (S(null).isEmpty())
})
})
describe('- isLower()', function() {
it('should return true if the character or string is lowercase', function() {
T (S('a').isLower());
T (S('z').isLower());
F (S('B').isLower());
T (S('hijp').isLower());
F (S('hi jp').isLower());
F (S('HelLO').isLower());
})
})
describe('- isNumeric()', function() {
it("should return true if the string only contains digits, this would not include Infinity or -Infinity", function() {
T (S("3").isNumeric());
F (S("34.22").isNumeric());
F (S("-22.33").isNumeric());
F (S("NaN").isNumeric());
F (S("Infinity").isNumeric());
F (S("-Infinity").isNumeric());
F (S("JP").isNumeric());
F (S("-5").isNumeric());
T (S("000992424242").isNumeric());
})
})
describe('- isUpper()', function() {
it('should return true if the character or string is uppercase', function() {
F (S('a').isUpper());
F (S('z').isUpper());
T (S('B').isUpper());
T (S('HIJP').isUpper());
F (S('HI JP').isUpper());
F (S('HelLO').isUpper());
})
})
describe('- length', function() {
it('should return the length of the string', function() {
T (S('hello').length === 5);
T (S('').length === 0);
T (S(null).length === -1);
T (S(undefined).length === -1);
})
})
describe('- left(N)', function() {
it('should return the substring denoted by N positive left-most characters', function() {
T (S('My name is JP').left(2).s === 'My');
T (S('Hi').left(0).s === '');
T (S('Hello').left(1).s === 'H');
})
it('should return the substring denoted by N negative left-most characters, equivalent to calling right(-N)', function() {
T (S('My name is JP').left(-2).s === 'JP');
})
})
describe('- lines()', function() {
it('should return an array of native strings representing lines with whitespace trimmed', function() {
var lines = S('1 Infinite Loop\r\nCupertino, CA').lines();
T (lines[0] === '1 Infinite Loop')
T (lines[1] === 'Cupertino, CA')
})
})
describe('- parseCSV([delim],[qualifier])', function() {
it('should parse a CSV line into an array', function() {
ARY_EQ (S("'a','b','c'").parseCSV(',', "'"), ['a', 'b', 'c'])
ARY_EQ (S('"a","b","c"').parseCSV(), ['a', 'b', 'c'])
ARY_EQ (S('a,b,c').parseCSV(',', null), ['a', 'b', 'c'])
ARY_EQ (S("'a,','b','c'").parseCSV(',', "'"), ['a,', 'b', 'c'])
ARY_EQ (S('"a","b",4,"c"').parseCSV(',', null), ['"a"', '"b"', '4', '"c"'])
ARY_EQ (S('"a","b","4","c"').parseCSV(), ['a', 'b', '4', 'c'])
ARY_EQ (S('"a","b", "4","c"').parseCSV(), ['a', 'b', '4', 'c'])
ARY_EQ (S('"a","b", 4,"c"').parseCSV(",", null), [ '"a"', '"b"', ' 4', '"c"' ])
ARY_EQ (S('"a","b\\"","d","c"').parseCSV(), ['a', 'b"', 'd', 'c'])
})
})
describe('- repeat(n)', function() {
it('should return a string with that is concatenated n times', function() {
T (S(' ').repeat(5).s === ' ');
T (S('*').repeat(3).s === '***');
})
})
describe('- replaceAll(substring, replacement)', function() {
it('should return the new string with all occurrences of substring replaced with the replacment string', function() {
T (S(' does IT work? ').replaceAll(' ', '_').s === '_does_IT_work?_');
T (S('Yes it does!').replaceAll(' ', '').s === 'Yesitdoes!');
var e = '\\', q = '"';
var r = e + q;
T (S('a').replaceAll(q, r).s === 'a');
})
})
describe('+ restorePrototype()', function() {
it('should restore the original String prototype', function() {
T (typeof ' hi'.endsWith === 'undefined');
S.clobberPrototype();
T (' hi'.endsWith('hi'));
S.restorePrototype();
T (typeof ' hi'.endsWith === 'undefined');
})
})
describe('- right(N)', function() {
it('should return the substring denoted by N positive right-most characters', function() {
T (S('I AM CRAZY').right(2).s === 'ZY');
T (S('Does it work? ').right(4).s === 'k? ');
T (S('Hi').right(0).s === '');
})
it('should return the substring denoted by N negative right-most characters, equivalent to calling left(-N)', function() {
T (S('My name is JP').right(-2).s === 'My');
})
})
describe('- s', function() {
it('should return the native string', function() {
T (S('hi').s === 'hi');
T (S('hi').toString() === S('hi').s);
})
})
describe('- slugify', function() {
it('should convert the text to url slug', function() {
T (S('Global Thermonuclear Warfare').slugify().s === 'global-thermonuclear-warfare')
})
})
describe('- startsWith(prefix)', function() {
it("should return true if the string starts with the input string", function() {
T (S("JP is a software engineer").startsWith("JP"));
F (S('wants to change the world').startsWith("politicians"));
T (S("").startsWith(""));
T (S("Hi").startsWith(""));
T (S("JP").startsWith("JP"));
})
})
describe('- stripTags([tag1],[tag2],...)', function() {
it('should strip all of the html tags or tags specified by the parameters', function() {
T (S('<p>just <b>some</b> text</p>').stripTags().s === 'just some text')
T (S('<p>just <b>some</b> text</p>').stripTags('p').s === 'just <b>some</b> text')
})
})
describe('- times(n)', function() {
it('should return a string with that is concatenated n times', function() {
T (S(' ').times(5).s === ' ');
T (S('*').times(3).s === '***');
})
})
describe('- toCSV(options)', function() {
it('should convert the array to csv', function() {
T (S(['a', 'b', 'c']).toCSV().s === '"a","b","c"');
T (S(['a', 'b', 'c']).toCSV(':').s === '"a":"b":"c"');
T (S(['a', 'b', 'c']).toCSV(':', null).s === 'a:b:c');
T (S(['a', 'b', 'c']).toCSV('*', "'").s === "'a'*'b'*'c'");
T (S(['a"', 'b', 4, 'c']).toCSV({delimiter: ',', qualifier: '"', escape: '\\', encloseNumbers: false}).s === '"a\\"","b",4,"c"');
T (S({firstName: 'JP', lastName: 'Richardson'}).toCSV({keys: true}).s === '"firstName","lastName"');
T (S({firstName: 'JP', lastName: 'Richardson'}).toCSV().s === '"JP","Richardson"');
})
})
describe('- toString()', function() {
it('should return the native string', function() {
T (S('hi').toString() === 'hi');
T (S('hi').toString() === S('hi').s);
})
})
describe('- toInt()', function() {
it('should return the integer value, wraps parseInt', function() {
T (S('5').toInt() === 5);
T (S('5.3').toInt() === 5);
T (S(5.3).toInt() === 5);
T (S('-10').toInt() === -10);
T (S('55 adfafaf').toInt() === 55)
T (S('afff 44').toInt().toString() === 'NaN')
T (S('0xff').toInt() == 255)
})
})
describe('- toFloat([precision])', function() {
it('should return the float value, wraps parseFloat', function() {
T (S('5').toFloat() === 5);
T (S('5.3').toFloat() === 5.3);
T (S(5.3).toFloat() === 5.3);
T (S('-10').toFloat() === -10);
T (S('55.3 adfafaf').toFloat() === 55.3)
T (S('afff 44').toFloat().toString() === 'NaN')
T (S(3.45522222333232).toFloat(2) === 3.46)
})
})
describe('- trim()', function() {
it('should return the string with leading and trailing whitespace removed', function() {
T (S('hello ').trim().s === 'hello');
T (S(' hello ').trim().s === 'hello');
T (S('\nhello').trim().s === 'hello');
T (S('\nhello\r\n').trim().s === 'hello');
T (S('\thello\t').trim().s === 'hello');
})
})
describe('- trimLeft()', function() {
it('should return the string with leading whitespace removed', function() {
T (S(' How are you?').trimLeft().s === 'How are you?');
T (S(' JP ').trimLeft().s === 'JP ');
})
})
describe('- trimRight()', function() {
it('should return the string with trailing whitespace removed', function() {
T (S('How are you? ').trimRight().s === 'How are you?');
T (S(' JP ').trimRight().s === ' JP');
})
})
describe('- truncate(length, [chars])', function() {
it('should truncate the string, accounting for word placement and chars count', function() {
T (S('this is some long text').truncate(3).s === '...')
T (S('this is some long text').truncate(7).s === 'this is...')
T (S('this is some long text').truncate(11).s === 'this is...')
T (S('this is some long text').truncate(12).s === 'this is some...')
T (S('this is some long text').truncate(11).s === 'this is...')
T (S('this is some long text').truncate(14, ' read more').s === 'this is some read more')
})
})
describe('- underscore()', function() {
it('should convert a camel cased string into a string separated by underscores', function() {
T (S('dataRate').underscore().s === 'data_rate');
T (S('CarSpeed').underscore().s === '_car_speed');
T (S('yesWeCan').underscore().s === 'yes_we_can');
})
})
describe('- unescapeHTML', function() {
it('should unescape the HTML', function() {
T (S('&lt;div&gt;Blah &amp; &quot;blah&quot; &amp; &apos;blah&apos;&lt;/div&gt;').unescapeHTML().s ===
'<div>Blah & "blah" & \'blah\'</div>');
T (S('&amp;lt;').unescapeHTML().s === '&lt;');
})
})
describe('- valueOf()', function() {
it('should return the primitive value of the string, wraps native valueOf()', function() {
T (S('hi').valueOf() === 'hi')
})
})
describe('+ VERSION', function() {
it('should exist', function() {
T (S.VERSION)
})
})
it('should import native JavaScript string methods', function() {
T (S('hi ').substr(0,1).trimRight().startsWith('h'));
T (S('hello ').concat('jp').indexOf('jp') === 6);
T (S('this is so cool').substr(0, 4).s === 'this');
})
})
}).call(this);
+32
-9

@@ -0,3 +1,21 @@

1.0.0 / 2012-09-25
------------------
* Translated from CoffeeScript to JavaScript.
* Added native JavaScript string functions such as `substr()`, `substring()`, `match()`, `indexOf()`, etc.
* Added `length` property.
* Renamed `ltrim()` to `trimLeft()` and `rtrim()` to `trimRight()`.
* Added `valueOf()` method.
* Added `toInt()`\`toInteger()` and `toFloat()` methods.
* Modified behavior of `isEmpty()` to return true on `undefined` or `null`.
* Constructor will now cast the parameter to a string via its `toString()` method.
* Added `VERSION` value. Useful for browser dependency checking.
* Added `lines()` method.
* Added `slugify()` method.
* Added `escapeHTML()` and `unescapeHTML()` methods.
* Added `truncate()` method.
* Added `stripTags()` method.
* Added `toCSV()` and `parseCSV()` methods.
0.2.2 / 2012-09-20
==================
------------------
* Fixed bug in `left()` closes #6

@@ -7,3 +25,3 @@ * Upgraded to CoffeeScript 1.3.*. Last CoffeeScript release of `string.js`.

0.2.1 / 2012-03-09
==================
------------------
* Updated README to include Quirks/Credits.

@@ -13,3 +31,3 @@ * Added method `decodeHtmlEntities()`.

0.2.0 / 2012-03-02
==================
------------------
* Fixed method type `cloberPrototype()` to `clobberPrototype()`.

@@ -24,9 +42,12 @@ * Fixed Node.js testing bug that caused `T` and `F` to be undefined functions.

### 0.1.2 / 2012-02-27
0.1.2 / 2012-02-27
------------------
* Package.json updates.
### 0.1.1 / 2012-02-27
0.1.1 / 2012-02-27
------------------
* Package.json updates.
### 0.1.0 / 2012-02-27
0.1.0 / 2012-02-27
------------------
* Added a few more methods.

@@ -37,3 +58,4 @@ * Removed default behavior of modifying `String.prototype`

### 0.0.4 / 2012-01-27
0.0.4 / 2012-01-27
----------------------
* Added trim() method for IE browsers

@@ -44,6 +66,7 @@ * Moved string.coffee to lib/string.coffee

### 0.0.3 / 2012-01-20
0.0.3 / 2012-01-20
------------------
* Cleaned package.json file
* Removed dependency on CoffeeScript and Jasmine
* Removed development dependency on CoffeeScript and Jasmine
* Changed testing from Jasmine to Mocha
* Added `includes` and `contains` methods

@@ -1,47 +0,86 @@

// Generated by CoffeeScript 1.3.3
(function() {
var S, clobberPrototype, methodsAdded, restorePrototype, wrap;
/*
string.js - Copyright (C) 2012, JP Richardson <jprichardson@gmail.com>
S = (function() {
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is furnished to
do so, subject to the following conditions:
function S(s) {
this.s = s;
if (this.s == null) {
this.s = this;
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
;(function() {
"use strict";
var VERSION = '1.0.0';
function S(s) {
if (s !== null && s!== undefined) {
if (typeof s == 'string')
this.s = s;
else {
this.s = s.toString();
this.orig = s; //original object, currently only used by toCSV()
}
} else {
this.s = s; //null or undefined
}
S.prototype.camelize = function() {
var s;
s = this.trim().s.replace(/(\-|_|\s)+(.)?/g, function(match, sep, c) {
if (s !== null && s!== undefined) {
if (this.__defineGetter__) {
this.__defineGetter__('length', function() {
return this.s.length;
})
} else {
this.length = s.length;
}
} else {
this.length = -1;
}
}
var __nsp = String.prototype;
var __sp = S.prototype = {
//# modified slightly from https://github.com/epeli/underscore.string
camelize: function() {
var s = this.trim().s.replace(/(\-|_|\s)+(.)?/g, function(mathc, sep, c) {
return (c ? c.toUpperCase() : '');
});
return new S(s);
};
S.prototype.capitalize = function() {
},
capitalize: function() {
return new S(this.s.substr(0, 1).toUpperCase() + this.s.substring(1).toLowerCase());
};
},
S.prototype.collapseWhitespace = function() {
var s;
s = this.s.replace(/[\s\xa0]+/g, ' ').replace(/^\s+|\s+$/g, '');
charAt: function(index) {
return this.s.charAt(index);
},
//#thanks Google
collapseWhitespace: function() {
var s = this.s.replace(/[\s\xa0]+/g, ' ').replace(/^\s+|\s+$/g, '');
return new S(s);
};
},
S.prototype.contains = function(ss) {
contains: function(ss) {
return this.s.indexOf(ss) >= 0;
};
},
S.prototype.dasherize = function() {
var s;
s = this.trim().s.replace(/[_\s]+/g, '-').replace(/([A-Z])/g, '-$1').replace(/-+/g, '-').toLowerCase();
//#modified from https://github.com/epeli/underscore.string
dasherize: function() {
var s = this.trim().s.replace(/[_\s]+/g, '-').replace(/([A-Z])/g, '-$1').replace(/-+/g, '-').toLowerCase();
return new S(s);
};
},
S.prototype.decodeHtmlEntities = function(quote_style) {
var entity, hash_map, symbol, tmp_str;
hash_map = {};
symbol = entity = "";
tmp_str = this.s;
decodeHtmlEntities: function(quote_style) { //from php.js
var symbol = "", entity = "", hash_map = {};
var tmp_str = this.s;
if (false === (hash_map = get_html_translation_table("HTML_ENTITIES", quote_style))) {

@@ -58,38 +97,40 @@ return false;

return new S(tmp_str);
};
},
S.prototype.endsWith = function(suffix) {
var l;
l = this.s.length - suffix.length;
endsWith: function(suffix) {
var l = this.s.length - suffix.length;
return l >= 0 && this.s.indexOf(suffix, l) === l;
};
},
S.prototype.isAlpha = function() {
escapeHTML: function() { //from underscore.string
return new S(this.s.replace(/[&<>"']/g, function(m){ return '&' + reversedEscapeChars[m] + ';'; }));
},
isAlpha: function() {
return !/[^a-zA-Z]/.test(this.s);
};
},
S.prototype.isAlphaNumeric = function() {
isAlphaNumeric: function() {
return !/[^a-zA-Z0-9]/.test(this.s);
};
},
S.prototype.isEmpty = function() {
return /^[\s\xa0]*$/.test(this.s);
};
isEmpty: function() {
return this.s === null || this.s === undefined ? true : /^[\s\xa0]*$/.test(this.s);
},
S.prototype.isLower = function() {
isLower: function() {
return !/[^a-z]/.test(this.s);
};
},
S.prototype.isNumeric = function() {
isNumeric: function() {
return !/[^0-9]/.test(this.s);
};
},
S.prototype.isUpper = function() {
isUpper: function() {
return !/[^A-Z]/.test(this.s);
};
},
S.prototype.left = function(N) {
var s;
left: function(N) {
if (N >= 0) {
s = this.s.substr(0, N);
var s = this.s.substr(0, N);
return new S(s);

@@ -99,20 +140,70 @@ } else {

}
};
},
S.prototype.ltrim = function() {
var s;
s = this.s.replace(/(^\s*)/g, '');
return new S(s);
};
lines: function() {
var lines = this.s.split('\n')
for (var i = 0; i < lines.length; ++i) {
lines[i] = lines[i].replace(/(^\s*|\s*$)/g, '');
}
return lines;
},
S.prototype.replaceAll = function(ss, r) {
var s;
s = this.s.replace(new RegExp(ss, 'g'), r);
parseCSV: function(delimiter, qualifier) { //try to parse no matter what
delimiter = delimiter || ',';
escape = '\\'
if (typeof qualifier == 'undefined')
qualifier = '"';
var i = 0, fieldBuffer = [], fields = [], len = this.s.length, inField = false, self = this;
var ca = function(i){return self.s.charAt(i)};
if (!qualifier)
inField = true;
while (i < len) {
var current = ca(i);
switch (current) {
case qualifier:
if (!inField) {
inField = true;
} else {
if (ca(i-1) === escape)
fieldBuffer.push(current);
else
inField = false;
}
break;
case delimiter:
if (inField && qualifier)
fieldBuffer.push(current);
else {
fields.push(fieldBuffer.join(''))
fieldBuffer.length = 0;
}
break;
case escape:
if (qualifier)
if (ca(i+1) !== qualifier)
fieldBuffer.push(current);
break;
default:
if (inField)
fieldBuffer.push(current);
break;
}
i += 1;
}
fields.push(fieldBuffer.join(''))
return fields;
},
replaceAll: function(ss, r) {
var s = this.s.replace(new RegExp(ss, 'g'), r);
return new S(s);
};
},
S.prototype.right = function(N) {
var s;
right: function(N) {
if (N >= 0) {
s = this.s.substr(this.s.length - N, N);
var s = this.s.substr(this.s.length - N, N);
return new S(s);

@@ -122,19 +213,41 @@ } else {

}
};
},
S.prototype.rtrim = function() {
var s;
s = this.s.replace(/\s+$/, '');
return new S(s);
};
slugify: function() {
var sl = (new S(this.s.replace(/[^\w\s-]/g, ''))).dasherize().s;
if (sl.charAt(0) === '-')
sl = sl.substr(1);
return new S(sl);
},
S.prototype.startsWith = function(prefix) {
startsWith: function(prefix) {
return this.s.lastIndexOf(prefix, 0) === 0;
};
},
S.prototype.times = function(n) {
stripTags: function() { //from sugar.js
var s = this.s, args = arguments.length > 0 ? arguments : [''];
multiArgs(args, function(tag) {
s = s.replace(RegExp('<\/?' + tag + '[^<>]*>', 'gi'), '');
});
return new S(s);
},
times: function(n) {
return new S(new Array(n + 1).join(this.s));
};
},
S.prototype.trim = function() {
toFloat: function(precision) {
var num = parseFloat(this.s, 10);
if (precision)
return parseFloat(num.toFixed(precision));
else
return num;
},
toInt: function() { //thanks Google
// If the string starts with '0x' or '-0x', parse as hex.
return /^\s*-?0x/i.test(this.s) ? parseInt(this.s, 16) : parseInt(this.s, 10);
},
trim: function() {
var s;

@@ -147,11 +260,106 @@ if (typeof String.prototype.trim === 'undefined') {

return new S(s);
};
},
S.prototype.toString = function() {
trimLeft: function() {
var s;
if (__nsp.trimLeft)
s = this.s.trimLeft();
else
s = this.s.replace(/(^\s*)/g, '');
return new S(s);
},
trimRight: function() {
var s;
if (__nsp.trimRight)
s = this.s.trimRight();
else
s = this.s.replace(/\s+$/, '');
return new S(s);
},
truncate: function(length, pruneStr) { //from underscore.string, author: github.com/rwz
var str = this.s;
length = ~~length;
pruneStr = pruneStr || '...';
if (str.length <= length) return str;
var tmpl = function(c){ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; },
template = str.slice(0, length+1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA'
if (template.slice(template.length-2).match(/\w\w/))
template = template.replace(/\s*\S+$/, '');
else
template = new S(template.slice(0, template.length-1)).trimRight().s;
return (template+pruneStr).length > str.length ? new S(str) : new S(str.slice(0, template.length)+pruneStr);
},
toCSV: function() {
var delim = ',', qualifier = '"', escapeChar = '\\', encloseNumbers = true, keys = false;
var dataArray = [];
function hasVal(it) {
return it !== null && it !== '';
}
if (typeof arguments[0] === 'object') {
delim = arguments[0].delimiter || delim;
delim = arguments[0].separator || delim;
qualifier = arguments[0].qualifier || qualifier;
encloseNumbers = !!arguments[0].encloseNumbers;
escapeChar = arguments[0].escapeChar || escapeChar;
keys = !!arguments[0].keys;
} else if (typeof arguments[0] === 'string') {
delim = arguments[0];
}
if (typeof arguments[1] === 'string')
qualifier = arguments[1];
if (arguments[1] === null)
qualifier = null;
if (this.orig instanceof Array)
dataArray = this.orig;
else { //object
for (var key in this.orig)
if (this.orig.hasOwnProperty(key))
if (keys)
dataArray.push(key);
else
dataArray.push(this.orig[key]);
}
var rep = escapeChar + qualifier;
var buildString = [];
for (var i = 0; i < dataArray.length; ++i) {
var shouldQualify = hasVal(qualifier)
if (typeof dataArray[i] == 'number')
shouldQualify &= encloseNumbers;
if (shouldQualify)
buildString.push(qualifier);
var d = new S(dataArray[i]).replaceAll(qualifier, rep).s;
buildString.push(d);
if (shouldQualify)
buildString.push(qualifier);
if (delim)
buildString.push(delim);
}
//chop last delim
//console.log(buildString.length)
buildString.length = buildString.length - 1;
return new S(buildString.join(''));
},
toString: function() {
return this.s;
};
},
S.prototype.underscore = function() {
var s;
s = this.trim().s.replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase();
//#modified from https://github.com/epeli/underscore.string
underscore: function() {
var s = this.trim().s.replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase();
if ((new S(this.s.charAt(0))).isUpper()) {

@@ -161,203 +369,322 @@ s = '_' + s;

return new S(s);
};
},
S.prototype.repeat = S.prototype.times;
unescapeHTML: function() { //from underscore.string
return new S(this.s.replace(/\&([^;]+);/g, function(entity, entityCode){
var match;
S.prototype.include = S.prototype.contains;
if (entityCode in escapeChars) {
return escapeChars[entityCode];
} else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) {
return String.fromCharCode(parseInt(match[1], 16));
} else if (match = entityCode.match(/^#(\d+)$/)) {
return String.fromCharCode(~~match[1]);
} else {
return entity;
}
}));
},
return S;
valueOf: function() {
return this.s.valueOf();
}
})();
}
wrap = function(str) {
return new S(str);
};
var methodsAdded = [];
function clobberPrototype() {
for (var name in __sp) {
(function(name){
var func = __sp[name];
if (!__nsp.hasOwnProperty(name)) {
methodsAdded.push(name);
__nsp[name] = function() {
String.prototype.s = this;
return func.apply(this, arguments);
}
}
})(name);
}
}
methodsAdded = [];
function restorePrototype() {
for (var i = 0; i < methodsAdded.length; ++i)
delete String.prototype[methodsAdded[i]];
methodsAdded.length = 0;
}
clobberPrototype = function() {
var func, name, newS, _results;
newS = new S();
_results = [];
for (name in newS) {
func = newS[name];
if (!String.prototype.hasOwnProperty(name)) {
methodsAdded.push(name);
_results.push(String.prototype[name] = function() {
String.prototype.s = this;
return func.apply(this, arguments);
});
} else {
_results.push(void 0);
/*************************************
/* Attach Native JavaScript String Properties
/*************************************/
var nativeProperties = getNativeStringProperties();
for (var name in nativeProperties) {
(function(name) {
var stringProp = __nsp[name];
if (typeof stringProp == 'function') {
//console.log(stringProp)
if (!__sp[name]) {
if (nativeProperties[name] === 'string') {
__sp[name] = function() {
//console.log(name)
return new S(stringProp.apply(this, arguments));
}
} else {
__sp[name] = stringProp;
}
}
}
})(name);
}
/*************************************
/* Function Aliases
/*************************************/
__sp.repeat = __sp.times;
__sp.include = __sp.contains;
__sp.toInteger = __sp.toInt;
/*************************************
/* Private Functions
/*************************************/
function getNativeStringProperties() {
var names = getNativeStringPropertyNames();
var retObj = {};
for (var i = 0; i < names.length; ++i) {
var name = names[i];
var func = __nsp[name];
try {
var type = typeof func.apply('teststring', []);
retObj[name] = type;
} catch (e) {}
}
return _results;
};
return retObj;
}
restorePrototype = function() {
var name, _i, _len;
for (_i = 0, _len = methodsAdded.length; _i < _len; _i++) {
name = methodsAdded[_i];
delete String.prototype[name];
function getNativeStringPropertyNames() {
var results = [];
if (Object.getOwnPropertyNames) {
results = Object.getOwnPropertyNames(__nsp);
results.splice(results.indexOf('valueOf'), 1);
results.splice(results.indexOf('toString'), 1);
return results;
} else { //meant for legacy cruft, this could probably be made more efficient
var stringNames = {};
var objectNames = [];
for (var name in String.prototype)
stringNames[name] = name;
for (var name in Object.prototype)
delete stringNames[name];
//stringNames['toString'] = 'toString'; //this was deleted with the rest of the object names
for (var name in stringNames) {
results.push(name);
}
return results;
}
return methodsAdded.length = 0;
}
function wrap(str) {
return new S(str);
};
if (typeof window !== "undefined" && window !== null) {
/*************************************
/* Exports
/*************************************/
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = wrap;
module.exports.clobberPrototype = clobberPrototype;
module.exports.restorePrototype = restorePrototype;
module.exports.VERSION = VERSION
} else {
window.S = wrap;
window.S.clobberPrototype = clobberPrototype;
window.S.restorePrototype = restorePrototype;
} else {
module.exports = wrap;
module.exports.clobberPrototype = clobberPrototype;
module.exports.restorePrototype = restorePrototype;
window.S.VERSION = VERSION;
}
function get_html_translation_table (table, quote_style) {
var entities = {},
hash_map = {},
decimal;
var constMappingTable = {},
constMappingQuoteStyle = {};
var useTable = {},
useQuoteStyle = {};
// Translate arguments
constMappingTable[0] = 'HTML_SPECIALCHARS';
constMappingTable[1] = 'HTML_ENTITIES';
constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
constMappingQuoteStyle[2] = 'ENT_COMPAT';
constMappingQuoteStyle[3] = 'ENT_QUOTES';
/*************************************
/* 3rd Party Private Functions
/*************************************/
useTable = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';
useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT';
if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
throw new Error("Table: " + useTable + ' not supported');
// return false;
//from sugar.js
function multiArgs(args, fn) {
var result = [], i;
for(i = 0; i < args.length; i++) {
result.push(args[i]);
if(fn) fn.call(args, args[i], i);
}
return result;
}
entities['38'] = '&amp;';
if (useTable === 'HTML_ENTITIES') {
entities['160'] = '&nbsp;';
entities['161'] = '&iexcl;';
entities['162'] = '&cent;';
entities['163'] = '&pound;';
entities['164'] = '&curren;';
entities['165'] = '&yen;';
entities['166'] = '&brvbar;';
entities['167'] = '&sect;';
entities['168'] = '&uml;';
entities['169'] = '&copy;';
entities['170'] = '&ordf;';
entities['171'] = '&laquo;';
entities['172'] = '&not;';
entities['173'] = '&shy;';
entities['174'] = '&reg;';
entities['175'] = '&macr;';
entities['176'] = '&deg;';
entities['177'] = '&plusmn;';
entities['178'] = '&sup2;';
entities['179'] = '&sup3;';
entities['180'] = '&acute;';
entities['181'] = '&micro;';
entities['182'] = '&para;';
entities['183'] = '&middot;';
entities['184'] = '&cedil;';
entities['185'] = '&sup1;';
entities['186'] = '&ordm;';
entities['187'] = '&raquo;';
entities['188'] = '&frac14;';
entities['189'] = '&frac12;';
entities['190'] = '&frac34;';
entities['191'] = '&iquest;';
entities['192'] = '&Agrave;';
entities['193'] = '&Aacute;';
entities['194'] = '&Acirc;';
entities['195'] = '&Atilde;';
entities['196'] = '&Auml;';
entities['197'] = '&Aring;';
entities['198'] = '&AElig;';
entities['199'] = '&Ccedil;';
entities['200'] = '&Egrave;';
entities['201'] = '&Eacute;';
entities['202'] = '&Ecirc;';
entities['203'] = '&Euml;';
entities['204'] = '&Igrave;';
entities['205'] = '&Iacute;';
entities['206'] = '&Icirc;';
entities['207'] = '&Iuml;';
entities['208'] = '&ETH;';
entities['209'] = '&Ntilde;';
entities['210'] = '&Ograve;';
entities['211'] = '&Oacute;';
entities['212'] = '&Ocirc;';
entities['213'] = '&Otilde;';
entities['214'] = '&Ouml;';
entities['215'] = '&times;';
entities['216'] = '&Oslash;';
entities['217'] = '&Ugrave;';
entities['218'] = '&Uacute;';
entities['219'] = '&Ucirc;';
entities['220'] = '&Uuml;';
entities['221'] = '&Yacute;';
entities['222'] = '&THORN;';
entities['223'] = '&szlig;';
entities['224'] = '&agrave;';
entities['225'] = '&aacute;';
entities['226'] = '&acirc;';
entities['227'] = '&atilde;';
entities['228'] = '&auml;';
entities['229'] = '&aring;';
entities['230'] = '&aelig;';
entities['231'] = '&ccedil;';
entities['232'] = '&egrave;';
entities['233'] = '&eacute;';
entities['234'] = '&ecirc;';
entities['235'] = '&euml;';
entities['236'] = '&igrave;';
entities['237'] = '&iacute;';
entities['238'] = '&icirc;';
entities['239'] = '&iuml;';
entities['240'] = '&eth;';
entities['241'] = '&ntilde;';
entities['242'] = '&ograve;';
entities['243'] = '&oacute;';
entities['244'] = '&ocirc;';
entities['245'] = '&otilde;';
entities['246'] = '&ouml;';
entities['247'] = '&divide;';
entities['248'] = '&oslash;';
entities['249'] = '&ugrave;';
entities['250'] = '&uacute;';
entities['251'] = '&ucirc;';
entities['252'] = '&uuml;';
entities['253'] = '&yacute;';
entities['254'] = '&thorn;';
entities['255'] = '&yuml;';
}
//from underscore.string
var escapeChars = {
lt: '<',
gt: '>',
quot: '"',
apos: "'",
amp: '&'
};
if (useQuoteStyle !== 'ENT_NOQUOTES') {
entities['34'] = '&quot;';
}
if (useQuoteStyle === 'ENT_QUOTES') {
entities['39'] = '&#39;';
}
entities['60'] = '&lt;';
entities['62'] = '&gt;';
//from underscore.string
var reversedEscapeChars = {};
for(var key in escapeChars){ reversedEscapeChars[escapeChars[key]] = key; }
//from PHP.js
function get_html_translation_table (table, quote_style) {
var entities = {},
hash_map = {},
decimal;
var constMappingTable = {},
constMappingQuoteStyle = {};
var useTable = {},
useQuoteStyle = {};
// ascii decimals to real symbols
for (decimal in entities) {
if (entities.hasOwnProperty(decimal)) {
hash_map[String.fromCharCode(decimal)] = entities[decimal];
}
}
// Translate arguments
constMappingTable[0] = 'HTML_SPECIALCHARS';
constMappingTable[1] = 'HTML_ENTITIES';
constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
constMappingQuoteStyle[2] = 'ENT_COMPAT';
constMappingQuoteStyle[3] = 'ENT_QUOTES';
return hash_map;
}
;
useTable = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';
useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT';
if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
throw new Error("Table: " + useTable + ' not supported');
// return false;
}
entities['38'] = '&amp;';
if (useTable === 'HTML_ENTITIES') {
entities['160'] = '&nbsp;';
entities['161'] = '&iexcl;';
entities['162'] = '&cent;';
entities['163'] = '&pound;';
entities['164'] = '&curren;';
entities['165'] = '&yen;';
entities['166'] = '&brvbar;';
entities['167'] = '&sect;';
entities['168'] = '&uml;';
entities['169'] = '&copy;';
entities['170'] = '&ordf;';
entities['171'] = '&laquo;';
entities['172'] = '&not;';
entities['173'] = '&shy;';
entities['174'] = '&reg;';
entities['175'] = '&macr;';
entities['176'] = '&deg;';
entities['177'] = '&plusmn;';
entities['178'] = '&sup2;';
entities['179'] = '&sup3;';
entities['180'] = '&acute;';
entities['181'] = '&micro;';
entities['182'] = '&para;';
entities['183'] = '&middot;';
entities['184'] = '&cedil;';
entities['185'] = '&sup1;';
entities['186'] = '&ordm;';
entities['187'] = '&raquo;';
entities['188'] = '&frac14;';
entities['189'] = '&frac12;';
entities['190'] = '&frac34;';
entities['191'] = '&iquest;';
entities['192'] = '&Agrave;';
entities['193'] = '&Aacute;';
entities['194'] = '&Acirc;';
entities['195'] = '&Atilde;';
entities['196'] = '&Auml;';
entities['197'] = '&Aring;';
entities['198'] = '&AElig;';
entities['199'] = '&Ccedil;';
entities['200'] = '&Egrave;';
entities['201'] = '&Eacute;';
entities['202'] = '&Ecirc;';
entities['203'] = '&Euml;';
entities['204'] = '&Igrave;';
entities['205'] = '&Iacute;';
entities['206'] = '&Icirc;';
entities['207'] = '&Iuml;';
entities['208'] = '&ETH;';
entities['209'] = '&Ntilde;';
entities['210'] = '&Ograve;';
entities['211'] = '&Oacute;';
entities['212'] = '&Ocirc;';
entities['213'] = '&Otilde;';
entities['214'] = '&Ouml;';
entities['215'] = '&times;';
entities['216'] = '&Oslash;';
entities['217'] = '&Ugrave;';
entities['218'] = '&Uacute;';
entities['219'] = '&Ucirc;';
entities['220'] = '&Uuml;';
entities['221'] = '&Yacute;';
entities['222'] = '&THORN;';
entities['223'] = '&szlig;';
entities['224'] = '&agrave;';
entities['225'] = '&aacute;';
entities['226'] = '&acirc;';
entities['227'] = '&atilde;';
entities['228'] = '&auml;';
entities['229'] = '&aring;';
entities['230'] = '&aelig;';
entities['231'] = '&ccedil;';
entities['232'] = '&egrave;';
entities['233'] = '&eacute;';
entities['234'] = '&ecirc;';
entities['235'] = '&euml;';
entities['236'] = '&igrave;';
entities['237'] = '&iacute;';
entities['238'] = '&icirc;';
entities['239'] = '&iuml;';
entities['240'] = '&eth;';
entities['241'] = '&ntilde;';
entities['242'] = '&ograve;';
entities['243'] = '&oacute;';
entities['244'] = '&ocirc;';
entities['245'] = '&otilde;';
entities['246'] = '&ouml;';
entities['247'] = '&divide;';
entities['248'] = '&oslash;';
entities['249'] = '&ugrave;';
entities['250'] = '&uacute;';
entities['251'] = '&ucirc;';
entities['252'] = '&uuml;';
entities['253'] = '&yacute;';
entities['254'] = '&thorn;';
entities['255'] = '&yuml;';
}
if (useQuoteStyle !== 'ENT_NOQUOTES') {
entities['34'] = '&quot;';
}
if (useQuoteStyle === 'ENT_QUOTES') {
entities['39'] = '&#39;';
}
entities['60'] = '&lt;';
entities['62'] = '&gt;';
// ascii decimals to real symbols
for (decimal in entities) {
if (entities.hasOwnProperty(decimal)) {
hash_map[String.fromCharCode(decimal)] = entities[decimal];
}
}
return hash_map;
};
}).call(this);

@@ -1,2 +0,17 @@

// Generated by CoffeeScript 1.3.3
(function(){function s(e,t){var n={},r={},i,s={},o={},u={},a={};s[0]="HTML_SPECIALCHARS",s[1]="HTML_ENTITIES",o[0]="ENT_NOQUOTES",o[2]="ENT_COMPAT",o[3]="ENT_QUOTES",u=isNaN(e)?e?e.toUpperCase():"HTML_SPECIALCHARS":s[e],a=isNaN(t)?t?t.toUpperCase():"ENT_COMPAT":o[t];if(u!=="HTML_SPECIALCHARS"&&u!=="HTML_ENTITIES")throw new Error("Table: "+u+" not supported");n[38]="&amp;",u==="HTML_ENTITIES"&&(n[160]="&nbsp;",n[161]="&iexcl;",n[162]="&cent;",n[163]="&pound;",n[164]="&curren;",n[165]="&yen;",n[166]="&brvbar;",n[167]="&sect;",n[168]="&uml;",n[169]="&copy;",n[170]="&ordf;",n[171]="&laquo;",n[172]="&not;",n[173]="&shy;",n[174]="&reg;",n[175]="&macr;",n[176]="&deg;",n[177]="&plusmn;",n[178]="&sup2;",n[179]="&sup3;",n[180]="&acute;",n[181]="&micro;",n[182]="&para;",n[183]="&middot;",n[184]="&cedil;",n[185]="&sup1;",n[186]="&ordm;",n[187]="&raquo;",n[188]="&frac14;",n[189]="&frac12;",n[190]="&frac34;",n[191]="&iquest;",n[192]="&Agrave;",n[193]="&Aacute;",n[194]="&Acirc;",n[195]="&Atilde;",n[196]="&Auml;",n[197]="&Aring;",n[198]="&AElig;",n[199]="&Ccedil;",n[200]="&Egrave;",n[201]="&Eacute;",n[202]="&Ecirc;",n[203]="&Euml;",n[204]="&Igrave;",n[205]="&Iacute;",n[206]="&Icirc;",n[207]="&Iuml;",n[208]="&ETH;",n[209]="&Ntilde;",n[210]="&Ograve;",n[211]="&Oacute;",n[212]="&Ocirc;",n[213]="&Otilde;",n[214]="&Ouml;",n[215]="&times;",n[216]="&Oslash;",n[217]="&Ugrave;",n[218]="&Uacute;",n[219]="&Ucirc;",n[220]="&Uuml;",n[221]="&Yacute;",n[222]="&THORN;",n[223]="&szlig;",n[224]="&agrave;",n[225]="&aacute;",n[226]="&acirc;",n[227]="&atilde;",n[228]="&auml;",n[229]="&aring;",n[230]="&aelig;",n[231]="&ccedil;",n[232]="&egrave;",n[233]="&eacute;",n[234]="&ecirc;",n[235]="&euml;",n[236]="&igrave;",n[237]="&iacute;",n[238]="&icirc;",n[239]="&iuml;",n[240]="&eth;",n[241]="&ntilde;",n[242]="&ograve;",n[243]="&oacute;",n[244]="&ocirc;",n[245]="&otilde;",n[246]="&ouml;",n[247]="&divide;",n[248]="&oslash;",n[249]="&ugrave;",n[250]="&uacute;",n[251]="&ucirc;",n[252]="&uuml;",n[253]="&yacute;",n[254]="&thorn;",n[255]="&yuml;"),a!=="ENT_NOQUOTES"&&(n[34]="&quot;"),a==="ENT_QUOTES"&&(n[39]="&#39;"),n[60]="&lt;",n[62]="&gt;";for(i in n)n.hasOwnProperty(i)&&(r[String.fromCharCode(i)]=n[i]);return r}var e,t,n,r,i;e=function(){function e(e){this.s=e,this.s==null&&(this.s=this)}return e.prototype.camelize=function(){var t;return t=this.trim().s.replace(/(\-|_|\s)+(.)?/g,function(e,t,n){return n?n.toUpperCase():""}),new e(t)},e.prototype.capitalize=function(){return new e(this.s.substr(0,1).toUpperCase()+this.s.substring(1).toLowerCase())},e.prototype.collapseWhitespace=function(){var t;return t=this.s.replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,""),new e(t)},e.prototype.contains=function(e){return this.s.indexOf(e)>=0},e.prototype.dasherize=function(){var t;return t=this.trim().s.replace(/[_\s]+/g,"-").replace(/([A-Z])/g,"-$1").replace(/-+/g,"-").toLowerCase(),new e(t)},e.prototype.decodeHtmlEntities=function(t){var n,r,i,o;r={},i=n="",o=this.s;if(!1===(r=s("HTML_ENTITIES",t)))return!1;delete r["&"],r["&"]="&amp;";for(i in r)n=r[i],o=o.split(n).join(i);return o=o.split("&#039;").join("'"),new e(o)},e.prototype.endsWith=function(e){var t;return t=this.s.length-e.length,t>=0&&this.s.indexOf(e,t)===t},e.prototype.isAlpha=function(){return!/[^a-zA-Z]/.test(this.s)},e.prototype.isAlphaNumeric=function(){return!/[^a-zA-Z0-9]/.test(this.s)},e.prototype.isEmpty=function(){return/^[\s\xa0]*$/.test(this.s)},e.prototype.isLower=function(){return!/[^a-z]/.test(this.s)},e.prototype.isNumeric=function(){return!/[^0-9]/.test(this.s)},e.prototype.isUpper=function(){return!/[^A-Z]/.test(this.s)},e.prototype.left=function(t){var n;return t>=0?(n=this.s.substr(0,t),new e(n)):this.right(-t)},e.prototype.ltrim=function(){var t;return t=this.s.replace(/(^\s*)/g,""),new e(t)},e.prototype.replaceAll=function(t,n){var r;return r=this.s.replace(new RegExp(t,"g"),n),new e(r)},e.prototype.right=function(t){var n;return t>=0?(n=this.s.substr(this.s.length-t,t),new e(n)):this.left(-t)},e.prototype.rtrim=function(){var t;return t=this.s.replace(/\s+$/,""),new e(t)},e.prototype.startsWith=function(e){return this.s.lastIndexOf(e,0)===0},e.prototype.times=function(t){return new e((new Array(t+1)).join(this.s))},e.prototype.trim=function(){var t;return typeof String.prototype.trim=="undefined"?t=this.s.replace(/(^\s*|\s*$)/g,""):t=this.s.trim(),new e(t)},e.prototype.toString=function(){return this.s},e.prototype.underscore=function(){var t;return t=this.trim().s.replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase(),(new e(this.s.charAt(0))).isUpper()&&(t="_"+t),new e(t)},e.prototype.repeat=e.prototype.times,e.prototype.include=e.prototype.contains,e}(),i=function(t){return new e(t)},n=[],t=function(){var t,r,i,s;i=new e,s=[];for(r in i)t=i[r],String.prototype.hasOwnProperty(r)?s.push(void 0):(n.push(r),s.push(String.prototype[r]=function(){return String.prototype.s=this,t.apply(this,arguments)}));return s},r=function(){var e,t,r;for(t=0,r=n.length;t<r;t++)e=n[t],delete String.prototype[e];return n.length=0},typeof window!="undefined"&&window!==null?(window.S=i,window.S.clobberPrototype=t,window.S.restorePrototype=r):(module.exports=i,module.exports.clobberPrototype=t,module.exports.restorePrototype=r)}).call(this);
/*
string.js - Copyright (C) 2012, JP Richardson <jprichardson@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is furnished to
do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/(function(){"use strict";function t(e){e!==null&&e!==undefined?typeof e=="string"?this.s=e:(this.s=e.toString(),this.orig=e):this.s=e,e!==null&&e!==undefined?this.__defineGetter__?this.__defineGetter__("length",function(){return this.s.length}):this.length=e.length:this.length=-1}function s(){for(var e in r)(function(e){var t=r[e];n.hasOwnProperty(e)||(i.push(e),n[e]=function(){return String.prototype.s=this,t.apply(this,arguments)})})(e)}function o(){for(var e=0;e<i.length;++e)delete String.prototype[i[e]];i.length=0}function f(){var e=l(),t={};for(var r=0;r<e.length;++r){var i=e[r],s=n[i];try{var o=typeof s.apply("teststring",[]);t[i]=o}catch(u){}}return t}function l(){var e=[];if(Object.getOwnPropertyNames)return e=Object.getOwnPropertyNames(n),e.splice(e.indexOf("valueOf"),1),e.splice(e.indexOf("toString"),1),e;var t={},r=[];for(var i in String.prototype)t[i]=i;for(var i in Object.prototype)delete t[i];for(var i in t)e.push(i);return e}function c(e){return new t(e)}function h(e,t){var n=[],r;for(r=0;r<e.length;r++)n.push(e[r]),t&&t.call(e,e[r],r);return n}function m(e,t){var n={},r={},i,s={},o={},u={},a={};s[0]="HTML_SPECIALCHARS",s[1]="HTML_ENTITIES",o[0]="ENT_NOQUOTES",o[2]="ENT_COMPAT",o[3]="ENT_QUOTES",u=isNaN(e)?e?e.toUpperCase():"HTML_SPECIALCHARS":s[e],a=isNaN(t)?t?t.toUpperCase():"ENT_COMPAT":o[t];if(u!=="HTML_SPECIALCHARS"&&u!=="HTML_ENTITIES")throw new Error("Table: "+u+" not supported");n[38]="&amp;",u==="HTML_ENTITIES"&&(n[160]="&nbsp;",n[161]="&iexcl;",n[162]="&cent;",n[163]="&pound;",n[164]="&curren;",n[165]="&yen;",n[166]="&brvbar;",n[167]="&sect;",n[168]="&uml;",n[169]="&copy;",n[170]="&ordf;",n[171]="&laquo;",n[172]="&not;",n[173]="&shy;",n[174]="&reg;",n[175]="&macr;",n[176]="&deg;",n[177]="&plusmn;",n[178]="&sup2;",n[179]="&sup3;",n[180]="&acute;",n[181]="&micro;",n[182]="&para;",n[183]="&middot;",n[184]="&cedil;",n[185]="&sup1;",n[186]="&ordm;",n[187]="&raquo;",n[188]="&frac14;",n[189]="&frac12;",n[190]="&frac34;",n[191]="&iquest;",n[192]="&Agrave;",n[193]="&Aacute;",n[194]="&Acirc;",n[195]="&Atilde;",n[196]="&Auml;",n[197]="&Aring;",n[198]="&AElig;",n[199]="&Ccedil;",n[200]="&Egrave;",n[201]="&Eacute;",n[202]="&Ecirc;",n[203]="&Euml;",n[204]="&Igrave;",n[205]="&Iacute;",n[206]="&Icirc;",n[207]="&Iuml;",n[208]="&ETH;",n[209]="&Ntilde;",n[210]="&Ograve;",n[211]="&Oacute;",n[212]="&Ocirc;",n[213]="&Otilde;",n[214]="&Ouml;",n[215]="&times;",n[216]="&Oslash;",n[217]="&Ugrave;",n[218]="&Uacute;",n[219]="&Ucirc;",n[220]="&Uuml;",n[221]="&Yacute;",n[222]="&THORN;",n[223]="&szlig;",n[224]="&agrave;",n[225]="&aacute;",n[226]="&acirc;",n[227]="&atilde;",n[228]="&auml;",n[229]="&aring;",n[230]="&aelig;",n[231]="&ccedil;",n[232]="&egrave;",n[233]="&eacute;",n[234]="&ecirc;",n[235]="&euml;",n[236]="&igrave;",n[237]="&iacute;",n[238]="&icirc;",n[239]="&iuml;",n[240]="&eth;",n[241]="&ntilde;",n[242]="&ograve;",n[243]="&oacute;",n[244]="&ocirc;",n[245]="&otilde;",n[246]="&ouml;",n[247]="&divide;",n[248]="&oslash;",n[249]="&ugrave;",n[250]="&uacute;",n[251]="&ucirc;",n[252]="&uuml;",n[253]="&yacute;",n[254]="&thorn;",n[255]="&yuml;"),a!=="ENT_NOQUOTES"&&(n[34]="&quot;"),a==="ENT_QUOTES"&&(n[39]="&#39;"),n[60]="&lt;",n[62]="&gt;";for(i in n)n.hasOwnProperty(i)&&(r[String.fromCharCode(i)]=n[i]);return r}var e="1.0.0",n=String.prototype,r=t.prototype={camelize:function(){var e=this.trim().s.replace(/(\-|_|\s)+(.)?/g,function(e,t,n){return n?n.toUpperCase():""});return new t(e)},capitalize:function(){return new t(this.s.substr(0,1).toUpperCase()+this.s.substring(1).toLowerCase())},charAt:function(e){return this.s.charAt(e)},collapseWhitespace:function(){var e=this.s.replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"");return new t(e)},contains:function(e){return this.s.indexOf(e)>=0},dasherize:function(){var e=this.trim().s.replace(/[_\s]+/g,"-").replace(/([A-Z])/g,"-$1").replace(/-+/g,"-").toLowerCase();return new t(e)},decodeHtmlEntities:function(e){var n="",r="",i={},s=this.s;if(!1===(i=m("HTML_ENTITIES",e)))return!1;delete i["&"],i["&"]="&amp;";for(n in i)r=i[n],s=s.split(r).join(n);return s=s.split("&#039;").join("'"),new t(s)},endsWith:function(e){var t=this.s.length-e.length;return t>=0&&this.s.indexOf(e,t)===t},escapeHTML:function(){return new t(this.s.replace(/[&<>"']/g,function(e){return"&"+d[e]+";"}))},isAlpha:function(){return!/[^a-zA-Z]/.test(this.s)},isAlphaNumeric:function(){return!/[^a-zA-Z0-9]/.test(this.s)},isEmpty:function(){return this.s===null||this.s===undefined?!0:/^[\s\xa0]*$/.test(this.s)},isLower:function(){return!/[^a-z]/.test(this.s)},isNumeric:function(){return!/[^0-9]/.test(this.s)},isUpper:function(){return!/[^A-Z]/.test(this.s)},left:function(e){if(e>=0){var n=this.s.substr(0,e);return new t(n)}return this.right(-e)},lines:function(){var e=this.s.split("\n");for(var t=0;t<e.length;++t)e[t]=e[t].replace(/(^\s*|\s*$)/g,"");return e},parseCSV:function(e,t){e=e||",",escape="\\",typeof t=="undefined"&&(t='"');var n=0,r=[],i=[],s=this.s.length,o=!1,u=this,a=function(e){return u.s.charAt(e)};t||(o=!0);while(n<s){var f=a(n);switch(f){case t:o?a(n-1)===escape?r.push(f):o=!1:o=!0;break;case e:o&&t?r.push(f):(i.push(r.join("")),r.length=0);break;case escape:t&&a(n+1)!==t&&r.push(f);break;default:o&&r.push(f)}n+=1}return i.push(r.join("")),i},replaceAll:function(e,n){var r=this.s.replace(new RegExp(e,"g"),n);return new t(r)},right:function(e){if(e>=0){var n=this.s.substr(this.s.length-e,e);return new t(n)}return this.left(-e)},slugify:function(){var e=(new t(this.s.replace(/[^\w\s-]/g,""))).dasherize().s;return e.charAt(0)==="-"&&(e=e.substr(1)),new t(e)},startsWith:function(e){return this.s.lastIndexOf(e,0)===0},stripTags:function(){var e=this.s,n=arguments.length>0?arguments:[""];return h(n,function(t){e=e.replace(RegExp("</?"+t+"[^<>]*>","gi"),"")}),new t(e)},times:function(e){return new t((new Array(e+1)).join(this.s))},toFloat:function(e){var t=parseFloat(this.s,10);return e?parseFloat(t.toFixed(e)):t},toInt:function(){return/^\s*-?0x/i.test(this.s)?parseInt(this.s,16):parseInt(this.s,10)},trim:function(){var e;return typeof String.prototype.trim=="undefined"?e=this.s.replace(/(^\s*|\s*$)/g,""):e=this.s.trim(),new t(e)},trimLeft:function(){var e;return n.trimLeft?e=this.s.trimLeft():e=this.s.replace(/(^\s*)/g,""),new t(e)},trimRight:function(){var e;return n.trimRight?e=this.s.trimRight():e=this.s.replace(/\s+$/,""),new t(e)},truncate:function(e,n){var r=this.s;e=~~e,n=n||"...";if(r.length<=e)return r;var i=function(e){return e.toUpperCase()!==e.toLowerCase()?"A":" "},s=r.slice(0,e+1).replace(/.(?=\W*\w*$)/g,i);return s.slice(s.length-2).match(/\w\w/)?s=s.replace(/\s*\S+$/,""):s=(new t(s.slice(0,s.length-1))).trimRight().s,(s+n).length>r.length?new t(r):new t(r.slice(0,s.length)+n)},toCSV:function(){function u(e){return e!==null&&e!==""}var e=",",n='"',r="\\",i=!0,s=!1,o=[];typeof arguments[0]=="object"?(e=arguments[0].delimiter||e,e=arguments[0].separator||e,n=arguments[0].qualifier||n,i=!!arguments[0].encloseNumbers,r=arguments[0].escapeChar||r,s=!!arguments[0].keys):typeof arguments[0]=="string"&&(e=arguments[0]),typeof arguments[1]=="string"&&(n=arguments[1]),arguments[1]===null&&(n=null);if(this.orig instanceof Array)o=this.orig;else for(var a in this.orig)this.orig.hasOwnProperty(a)&&(s?o.push(a):o.push(this.orig[a]));var f=r+n,l=[];for(var c=0;c<o.length;++c){var h=u(n);typeof o[c]=="number"&&(h&=i),h&&l.push(n);var p=(new t(o[c])).replaceAll(n,f).s;l.push(p),h&&l.push(n),e&&l.push(e)}return l.length=l.length-1,new t(l.join(""))},toString:function(){return this.s},underscore:function(){var e=this.trim().s.replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase();return(new t(this.s.charAt(0))).isUpper()&&(e="_"+e),new t(e)},unescapeHTML:function(){return new t(this.s.replace(/\&([^;]+);/g,function(e,t){var n;return t in p?p[t]:(n=t.match(/^#x([\da-fA-F]+)$/))?String.fromCharCode(parseInt(n[1],16)):(n=t.match(/^#(\d+)$/))?String.fromCharCode(~~n[1]):e}))},valueOf:function(){return this.s.valueOf()}},i=[],u=f();for(var a in u)(function(e){var i=n[e];typeof i=="function"&&(r[e]||(u[e]==="string"?r[e]=function(){return new t(i.apply(this,arguments))}:r[e]=i))})(a);r.repeat=r.times,r.include=r.contains,r.toInteger=r.toInt,module&&module.exports?(module.exports=c,module.exports.clobberPrototype=s,module.exports.restorePrototype=o,module.exports.VERSION=e):(window.S=c,window.S.clobberPrototype=s,window.S.restorePrototype=o,window.S.VERSION=e);var p={lt:"<",gt:">",quot:'"',apos:"'",amp:"&"},d={};for(var v in p)d[p[v]]=v}).call(this);
{
"name": "string",
"version": "0.2.2",
"description": "string contains methods that aren't included in the vanilla JavaScript string.",
"homepage": [
"http://stringjs.com"
],
"repository": {
"type": "git",
"url": "https://github.com/jprichardson/string.js"
},
"keywords": ["string","strings", "string.js", "stringjs", "S", "s"],
"author": "JP Richardson <jprichardson@gmail.com>",
"licenses":[{
"type" : "MIT,Apache v2,LGPL"
}],
"dependencies": {},
"devDependencies": {
"coffee-script" : "1.3.x",
"mocha": "*",
"uglify-js": "1.2.x",
"growl": "1.5.x"
},
"main": "lib/string.js"
"name": "string",
"version": "1.0.0",
"description": "string contains methods that aren't included in the vanilla JavaScript string.",
"homepage": [
"http://stringjs.com"
],
"repository": {
"type": "git",
"url": "https://github.com/jprichardson/string.js"
},
"keywords": [
"string",
"strings",
"string.js",
"stringjs",
"S",
"s",
"csv",
"html",
"entities",
"parse"
],
"author": "JP Richardson <jprichardson@gmail.com>",
"licenses": [
{
"type": "MIT"
}
],
"dependencies": {},
"devDependencies": {
"mocha": "*",
"uglify-js": "1.3.x"
},
"main": "lib/string",
"scripts": {
"test": "mocha test"
}
}
+280
-40
[string.js](http://stringjs.com)
=========
`string.js`, or simply `S` is a lightweight (< 2k Gzipped) JavaScript library for the browser or for Node.js that provides extra String methods. Originally, it modified the String prototype. But I quickly learned that in JavaScript, this is considered poor practice.
[![build status](https://secure.travis-ci.org/jprichardson/string.js.png)](http://travis-ci.org/jprichardson/string.js)
`string.js`, or simply `S` is a lightweight (< 4k minified and gzipped) JavaScript library for the browser or for Node.js that provides extra String methods. Originally, it modified the String prototype. But I quickly learned that in JavaScript, this is considered poor practice.
Motivation
----------
Personally, I prefer the cleanliness of the way code looks when it appears to be native methods. i.e. when you modify native Javascript prototypes. However, if any app dependency required `string.js`, then the app's string prototype in every module would be modified as well. This could be troublesome. So I settled on creating a wrapper a la jQuery style. For those of you prototype hatin' fools, such as myself, there is the method `clobberPrototype()`.
Why?
----
Personally, I prefer the cleanliness of the way code looks when it appears to be native methods. i.e. when you modify native JavaScript prototypes. However, if any app dependency required `string.js`, then the app's string prototype would be modified in every module. This could be troublesome. So I settled on creating a wrapper a la jQuery style. For those of you prototype hatin' fools, there is the method `clobberPrototype()`.
Here's a list of alternative frameworks:

@@ -29,3 +31,3 @@

npm install --production string
npm install string

@@ -90,10 +92,46 @@

### Browser Compatiblity
`string.js` has been designed to be compatible with Node.js and with IE6+, Firefox 3+, Safari 2+, Chrome 3+. Please [click here][browsertest] to run the tests in your browser. Report any browser issues here: https://github.com/jprichardson/string.js/issues
Native JavaScript Methods
-------------------------
`string.js` imports all of the native JavaScript methods. This is for convenience. The only difference is that the imported methods return `string.js` objects instead of native JavaScript strings. The one exception to this is the method `charAt(index)`. This is because `charAt()` only returns a string of length one. This is typically done for comparisons and a `string.js` object will have little to no value here.
All of the native methods support chaining with the `string.js` methods.
**Example:**
```javascript
var S = require('string');
var phrase = S('JavaScript is the best scripting language ever!');
var sub = 'best scripting';
var pos = phrase.indexOf(sub);
console.log(phrase.substr(pos, sub.length).truncate(8)); //best...
```
Methods
-------
See [test file][1] for more details.
See [test file][testfile] for more details.
I use the same nomenclature as Objective-C regarding methods. **+** means `static` or `class` method. **-** means `non-static` or `instance` method.
### - constructor(nativeJsString) ###
This creates a new `string.js` object. The parameter can be anything. The `toString()` method will be called on any objects. Some native objects are used in some functions such as `toCSV()`.
Example:
```javascript
S('hello').s //'hello'
S(['a,b']).s //"['a','b']"
S({hi: 'jp'}).s //[object Object]
```
### - camelize()

@@ -196,2 +234,13 @@

### - escapeHTML() ###
Escapes the html.
Example:
```javascript
S('<div>hi</div>').escapeHTML().s; //&lt;div&gt;hi&lt;/div&gt;
```
### - include(ss) ###

@@ -243,3 +292,3 @@

Return true if the string is solely composed of whitespace
Return true if the string is solely composed of whitespace or is `null`/`undefined`.

@@ -252,2 +301,5 @@ Example:

S('\n\n ').isEmpty(); //true
S('helo').isEmpty(); //false
S(null).isEmpty(); //true
S(undefined).isEmpty(); //true
```

@@ -307,5 +359,5 @@

### - ltrim() ###
### - left(n) ###
Return the string with leading and whitespace removed
Return the substring denoted by `n` positive left-most characters.

@@ -315,9 +367,11 @@ Example:

```javascript
S(' How are you?').ltrim().s; //'How are you?';
S('My name is JP').left(2).s; //'My'
S('Hi').left(0).s; //''
S('My name is JP').left(-2).s; //'JP', same as right(2)
```
### - left(n) ###
### - length ###
Return the substring denoted by `n` positive left-most characters.
Property to return the length of the string object.

@@ -327,8 +381,41 @@ Example:

```javascript
S('My name is JP').left(2).s; //'My'
S('Hi').left(0).s; //''
S('My name is JP').left(-2).s; //'JP', same as right(2)
S('hi').length; //2
```
### - lines()
Returns an array of native strings representing lines with whitespace trimmed.
Example:
```javacript
var lines = S('1 Infinite Loop\r\nCupertino, CA').lines();
lines[0] // '1 Infinite Loop'
lines[1] // 'Cupertino, CA'
```
### - parseCSV() ###
Parses a CSV line into an array.
**Arguments:**
- `delimiter`: The character that is separates or delimits fields. Default: `,`
- `qualifier`: The character that encloses fields. Default: `"`
Example:
```javascript
S("'a','b','c'").parseCSV(',', "'") //['a', 'b', 'c'])
S('"a","b","c"').parseCSV() // ['a', 'b', 'c'])
S('a,b,c').parseCSV(',', null) //['a', 'b', 'c'])
S("'a,','b','c'").parseCSV(',', "'") //['a,', 'b', 'c'])
S('"a","b",4,"c"').parseCSV(',', null) //['"a"', '"b"', '4', '"c"'])
S('"a","b","4","c"').parseCSV() //['a', 'b', '4', 'c'])
S('"a","b", "4","c"').parseCSV() //['a', 'b', '4', 'c'])
S('"a","b", 4,"c"').parseCSV(",", null) //[ '"a"', '"b"', ' 4', '"c"' ])
S('"a","b\\"","d","c"').parseCSV() //['a', 'b"', 'd', 'c'])
```
### - repeat(n) ###

@@ -385,13 +472,2 @@

### - rtrim() ###
Return the string with trailing whitespace removed.
Example:
```javascript
S('How are you? ').rtrim().s; //'How are you?';
```
### - s ###

@@ -412,2 +488,11 @@

### - slugify() ###
Converts the text into a valid url slug
```javascript
S('Global Thermonuclear Warfare').slugify().s // 'global-thermonuclear-warfare'
```
### - startsWith(prefix) ###

@@ -425,2 +510,14 @@

### - stripTags([tag1],[tag2],...) ###
Strip all of the HTML tags or tags specified by the parameters.
Example:
```javascript
S('<p>just <b>some</b> text</p>').stripTags().s //'just some text'
S('<p>just <b>some</b> text</p>').stripTags('p').s //'just <b>some</b> text'
```
### - times(n) ###

@@ -440,2 +537,82 @@

### - toCSV(options) ###
Converts an array or object to a CSV line.
You can either optionally pass in two string arguments or pass in a configuration object.
**String Arguments:**
- `delimiter`: The character that is separates or delimits fields. Default: `,`
- `qualifier`: The character that encloses fields. Default: `"`
**Object Configuration:**
- `delimiter`: The character that is separates or delimits fields. Default: `,`
- `qualifier`: The character that encloses fields. Default: `"`
- `escape`: The character that escapes any incline `qualifier` characters. Default: `\`, in JS this is `\\`
- `encloseNumbers`: Enclose number objects with the `qualifier` chracter. Default: `true`
- `keys`: If the input isn't an array, but an object, then if this is set to true, the keys will be output to the CSV line, otherwise it's the object's values. Default: `false`.
Example:
```javascript
S(['a', 'b', 'c']).toCSV().s //'"a","b","c"'
S(['a', 'b', 'c']).toCSV(':').s //'"a":"b":"c"'
S(['a', 'b', 'c']).toCSV(':', null).s //'a:b:c')
S(['a', 'b', 'c']).toCSV('*', "'").s //"'a'*'b'*'c'"
S(['a"', 'b', 4, 'c']).toCSV({delimiter: ',', qualifier: '"', escape: '\\', encloseNumbers: false}).s //'"a\\"","b",4,"c"'
S({firstName: 'JP', lastName: 'Richardson'}).toCSV({keys: true}).s //'"firstName","lastName"'
S({firstName: 'JP', lastName: 'Richardson'}).toCSV().s //'"JP","Richardson"'
```
### - toInt() ###
Return the number value in integer form. Wrapper for `parseInt()`. Can also parse hex values.
Example:
```javascript
S('5').toInt(); //5
S('5.3').toInt(); //5;
S(5.3).toInt(); //5;
S('-10').toInt(); //-10
S('55 adfafaf').toInt(); //55
S('afff 44').toInt(); //NaN
S('0xff').toInt() //255
```
### - toFloat([precision]) ###
Return the float value, wraps parseFloat.
Example:
```javascript
S('5').toFloat() // 5
S('5.3').toFloat() //5.3
S(5.3).toFloat() //5.3
S('-10').toFloat() //-10
S('55.3 adfafaf').toFloat() // 55.3
S('afff 44').toFloat() //NaN
S(3.45522222333232).toFloat(2) // 3.46
```
### - toString() ###
Alias: `s`
Return the string representation of an `S` object. Not really necessary to use. However, JS engines will look at an object and display its `toString()` result.
Example:
```javascript
S('my name is JP.').capitalize().toString(); //My name is JP.
var a = "Hello " + S('joe!'); //a = "Hello joe!"
S("Hello").toString() === S("Hello").s; //true
```
### - trim() ###

@@ -456,17 +633,41 @@

### - toString() ###
### - trimLeft() ###
Alias: `s`
Return the string with leading and whitespace removed
Return the string representation of an `S` object. Not really necessary to use. However, JS engines will look at an object and display its `toString()` result.
Example:
```javascript
S(' How are you?').trimLeft().s; //'How are you?';
```
### - trimRight() ###
Return the string with trailing whitespace removed.
Example:
```javascript
S('my name is JP.').capitalize().toString(); //My name is JP.
var a = "Hello " + S('joe!'); //a = "Hello joe!"
S("Hello").toString() === S("Hello").s; //true
S('How are you? ').trimRight().s; //'How are you?';
```
### - truncate(length, [chars]) ###
Truncates the string, accounting for word placement and character count.
Example:
```javascript
S('this is some long text').truncate(3).s //'...'
S('this is some long text').truncate(7).s //'this is...'
S('this is some long text').truncate(11).s //'this is...'
S('this is some long text').truncate(12).s //'this is some...'
S('this is some long text').truncate(11).s //'this is...'
S('this is some long text').truncate(14, ' read more').s //'this is some read more'
```
### - underscore()

@@ -485,11 +686,29 @@

### - unescapeHTML() ###
I will definitely add more methods, I'll be adding them on as-needed basis.
Unescapes the html.
Example:
```javascript
S('&lt;div&gt;hi&lt;/div&gt;').unescapeHTML().s; //<div>hi</div>
```
### + VERSION ###
Returns native JavaScript string containing the version of `string.js`.
Example:
```javascript
S.VERSION; //1.0.0
```
Quirks
------
`decodeHtmlEntities()` converts `&nbsp;` to **0x0a** (160) and not **0x20** (20). Most browsers consider 0xa to be whitespace characters, Internet Explorer does not despite it being part of the ECMA standard. Google Closure does a good job of normalizing this behavior. This may need to fixed in `string.js` at some point in time.
`decodeHtmlEntities()` converts `&nbsp;` to **0xa0** (160) and not **0x10** (20). Most browsers consider 0xa0 to be whitespace characters, Internet Explorer does not despite it being part of the ECMA standard. Google Closure does a good job of normalizing this behavior. This may need to fixed in `string.js` at some point in time.

@@ -505,3 +724,3 @@

$ npm install string
$ npm install string --development

@@ -514,3 +733,3 @@ Then navigate to the installed directory:

$ cake test
$ mocha test

@@ -521,3 +740,3 @@

[Click Here](http://stringjs.com/browser.test.html)
[Click here to run the tests in your web browser.][browsertest]

@@ -533,12 +752,33 @@

Author
------
`string.js` was written by [JP Richardson][aboutjp]. You should follow him on Twitter [@jprichardson][twitter]. Also read his coding blog [Procbits][procbits]. If you write software with others, you should checkout [Gitpilot][gitpilot] to make collaboration with Git simple.
License
-------
Triple licensed under MIT/X11, Apache v2, and LGPL. If you use this, pick which one works for you and your software. Attribution is always nice.
Licensed under MIT.
Copyright (C) 2012 JP Richardson <jprichardson@gmail.com>
Copyright (c) 2012 JP Richardson
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
[1]: https://github.com/jprichardson/string.js/blob/master/test/string.test.coffee
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
[testfile]: https://github.com/jprichardson/string.js/blob/master/test/string.test.js
[browsertest]: http://stringjs.com/browser.test.html
[aboutjp]: http://about.me/jprichardson
[twitter]: http://twitter.com/jprichardson
[procbits]: http://procbits.com
[gitpilot]: http://gitpilot.com

Sorry, the diff of this file is not supported yet

class S
constructor: (@s) ->
@s = @ unless @s?
# modified slightly from https://github.com/epeli/underscore.string
camelize: ->
s = @.trim().s.replace /(\-|_|\s)+(.)?/g, (match, sep, c) ->
return (if c then c.toUpperCase() else '')
#s = s.charAt(0).toLowerCase() + s.substring(1)
new S(s)
capitalize: ->
new S(@s.substr(0,1).toUpperCase() + @s.substring(1).toLowerCase())
collapseWhitespace: ->
s = @s.replace(/[\s\xa0]+/g, ' ').replace(/^\s+|\s+$/g, ''); #thanks Google
new S(s)
contains: (ss) ->
@s.indexOf(ss) >= 0
dasherize: -> #modified from https://github.com/epeli/underscore.string
s = @.trim().s.replace(/[_\s]+/g, '-').replace(/([A-Z])/g, '-$1').replace(/-+/g, '-').toLowerCase()
#if (new S(@s.charAt(0))).isUpper() then s = '-' + s
new S(s)
decodeHtmlEntities: (quote_style) -> #modified from php.js
hash_map = {}
symbol = entity = ""
tmp_str = @s
return false if false is (hash_map = get_html_translation_table("HTML_ENTITIES", quote_style))
delete (hash_map["&"])
hash_map["&"] = "&amp;"
for symbol of hash_map
entity = hash_map[symbol]
tmp_str = tmp_str.split(entity).join(symbol)
tmp_str = tmp_str.split("&#039;").join("'")
new S(tmp_str)
endsWith: (suffix) ->
l = @s.length - suffix.length;
l >= 0 && @s.indexOf(suffix, l) == l;
isAlpha: ->
!/[^a-zA-Z]/.test(@s)
isAlphaNumeric: ->
!/[^a-zA-Z0-9]/.test(@s)
isEmpty: ->
/^[\s\xa0]*$/.test(@s)
isLower: ->
!/[^a-z]/.test(@s)
isNumeric: ->
!/[^0-9]/.test(@s)
isUpper: ->
!/[^A-Z]/.test(@s)
left: (N) ->
if N >= 0
s = @s.substr(0,N)
new S(s)
else
@right(-N)
ltrim: ->
s = @s.replace(/(^\s*)/g, '')
new S(s)
replaceAll: (ss, r) ->
s = @s.replace(new RegExp(ss, 'g'), r)
new S(s)
right: (N) ->
if N >= 0
s = @s.substr(@s.length - N, N)
new S(s)
else
@left(-N)
rtrim: ->
s = @s.replace(/\s+$/, '')
new S(s)
startsWith: (prefix) ->
@s.lastIndexOf(prefix, 0) is 0 #Google says this is the fastest
times: (n) ->
new S(new Array(n+1).join(@s))
trim: ->
if typeof String::trim is 'undefined'
s = @s.replace(/(^\s*|\s*$)/g, '')
else
s = @s.trim()
new S(s)
toString: ->
@s
underscore: -> #modified from https://github.com/epeli/underscore.string
s = @.trim().s.replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase()
if (new S(@s.charAt(0))).isUpper() then s = '_' + s
new S(s)
#aliases
repeat: S::.times
include: S::.contains
wrap = (str) ->
new S(str)
methodsAdded = []
clobberPrototype = ->
newS = new S()
for name,func of newS
if !String.prototype.hasOwnProperty(name)
methodsAdded.push(name)
String.prototype[name] = ->
String.prototype.s = @
func.apply(@, arguments)
restorePrototype = ->
for name in methodsAdded
delete String.prototype[name]
methodsAdded.length = 0
if window?
window.S = wrap
window.S.clobberPrototype = clobberPrototype
window.S.restorePrototype = restorePrototype
else
module.exports = wrap
module.exports.clobberPrototype = clobberPrototype
module.exports.restorePrototype = restorePrototype
#eewwwww... i like to minimize line count. TODO: convert to CoffeeScript.
# from php.js
`
function get_html_translation_table (table, quote_style) {
var entities = {},
hash_map = {},
decimal;
var constMappingTable = {},
constMappingQuoteStyle = {};
var useTable = {},
useQuoteStyle = {};
// Translate arguments
constMappingTable[0] = 'HTML_SPECIALCHARS';
constMappingTable[1] = 'HTML_ENTITIES';
constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
constMappingQuoteStyle[2] = 'ENT_COMPAT';
constMappingQuoteStyle[3] = 'ENT_QUOTES';
useTable = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';
useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT';
if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
throw new Error("Table: " + useTable + ' not supported');
// return false;
}
entities['38'] = '&amp;';
if (useTable === 'HTML_ENTITIES') {
entities['160'] = '&nbsp;';
entities['161'] = '&iexcl;';
entities['162'] = '&cent;';
entities['163'] = '&pound;';
entities['164'] = '&curren;';
entities['165'] = '&yen;';
entities['166'] = '&brvbar;';
entities['167'] = '&sect;';
entities['168'] = '&uml;';
entities['169'] = '&copy;';
entities['170'] = '&ordf;';
entities['171'] = '&laquo;';
entities['172'] = '&not;';
entities['173'] = '&shy;';
entities['174'] = '&reg;';
entities['175'] = '&macr;';
entities['176'] = '&deg;';
entities['177'] = '&plusmn;';
entities['178'] = '&sup2;';
entities['179'] = '&sup3;';
entities['180'] = '&acute;';
entities['181'] = '&micro;';
entities['182'] = '&para;';
entities['183'] = '&middot;';
entities['184'] = '&cedil;';
entities['185'] = '&sup1;';
entities['186'] = '&ordm;';
entities['187'] = '&raquo;';
entities['188'] = '&frac14;';
entities['189'] = '&frac12;';
entities['190'] = '&frac34;';
entities['191'] = '&iquest;';
entities['192'] = '&Agrave;';
entities['193'] = '&Aacute;';
entities['194'] = '&Acirc;';
entities['195'] = '&Atilde;';
entities['196'] = '&Auml;';
entities['197'] = '&Aring;';
entities['198'] = '&AElig;';
entities['199'] = '&Ccedil;';
entities['200'] = '&Egrave;';
entities['201'] = '&Eacute;';
entities['202'] = '&Ecirc;';
entities['203'] = '&Euml;';
entities['204'] = '&Igrave;';
entities['205'] = '&Iacute;';
entities['206'] = '&Icirc;';
entities['207'] = '&Iuml;';
entities['208'] = '&ETH;';
entities['209'] = '&Ntilde;';
entities['210'] = '&Ograve;';
entities['211'] = '&Oacute;';
entities['212'] = '&Ocirc;';
entities['213'] = '&Otilde;';
entities['214'] = '&Ouml;';
entities['215'] = '&times;';
entities['216'] = '&Oslash;';
entities['217'] = '&Ugrave;';
entities['218'] = '&Uacute;';
entities['219'] = '&Ucirc;';
entities['220'] = '&Uuml;';
entities['221'] = '&Yacute;';
entities['222'] = '&THORN;';
entities['223'] = '&szlig;';
entities['224'] = '&agrave;';
entities['225'] = '&aacute;';
entities['226'] = '&acirc;';
entities['227'] = '&atilde;';
entities['228'] = '&auml;';
entities['229'] = '&aring;';
entities['230'] = '&aelig;';
entities['231'] = '&ccedil;';
entities['232'] = '&egrave;';
entities['233'] = '&eacute;';
entities['234'] = '&ecirc;';
entities['235'] = '&euml;';
entities['236'] = '&igrave;';
entities['237'] = '&iacute;';
entities['238'] = '&icirc;';
entities['239'] = '&iuml;';
entities['240'] = '&eth;';
entities['241'] = '&ntilde;';
entities['242'] = '&ograve;';
entities['243'] = '&oacute;';
entities['244'] = '&ocirc;';
entities['245'] = '&otilde;';
entities['246'] = '&ouml;';
entities['247'] = '&divide;';
entities['248'] = '&oslash;';
entities['249'] = '&ugrave;';
entities['250'] = '&uacute;';
entities['251'] = '&ucirc;';
entities['252'] = '&uuml;';
entities['253'] = '&yacute;';
entities['254'] = '&thorn;';
entities['255'] = '&yuml;';
}
if (useQuoteStyle !== 'ENT_NOQUOTES') {
entities['34'] = '&quot;';
}
if (useQuoteStyle === 'ENT_QUOTES') {
entities['39'] = '&#39;';
}
entities['60'] = '&lt;';
entities['62'] = '&gt;';
// ascii decimals to real symbols
for (decimal in entities) {
if (entities.hasOwnProperty(decimal)) {
hash_map[String.fromCharCode(decimal)] = entities[decimal];
}
}
return hash_map;
}
`
<html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
<link rel="stylesheet" href="https://raw.github.com/visionmedia/mocha/master/mocha.css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://raw.github.com/visionmedia/mocha/master/mocha.js"></script>
<script src="../lib/string.js"></script>
<script>mocha.setup('bdd')</script>
<script src="string.test.js"></script>
<script>
$(function () {
mocha
.run()
.globals(['S']) // acceptable globals
})
</script>
</head>
<body>
<div id="mocha"></div>
</body>
</html>
// Generated by CoffeeScript 1.3.3
(function() {
var F, S, T;
T = function(v) {
if (!v) {
throw new Error('Should be true.');
}
};
F = function(v) {
if (v) {
throw new Error('Should be false.');
}
};
if (typeof window !== "undefined" && window !== null) {
S = window.S;
} else {
S = require('../lib/string');
}
describe('string.js', function() {
describe('- camelize()', function() {
return it('should remove any underscores or dashes and convert a string into camel casing', function() {
T(S('data_rate').camelize().s === 'dataRate');
T(S('background-color').camelize().s === 'backgroundColor');
T(S('-moz-something').camelize().s === 'MozSomething');
T(S('_car_speed_').camelize().s === 'CarSpeed');
return T(S('yes_we_can').camelize().s === 'yesWeCan');
});
});
describe('- capitalize()', function() {
return it('should capitalize the string', function() {
T(S('jon').capitalize().s === 'Jon');
return T(S('JP').capitalize().s === 'Jp');
});
});
describe('+ clobberPrototype()', function() {
return it('should extend the String prototype with the extra methods', function() {
S.clobberPrototype();
T(" hello!".endsWith('!'));
return S.restorePrototype();
});
});
describe('- collapseWhitespace()', function() {
return it('should convert all adjacent whitespace characters to a single space and trim the ends', function() {
return T(S(' String \t libraries are \n\n\t fun\n! ').collapseWhitespace().s === 'String libraries are fun !');
});
});
describe('- contains(substring)', function() {
return it('should return true if the string contains the specified input string', function() {
T(S('JavaScript is one of the best languages!').contains('one'));
return F(S('What do you think?').contains('YES!'));
});
});
describe('- dasherize()', function() {
return it('should convert a camel cased string into a string delimited by dashes', function() {
T(S('dataRate').dasherize().s === 'data-rate');
T(S('CarSpeed').dasherize().s === '-car-speed');
T(S('yesWeCan').dasherize().s === 'yes-we-can');
return T(S('backgroundColor').dasherize().s === 'background-color');
});
});
describe('- decodeHtmlEntities()', function() {
return it('should decode HTML entities into their proper string representation', function() {
T(S('Ken Thompson &amp; Dennis Ritchie').decodeHtmlEntities().s === 'Ken Thompson & Dennis Ritchie');
return T(S('3 &lt; 4').decodeHtmlEntities().s === '3 < 4');
});
});
describe('- endsWith(suffix)', function() {
return it("should return true if the string ends with the input string", function() {
T(S("hello jon").endsWith('jon'));
F(S('ffffaaa').endsWith('jon'));
T(S("").endsWith(''));
T(S("hi").endsWith(''));
return T(S("hi").endsWith('hi'));
});
});
describe('- include(substring)', function() {
return it('should return true if the string contains the specified input string', function() {
T(S('JavaScript is one of the best languages!').include('one'));
return F(S('What do you think?').include('YES!'));
});
});
describe('- isAlpha()', function() {
return it("should return true if the string contains only letters", function() {
T(S("afaf").isAlpha());
T(S("FJslfjkasfs").isAlpha());
F(S("adflj43faljsdf").isAlpha());
F(S("33").isAlpha());
return F(S("TT....TTTafafetstYY").isAlpha());
});
});
describe('- isAlphaNumeric()', function() {
return it("should return true if the string contains only letters and digits", function() {
T(S("afaf35353afaf").isAlphaNumeric());
T(S("FFFF99fff").isAlphaNumeric());
T(S("99").isAlphaNumeric());
T(S("afff").isAlphaNumeric());
T(S("Infinity").isAlphaNumeric());
F(S("-Infinity").isAlphaNumeric());
F(S("-33").isAlphaNumeric());
return F(S("aaff..").isAlphaNumeric());
});
});
describe('- isEmpty()', function() {
return it('should return true if the string is solely composed of whitespace', function() {
T(S(' ').isEmpty());
T(S('\t\t\t ').isEmpty());
return T(S('\n\n ').isEmpty());
});
});
describe('- isLower()', function() {
return it('should return true if the character or string is lowercase', function() {
T(S('a').isLower());
T(S('z').isLower());
F(S('B').isLower());
T(S('hijp').isLower());
F(S('hi jp').isLower());
return F(S('HelLO').isLower());
});
});
describe('- isNumeric()', function() {
return it("should return true if the string only contains digits, this would not include Infinity or -Infinity", function() {
T(S("3").isNumeric());
F(S("34.22").isNumeric());
F(S("-22.33").isNumeric());
F(S("NaN").isNumeric());
F(S("Infinity").isNumeric());
F(S("-Infinity").isNumeric());
F(S("JP").isNumeric());
F(S("-5").isNumeric());
return T(S("000992424242").isNumeric());
});
});
describe('- isUpper()', function() {
return it('should return true if the character or string is uppercase', function() {
F(S('a').isUpper());
F(S('z').isUpper());
T(S('B').isUpper());
T(S('HIJP').isUpper());
F(S('HI JP').isUpper());
return F(S('HelLO').isUpper());
});
});
describe('- ltrim()', function() {
return it('should return the string with leading whitespace removed', function() {
T(S(' How are you?').ltrim().s === 'How are you?');
return T(S(' JP ').ltrim().s === 'JP ');
});
});
describe('- left(N)', function() {
it('should return the substring denoted by N positive left-most characters', function() {
T(S('My name is JP').left(2).s === 'My');
T(S('Hi').left(0).s === '');
return T(S('Hello').left(1).s === 'H');
});
return it('should return the substring denoted by N negative left-most characters, equivalent to calling right(-N)', function() {
return T(S('My name is JP').left(-2).s === 'JP');
});
});
describe('- repeat(n)', function() {
return it('should return a string with that is concatenated n times', function() {
T(S(' ').repeat(5).s === ' ');
return T(S('*').repeat(3).s === '***');
});
});
describe('- replaceAll(substring, replacement)', function() {
return it('should return the new string with all occurrences of substring replaced with the replacment string', function() {
T(S(' does IT work? ').replaceAll(' ', '_').s === '_does_IT_work?_');
return T(S('Yes it does!').replaceAll(' ', '').s === 'Yesitdoes!');
});
});
describe('+ restorePrototype()', function() {
return it('should restore the original String prototype', function() {
T(typeof ' hi'.endsWith === 'undefined');
S.clobberPrototype();
T(' hi'.endsWith('hi'));
S.restorePrototype();
return T(typeof ' hi'.endsWith === 'undefined');
});
});
describe('- right(N)', function() {
it('should return the substring denoted by N positive right-most characters', function() {
T(S('I AM CRAZY').right(2).s === 'ZY');
T(S('Does it work? ').right(4).s === 'k? ');
return T(S('Hi').right(0).s === '');
});
return it('should return the substring denoted by N negative right-most characters, equivalent to calling left(-N)', function() {
return T(S('My name is JP').right(-2).s === 'My');
});
});
describe('- rtrim()', function() {
return it('should return the string with trailing whitespace removed', function() {
T(S('How are you? ').rtrim().s === 'How are you?');
return T(S(' JP ').rtrim().s === ' JP');
});
});
describe('- s', function() {
return it('should return the native string', function() {
T(S('hi').s === 'hi');
return T(S('hi').toString() === S('hi').s);
});
});
describe('- startsWith(prefix)', function() {
return it("should return true if the string starts with the input string", function() {
T(S("JP is a software engineer").startsWith("JP"));
F(S('wants to change the world').startsWith("politicians"));
T(S("").startsWith(""));
T(S("Hi").startsWith(""));
return T(S("JP").startsWith("JP"));
});
});
describe('- times(n)', function() {
return it('should return a string with that is concatenated n times', function() {
T(S(' ').times(5).s === ' ');
return T(S('*').times(3).s === '***');
});
});
describe('- toString()', function() {
return it('should return the native string', function() {
T(S('hi').toString() === 'hi');
return T(S('hi').toString() === S('hi').s);
});
});
describe('- trim()', function() {
return it('should return the string with leading and trailing whitespace removed', function() {
T(S('hello ').trim().s === 'hello');
T(S(' hello ').trim().s === 'hello');
T(S('\nhello').trim().s === 'hello');
T(S('\nhello\r\n').trim().s === 'hello');
return T(S('\thello\t').trim().s === 'hello');
});
});
return describe('- underscore()', function() {
return it('should convert a camel cased string into a string separated by underscores', function() {
T(S('dataRate').underscore().s === 'data_rate');
T(S('CarSpeed').underscore().s === '_car_speed');
return T(S('yesWeCan').underscore().s === 'yes_we_can');
});
});
});
}).call(this);
T = (v) -> if !v then throw new Error('Should be true.')
F = (v) -> if v then throw new Error('Should be false.')
if window?
S = window.S
else
S = require('../lib/string')
describe 'string.js', ->
describe '- camelize()', ->
it 'should remove any underscores or dashes and convert a string into camel casing', ->
T S('data_rate').camelize().s is 'dataRate'
T S('background-color').camelize().s is 'backgroundColor'
T S('-moz-something').camelize().s is 'MozSomething'
T S('_car_speed_').camelize().s is 'CarSpeed'
T S('yes_we_can').camelize().s is 'yesWeCan'
describe '- capitalize()', ->
it 'should capitalize the string', ->
T S('jon').capitalize().s is 'Jon'
T S('JP').capitalize().s is 'Jp'
describe '+ clobberPrototype()', ->
it 'should extend the String prototype with the extra methods', ->
S.clobberPrototype()
T " hello!".endsWith('!')
S.restorePrototype()
describe '- collapseWhitespace()', ->
it 'should convert all adjacent whitespace characters to a single space and trim the ends', ->
T S(' String \t libraries are \n\n\t fun\n! ').collapseWhitespace().s is 'String libraries are fun !'
describe '- contains(substring)', ->
it 'should return true if the string contains the specified input string', ->
T S('JavaScript is one of the best languages!').contains('one')
F S('What do you think?').contains('YES!')
describe '- dasherize()', ->
it 'should convert a camel cased string into a string delimited by dashes', ->
T S('dataRate').dasherize().s is 'data-rate'
T S('CarSpeed').dasherize().s is '-car-speed'
T S('yesWeCan').dasherize().s is 'yes-we-can'
T S('backgroundColor').dasherize().s is 'background-color'
describe '- decodeHtmlEntities()', ->
it 'should decode HTML entities into their proper string representation', ->
T S('Ken Thompson &amp; Dennis Ritchie').decodeHtmlEntities().s is 'Ken Thompson & Dennis Ritchie'
T S('3 &lt; 4').decodeHtmlEntities().s is '3 < 4'
describe '- endsWith(suffix)', ->
it "should return true if the string ends with the input string", ->
T S("hello jon").endsWith('jon')
F S('ffffaaa').endsWith('jon')
T S("").endsWith('')
T S("hi").endsWith('')
T S("hi").endsWith('hi')
describe '- include(substring)', ->
it 'should return true if the string contains the specified input string', ->
T S('JavaScript is one of the best languages!').include('one')
F S('What do you think?').include('YES!')
describe '- isAlpha()', ->
it "should return true if the string contains only letters", ->
T S("afaf").isAlpha()
T S("FJslfjkasfs").isAlpha()
F S("adflj43faljsdf").isAlpha()
F S("33").isAlpha()
F S("TT....TTTafafetstYY").isAlpha()
describe '- isAlphaNumeric()', ->
it "should return true if the string contains only letters and digits", ->
T S("afaf35353afaf").isAlphaNumeric()
T S("FFFF99fff").isAlphaNumeric()
T S("99").isAlphaNumeric()
T S("afff").isAlphaNumeric()
T S("Infinity").isAlphaNumeric()
F S("-Infinity").isAlphaNumeric()
F S("-33").isAlphaNumeric()
F S("aaff..").isAlphaNumeric()
describe '- isEmpty()', ->
it 'should return true if the string is solely composed of whitespace', ->
T S(' ').isEmpty()
T S('\t\t\t ').isEmpty()
T S('\n\n ').isEmpty()
describe '- isLower()', ->
it 'should return true if the character or string is lowercase', ->
T S('a').isLower()
T S('z').isLower()
F S('B').isLower()
T S('hijp').isLower()
F S('hi jp').isLower()
F S('HelLO').isLower()
describe '- isNumeric()', ->
it "should return true if the string only contains digits, this would not include Infinity or -Infinity", ->
T S("3").isNumeric()
F S("34.22").isNumeric()
F S("-22.33").isNumeric()
F S("NaN").isNumeric()
F S("Infinity").isNumeric()
F S("-Infinity").isNumeric()
F S("JP").isNumeric()
F S("-5").isNumeric()
T S("000992424242").isNumeric()
describe '- isUpper()', ->
it 'should return true if the character or string is uppercase', ->
F S('a').isUpper()
F S('z').isUpper()
T S('B').isUpper()
T S('HIJP').isUpper()
F S('HI JP').isUpper()
F S('HelLO').isUpper()
describe '- ltrim()', ->
it 'should return the string with leading whitespace removed', ->
T S(' How are you?').ltrim().s is 'How are you?'
T S(' JP ').ltrim().s is 'JP '
describe '- left(N)', ->
it 'should return the substring denoted by N positive left-most characters', ->
T S('My name is JP').left(2).s is 'My'
T S('Hi').left(0).s is ''
T S('Hello').left(1).s is 'H'
it 'should return the substring denoted by N negative left-most characters, equivalent to calling right(-N)', ->
T S('My name is JP').left(-2).s is 'JP' #same as right(-(-2))
describe '- repeat(n)', ->
it 'should return a string with that is concatenated n times', ->
T S(' ').repeat(5).s is ' '
T S('*').repeat(3).s is '***'
describe '- replaceAll(substring, replacement)', ->
it 'should return the new string with all occurrences of substring replaced with the replacment string', ->
T S(' does IT work? ').replaceAll(' ', '_').s is '_does_IT_work?_'
T S('Yes it does!').replaceAll(' ', '').s is 'Yesitdoes!'
describe '+ restorePrototype()', ->
it 'should restore the original String prototype', ->
T typeof ' hi'.endsWith is 'undefined'
S.clobberPrototype()
T ' hi'.endsWith('hi')
S.restorePrototype()
T typeof ' hi'.endsWith is 'undefined'
describe '- right(N)', ->
it 'should return the substring denoted by N positive right-most characters', ->
T S('I AM CRAZY').right(2).s is 'ZY'
T S('Does it work? ').right(4).s is 'k? '
T S('Hi').right(0).s is ''
it 'should return the substring denoted by N negative right-most characters, equivalent to calling left(-N)', ->
T S('My name is JP').right(-2).s is 'My' #same as left(-(-2))
describe '- rtrim()', ->
it 'should return the string with trailing whitespace removed', ->
T S('How are you? ').rtrim().s is 'How are you?'
T S(' JP ').rtrim().s is ' JP'
describe '- s', ->
it 'should return the native string', ->
T S('hi').s is 'hi'
T S('hi').toString() is S('hi').s
describe '- startsWith(prefix)', ->
it "should return true if the string starts with the input string", ->
T S("JP is a software engineer").startsWith("JP")
F S('wants to change the world').startsWith("politicians")
T S("").startsWith("")
T S("Hi").startsWith("")
T S("JP").startsWith("JP")
describe '- times(n)', ->
it 'should return a string with that is concatenated n times', ->
T S(' ').times(5).s is ' '
T S('*').times(3).s is '***'
describe '- toString()', ->
it 'should return the native string', ->
T S('hi').toString() is 'hi'
T S('hi').toString() is S('hi').s
describe '- trim()', ->
it 'should return the string with leading and trailing whitespace removed', ->
T S('hello ').trim().s is 'hello'
T S(' hello ').trim().s is 'hello'
T S('\nhello').trim().s is 'hello'
T S('\nhello\r\n').trim().s is 'hello'
T S('\thello\t').trim().s is 'hello'
describe '- underscore()', ->
it 'should convert a camel cased string into a string separated by underscores', ->
T S('dataRate').underscore().s is 'data_rate'
T S('CarSpeed').underscore().s is '_car_speed'
T S('yesWeCan').underscore().s is 'yes_we_can'

Sorry, the diff of this file is not supported yet