Skip to content

Instantly share code, notes, and snippets.

@whiteinge
Created July 5, 2012 20:10
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whiteinge/3056154 to your computer and use it in GitHub Desktop.
Save whiteinge/3056154 to your computer and use it in GitHub Desktop.
A baseline JS toolbox for new projects
/**
* Allow Prototypal inheritance
* http://javascript.crockford.com/prototypal.html
* @author Douglas Crockford
* @version 2008-04-07
* @param oldObject
* @return newObject
*/
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
/**
* Add some ES5 functions to browsers that don't already have them builtin.
* javascript.crockford.com/remedial.html
*
*/
function typeOf(value) {
var s = typeof value;
if (s === 'object') {
if (value) {
if (typeof value.length === 'number' &&
!(value.propertyIsEnumerable('length')) &&
typeof value.splice === 'function') {
s = 'array';
}
} else {
s = 'null';
}
}
return s;
}
/**
* isEmpty(v) returns true if v is an object containing no enumerable members.
*
*/
if (typeof String.prototype.isEmpty !== 'function') {
function isEmpty(o) {
var i, v;
if (typeOf(o) === 'object') {
for (i in o) {
v = o[i];
if (v !== undefined && typeOf(v) !== 'function') {
return false;
}
}
}
return true;
};
}
/**
* entityify() produces a string in which '<', '>', and '&' are replaced with
* their HTML entity equivalents. This is essential for placing arbitrary
* strings into HTML texts.
*
*/
if (typeof String.prototype.entityify !== 'function') {
String.prototype.entityify = function () {
return this.replace(/&/g, "&amp;").replace(/</g,
"&lt;").replace(/>/g, "&gt;");
};
}
/**
* quote() produces a quoted string. This method returns a string that is like
* the original string except that it is wrapped in quotes and all quote and
* backslash characters are preceded with backslash.
*
*/
if (typeof String.prototype.quote !== 'function') {
String.prototype.quote = function () {
var c, i, l = this.length, o = '"';
for (i = 0; i < l; i += 1) {
c = this.charAt(i);
if (c >= ' ') {
if (c === '\\' || c === '"') {
o += '\\';
}
o += c;
} else {
switch (c) {
case '\b':
o += '\\b';
break;
case '\f':
o += '\\f';
break;
case '\n':
o += '\\n';
break;
case '\r':
o += '\\r';
break;
case '\t':
o += '\\t';
break;
default:
c = c.charCodeAt();
o += '\\u00' + Math.floor(c / 16).toString(16) +
(c % 16).toString(16);
}
}
}
return o + '"';
};
}
/**
* supplant() does variable substitution on the string. It scans through the
* string looking for expressions enclosed in { } braces. If an expression is
* found, use it as a key on the object, and if the key has a string value or
* number value, it is substituted for the bracket expression and it repeats.
*
* @example
* param = {domain: 'valvion.com', media: 'http://media.valvion.com/'};
* url = "{media}logo.gif".supplant(param);
*
*/
if (typeof String.prototype.supplant !== 'function') {
String.prototype.supplant = function (o) {
return this.replace(/{([^{}]*)}/g,
function (a, b) {
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a;
}
);
};
}
/**
* The trim() method removes whitespace characters from the beginning and end
* of the string.
*
*/
if (typeof String.prototype.trim !== 'function') {
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, "");
};
}
// Mixin pattern
// http://javascriptweblog.wordpress.com/2011/05/31/a-fresh-look-at-javascript-mixins/
// var asCircle = function() {
// this.area = function() {
// return Math.PI * this.radius * this.radius;
// };
// this.grow = function() {
// this.radius++;
// };
// this.shrink = function() {
// this.radius--;
// };
// return this;
// };
// var Circle = function(radius) {
// this.radius = radius;
// };
// asCircle.call(Circle.prototype);
// Functional programming constructs
// http://extralogical.net/projects/udon/
Udon = (typeof Udon === 'undefined') ? {} : Udon;
/**
* Returns the result of applying a given function to each element of a list.
*/
Udon.map = function(f, xs) {
var i = xs.length, ys = new Array(i);
while (i--) ys[i] = f(xs[i]);
return ys;
};
/**
* Returns the elements of a list which satisfy some predicate.
*/
Udon.filter = function(f, xs) {
var ys = [], len = xs.length, i, e;
for (i = 0; i < len; i++) {
e = xs[i];
if (f(e)) ys.push(e);
}
return ys;
};
/**
* Adds the elements of a numeric list together.
*/
Udon.sum = function(ns) {
var i = ns.length, t = 0;
while (i--) t += ns[i];
return t;
};
/**
* Multiplies the elements of a numeric list together.
*/
Udon.product = function(ns) {
var i = ns.length, t = 1;
while (i--) t *= ns[i];
return t;
};
/**
* Check whether any element of a list satisfies some predicate.
*
*/
Udon.any = function(p, xs) {
var i = xs.length;
while (i--) {
if (p(xs[i])) return true;
}
return false;
};
/**
* Determine whether all the elements of a list satisfy some predicate.
*/
Udon.all = function(p, xs) {
var i = xs.length;
while (i--) {
if (!p(xs[i])) return false;
}
return true;
};
/**
* Transforms a pair of lists into a list of pairs.
* (Mismatched extra values will be dropped.)
*/
Udon.zip = function(xs, ys) {
return Udon.zipWith(function(x, y) { return [x, y]; }, xs, ys);
};
/**
* The zipWith function is a generalisation of zip: it returns the result of
* applying a function to each pair of elements from two lists.
*/
Udon.zipWith = function(f, xs, ys) {
var xsl = xs.length, ysl = ys.length, i = xsl > ysl ? ysl : xsl,
zs = new Array(i);
while (i--) zs[i] = f(xs[i], ys[i]);
return zs;
};
// Simple JavaScript Templating
// John Resig - http://ejohn.org/ - MIT Licensed
(function(){
var cache = {};
this.tmpl = function tmpl(str, data){
// Figure out if we're getting a template, or if we need to
// load the template - and be sure to cache the result.
var fn = !/\W/.test(str) ?
cache[str] = cache[str] ||
tmpl(document.getElementById(str).innerHTML) :
// Generate a reusable function that will serve as a template
// generator (and which will be cached).
new Function("obj",
"var p=[],print=function(){p.push.apply(p,arguments);};" +
// Introduce the data as local variables using with(){}
"with(obj){p.push('" +
// Convert the template into pure JavaScript
str
.replace(/[\r\t\n]/g, " ")
.split("<%").join("\t")
.replace(/((^|%>)[^\t]*)'/g, "$1\r")
.replace(/\t=(.*?)%>/g, "',$1,'")
.split("\t").join("');")
.split("%>").join("p.push('")
.split("\r").join("\\'")
+ "');}return p.join('');");
// Provide some basic currying to the user
return data ? fn( data ) : fn;
};
})();
// <script type="text/html" id="user_tmpl">
// <% for ( var i = 0; i < users.length; i++ ) { %>
// <li><a href="<%=users[i].url%>"><%=users[i].name%></a></li>
// <% } %>
// </script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment