Created
January 2, 2011 13:55
-
-
Save jaredwilli/762543 to your computer and use it in GitHub Desktop.
a framework in the making
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
// Establish the root object, `window` in the browser, or `global` on the server. | |
var root = window.document; | |
var JL = function( selector, context ) { | |
// The JL object is actually just the init constructor 'enhanced' | |
return new JL.fn.init( selector, context ); | |
}, | |
// A simple way to check for HTML strings or ID strings | |
// (both of which we optimize for) | |
quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/, | |
// Is it a simple selector | |
isSimple = /^.[^:#\[\.,]*$/, | |
// Check if a string has a non-whitespace character in it | |
rnotwhite = /\S/, | |
rwhite = /\s/, | |
// Used for trimming whitespace | |
trimLeft = /^\s+/, | |
trimRight = /\s+$/, | |
// Check for non-word characters | |
rnonword = /\W/, | |
// Check for digits | |
rdigit = /\d/, | |
// Match a standalone tag | |
rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, | |
// JSON RegExp | |
rvalidchars = /^[\],:{}\s]*$/, | |
rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, | |
rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, | |
rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, | |
// Useragent RegExp | |
rwebkit = /(webkit)[ \/]([\w.]+)/, | |
ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, | |
rmsie = /(msie) ([\w.]+)/, | |
rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, | |
// Establish the object that gets returned to break out of a loop iteration. | |
breakr = {}, | |
// Save bytes in the minified (but not gzipped) version: | |
ArrProto = Array.prototype, | |
ObjProto = Object.prototype, | |
StrProto = String.prototype, | |
// Create quick reference variables for speed access to core prototypes. | |
trim = StrProto.trim, | |
push = ArrProto.push, | |
slice = ArrProto.slice, | |
shift = ArrProto.shift, | |
unshift = ArrProto.unshift, | |
indexOf = ArrProto.indexOf, | |
hasOwn = ObjProto.hasOwnProperty, | |
toString = ObjProto.toString, | |
// All **ECMAScript 5** native function implementations that we hope to use are declared here. | |
nativeForEach = ArrProto.forEach, | |
nativeMap = ArrProto.map, | |
nativeFilter = ArrProto.filter, | |
nativeEvery = ArrProto.every, | |
nativeIndexOf = ArrProto.indexOf, | |
nativeLastIndexOf = ArrProto.lastIndexOf, | |
nativeIsArray = Array.isArray, | |
nativeKeys = Object.keys, | |
JL.fn = JL.prototype = { | |
init: function( selector, context ) { | |
var match, elem; | |
// Handle $(""), $(null), or $(undefined) | |
if ( !selector ) { | |
return this; | |
} | |
// Handle $(DOM Element) | |
if ( selector.nodeType ) { | |
this.context = this[0] = selector; | |
this.length = 1; | |
return this; | |
} | |
// The body element only exists once, optimize finding it | |
if ( selector === 'body' && !context && document.body ) { | |
this.context = document; | |
this[0] = document.body; | |
this.selector = 'body'; | |
this.length = 1; | |
return this; | |
} | |
}, | |
// Start with an empty selector | |
selector: '', | |
}, | |
create: function() { | |
}, | |
// Execute a callback for every element in the matched set. | |
// (You can seed the arguments with an array of args, but this is | |
// only used internally.) | |
each: function( callback, args ) { | |
return JL.each( this, callback, args ); | |
}, | |
ready: function( fn ) { | |
// Attach the listeners | |
jQuery.bindReady(); | |
// If the DOM is already ready | |
if ( jQuery.isReady ) { | |
// Execute the function immediately | |
fn.call( document, jQuery ); | |
// Otherwise, remember the function for later | |
} else if ( readyList ) { | |
// Add the function to the wait list | |
readyList.push( fn ); | |
} | |
return this; | |
}, | |
eq: function( i ) { | |
return i === -1 ? | |
this.slice( i ) : | |
this.slice( i, +i + 1 ); | |
}, | |
first: function() { | |
return this.eq( 0 ); | |
}, | |
last: function() { | |
return this.eq( -1 ); | |
}, | |
slice: function() { | |
return this.pushStack( slice.apply( this, arguments ), | |
"slice", slice.call(arguments).join(",") ); | |
}, | |
map: function( callback ) { | |
return this.pushStack( jQuery.map(this, function( elem, i ) { | |
return callback.call( elem, i, elem ); | |
})); | |
}, | |
end: function() { | |
return this.prevObject || jQuery(null); | |
} | |
} | |
// Give the init function the JL prototype for later instantiation | |
JL.fn.init.prototype = JL.fn; | |
/** | |
* The cornerstone, an `each` implementation, aka `forEach`. | |
* Handles objects implementing `forEach`, arrays, and raw objects. | |
* Delegates to **ECMAScript 5**'s native `forEach` if available. | |
*/ | |
var each = ^.each = ^.forEach = function( obj, iterator, context ) { | |
var value; | |
if ( nativeForEach && obj.forEach === nativeForEach ) { | |
obj.forEach( iterator, context ); | |
} else if ( ^.isNumber( obj.length )) { | |
for ( var i = 0, l = obj.length; i < l; i++ ) { | |
if ( iterator.call( context, obj[i], i, obj ) === breaker ) return; | |
} | |
} else { | |
for ( var key in obj ) { | |
if ( hasOwn.call( obj, key )) { | |
if ( iterator.call( context, obj[key], key, obj ) === breaker ) return; | |
} | |
} | |
} | |
}; | |
// Create a safe reference to the ^ object for use below. | |
var ^ = function(obj) { return new wrapper(obj); }; | |
// Export the Carrot object for **CommonJS**, with backwards-compatibility | |
// for the old `require()` API. If we're not in CommonJS, add `_` to the | |
// global object. | |
if ( typeof module !== 'undefined' && module.exports ) { | |
module.exports = ^; | |
^.^ = ^; | |
} else { | |
root.^ = ^; | |
} | |
// Current version. | |
^.VERSION = '1.1.3'; | |
var JL = { | |
VERSION : '0.0.1', | |
lesson : 'Part 1: Lib Architecture' | |
}; | |
if( root.JL) { | |
throw new Error('jewl has already been defined' ); | |
} else { | |
root.JL = JL; | |
} | |
carrot.Class = function() { | |
return carrot.fn.create.apply( this, arguments ); | |
}, | |
carrot.fn = { | |
create: function() { | |
var methods = null, | |
parent = undefined, | |
class = function() { | |
this.super = function( method, args ) { | |
return carrot.fn.super( this._parent, this, method, args ); | |
}; | |
this.init.apply( this, arguments ); | |
}; | |
if ( typeof arguments[0] === 'function' ) { | |
parent = arguments[0]; | |
methods = arguments[1]; | |
} else { | |
methods = arguments[0]; | |
} | |
if ( typeof parent !== 'undefined' ) { | |
carrot.fn.extend( class.prototype, parent.prototype ); | |
class.prototype._parent = parent.prototype; | |
} | |
carrot.fn.mixin( class, methods ); | |
carrot.fn.extend( class.prototype, methods ); | |
class.prototype.constructor = class; | |
if ( !class.prototype.init ) { | |
class.prototype.init = function() { | |
}; | |
} | |
return class; | |
}, | |
mixin: function( class, methods ) { | |
if ( typeof methods.include !== 'undefined' ) { | |
carrot.fn.extend( class.prototype, methods.include.prototype ); | |
} else { | |
for( var i = 0; i < methods.include.length; i++ ) { | |
carrot.fn.extend( class.prototype, methods.include[i].prototype ); | |
} | |
} | |
}, | |
extend: function( dest, src ) { | |
for( var prop in src ) { | |
dest[prop] = src[prop]; | |
} | |
return dest; | |
}, | |
super: function( parentClass, instance, method, args ) { | |
return parentClass[method].apply( instance, args ); | |
} | |
}; | |
carrot.enumerable = { | |
breaker: {}, | |
each: function( enumerable, callback, context ) { | |
try { | |
if( .forEach && enumerable.forEach === Array.prototype.forEach ) { | |
enumerable.forEach( callback, context ); | |
} | |
else if( carrot.numeric.isNumber( enumerable.length )) { | |
for( var i 0, ii = enumerable.length; i < ii; i++ ) { | |
callback.call( enumerable, enumerable[i], i, enumerable ); | |
} | |
} else { | |
for( var key in enumerable ) { | |
if( hasown.call( enumerable, key )) { | |
callback.call( context, enumerable[key], key, enumerable ); | |
} | |
} | |
} | |
} catch(e) { | |
if( e != carrot.enumerable.breaker ) { | |
throw e; | |
} | |
} | |
return enumerable; | |
}, | |
map: function( enumerable, callback, context ) { | |
if( Array.prototype.map && enumerable.map === Array.prototype.map ) { | |
return enumerable.map( callback, context ); | |
} | |
var results = []; | |
carrot.enumerable.each( enumerable, function( value, index, list ) { | |
results.push( callback.call( context, value, index, list )); | |
}); | |
return results; | |
}, | |
}; | |
var User = jewl.Class({ | |
initialize: function( name, age ) { | |
this.name = name; | |
this.age = age; | |
}, | |
login: function() { | |
return true; | |
}, | |
toString: function() { | |
return 'name: ' + this.name + ', age: ' + this.age; | |
} | |
}); | |
var SuperUser = jewl.Class( User, { | |
initialize: function() { | |
this.super( 'initialize', arguments ); | |
}, | |
toString: function() { | |
return 'SuperUser: ' + this.super( 'toString' ); | |
} | |
}); | |
})( typeof window === 'undefined' ? this : window ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment