Skip to content

Instantly share code, notes, and snippets.

@optikalefx
Created July 31, 2012 05:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save optikalefx/3213813 to your computer and use it in GitHub Desktop.
Save optikalefx/3213813 to your computer and use it in GitHub Desktop.
// Root Version SC.05.27.12
///////////////////////////////////////////////////////////////////////////////
// RootJS is basically a way to write much easier OOP code
// Root.DOM is a helper object to inherit from, so you get a bunch of really cool
// dom stuff, like events, objects tied to elements, and a jQuery plugin arch
///////////////////////////////////////////////////////////////////////////////
(function($, window, document, undefined) {
"use strict";
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// Root
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
window.Root = {
_construct : function() {}, // construct method
_init : function() {}, // method called on every instantiation
proto : function () { // shortcut to parent object
return Object.getPrototypeOf(this);
},
// borrowed and modifed from jQuery source. They do it the best.
// we use our own check methods though
extend : function() {
var options, name, src, copy, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = true;
// Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && typeof target != "function" ) {
target = {};
}
for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
for ( name in options ) {
src = target[ name ];
copy = options[ name ];
// Prevent never-ending loop
if ( target === copy ) {
continue;
}
// Recurse if we're merging plain objects or arrays
if ( deep && copy && ( this.isPlainObject(copy) )) {
if(src && Array.isArray(src)) {
clone = src && Array.isArray(src) ? src : [];
} else {
clone = src && this.isPlainObject(src) ? src : {};
}
// Never move original objects, clone them
target[ name ] = this.extend( deep, clone, copy );
// Don't bring in undefined values
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
}
// Return the modified object
return target;
},
// tests if object is a plain object
isPlainObject : function(obj) {
// typeof null == 'object' haha
if(obj !== null && typeof obj === "object") {
// yea!
return this.proto.call(obj).hasOwnProperty("hasOwnProperty");
} else {
return false;
}
},
// wrapper for set and get
// takes the property you wanna set, and calls the method on 'this'
// optional placeholder to init with
setter : function(prop,method,placeHolder) {
var placeHolder = placeHolder;
Object.defineProperty(this,prop,{
get : function() {return placeHolder},
set : function(val) {
placeHolder = val;
this[method](val);
}
});
},
// convience method
define : function() {
return this.inherit.apply(this,arguments);
},
// object inheritance method
// takes an object to extend the class with, &| a dom element to use
inherit: function(values, el) {
// create a copy of the parent and copy over new values
// normally Object.create() takes a 2nd param to extend properties. But when you use that,
// you can't use use an easy JSON structure, you have to define enumerable, writable, and configurable and value
// FOR EVERY PROPERTY. So.. we just do it ourselves with this.extend
var parent = this, instance;
if(typeof el != "undefined") values.el = el;
// handle arrays
if(Array.isArray(values)) {
instance = values;
this.extend(instance, parent);
} else {
instance = Object.create(parent);
// now do a deep copy
this.extend(instance, values);
}
// if the parent element has a constructor, call it on the instances
if(parent.hasOwnProperty("_construct")) { parent._construct.apply(instance); }
// if i have an _init function, call me
if(instance.hasOwnProperty("_init")) { instance._init(); }
// return the new instance
return instance;
},
jQueryPlugin : function(name) {
// pull the name out of the first argument
var args = Array.prototype.slice.call(arguments);
args.splice(0,1);
// this does our Grid = Root.inherit(stuff)
// so this is just like the main definition of the main object
console.log("creating main Grid object");
var Obj = this.inherit.apply(this,args);
// create the jQuery Plugin
console.log("creating jquery plugin");
$.fn[name] = function(user_opts) {
var args = Array.prototype.slice.call(arguments);
for(var i=0;i<this.length;i++) {
var self = this[i];
if(typeof self.instance == "undefined") {
if(!user_opts) user_opts = {};
// store the instance on the element
// THIS LINE HAS BEEN ALTERED FOR OPENJSGRID
self.instance = Obj.inherit({opts : user_opts}, self);
}
// passing a string calls a method
if(typeof user_opts === "string") {
var method = user_opts, property = user_opts;
// call the method, passing it all params (except first 1)
if(typeof self.instance[method] == "function") {
args.splice(0,1); // first arg is the method name, we dont need this
self.instance[method].apply(self.instance,args);
return self;
} else {
// if there was just a property, get it
if(args.length == 1) {
return self.instance[property];
// if there was a property and a value, set it
} else if (args.length == 2) {
self.instance[property] = args[1];
return args[1];
}
}
// passed an object in
} else {
this.extend(self.instance, user_opts);
//$.extend(self.instance,user_opts);
}
}
}
}
};
// jquery helper
$.fn._on = function(type,sel,method,scope) {
console.log("_on",this, scope);
if(!scope) scope = method, method = sel, sel = undefined
var fn = function(e) { method.call(scope, e, this); }
sel ? $(this).on(type,sel, fn) : $(this).on(type,fn);
return this;
}
})(jQuery,this,document)
/*
// Root Version SC.05.27.12
///////////////////////////////////////////////////////////////////////////////
// RootJS is basically a way to write much easier OOP code
// Root.DOM is a helper object to inherit from, so you get a bunch of really cool
// dom stuff, like events, objects tied to elements, and a jQuery plugin arch
///////////////////////////////////////////////////////////////////////////////
(function($, window, document, undefined) {
"use strict";
// random from an array
Array.prototype.random = function() {
return this[Math.ceil(Math.random() * this.length - 1)];
}
// remove an object from an array
Array.prototype.remove = function(obj) {
var index = this.indexOf(obj);
if(index !== -1) this.splice(index,1);
return this;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// Root
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
window.Root = {
_construct : function() {}, // construct method
_init : function() {}, // method called on every instantiation
proto : function () { // shortcut to parent object
return Object.getPrototypeOf(this);
},
// borrowed and modifed from jQuery source. They do it the best.
// we use our own check methods though
extend : function() {
var options, name, src, copy, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = true;
// Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && typeof target != "function" ) {
target = {};
}
for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
for ( name in options ) {
src = target[ name ];
copy = options[ name ];
// Prevent never-ending loop
if ( target === copy ) {
continue;
}
// Recurse if we're merging plain objects or arrays
if ( deep && copy && ( this.isPlainObject(copy) )) {
if(src && Array.isArray(src)) {
clone = src && Array.isArray(src) ? src : [];
} else {
clone = src && this.isPlainObject(src) ? src : {};
}
// Never move original objects, clone them
target[ name ] = this.extend( deep, clone, copy );
// Don't bring in undefined values
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
}
// Return the modified object
return target;
},
// tests if object is a plain object
isPlainObject : function(obj) {
// typeof null == 'object' haha
if(obj !== null && typeof obj === "object") {
// yea!
return this.proto.call(obj).hasOwnProperty("hasOwnProperty");
} else {
return false;
}
},
// wrapper for set and get
// takes the property you wanna set, and calls the method on 'this'
// optional placeholder to init with
setter : function(prop,method,placeHolder) {
var placeHolder = placeHolder;
Object.defineProperty(this,prop,{
get : function() {return placeHolder},
set : function(val) {
placeHolder = val;
this[method](val);
}
});
},
// convience method
define : function() {
return this.inherit.apply(this,arguments);
},
// object inheritance method
// takes an object to extend the class with, &| a dom element to use
inherit: function(values) {
// create a copy of the parent and copy over new values
// normally Object.create() takes a 2nd param to extend properties. But when you use that,
// you can't use use an easy JSON structure, you have to define enumerable, writable, and configurable and value
// FOR EVERY PROPERTY. So.. we just do it ourselves with this.extend
var parent = this, instance;
// handle arrays
if(Array.isArray(values)) {
instance = values;
this.extend(instance, parent);
} else {
instance = Object.create(parent);
// now do a deep copy
this.extend(instance, values);
}
// if the parent element has a constructor, call it on the instances
if(parent.hasOwnProperty("_construct")) { parent._construct.apply(instance); }
// if i have an _init function, call me
if(instance.hasOwnProperty("_init")) { instance._init(); }
// return the new instance
return instance;
}
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// Root DOM
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// extend Root with DOM
Root.DOM = Root.inherit({
el : null, // the DOM object of this instance' element
_events : function() {}, // object of events for the DOM element
setEl : function(val) {
if(val) val.instance = this;
},
inherit : function(values,el) {
// create a copy of the parent and copy over values
var parent = this;
if(typeof values == "undefined") values = {};
if(el) values['el'] = el;
// create a copy and copy over values
var parent = this,
instance = Object.create(parent);
// setter for el
instance.setter("el","setEl",this.el);
// Copy over properties from the old to the new
// this triggers the above defineProperty
this.extend(instance,values);
// prototype the array object in the scope of this instance. heh.
Array.prototype.on = function(type, sel, method, data) {
var args = Array.prototype.slice.call(arguments);
// if any of the paramentes is an array, we need to slice that out, and use that as data
for(var i=0; i<args.length;i++) {
if(Array.isArray(args[i])) { data = args.splice(i,1)[0]; }
}
// if we only passed in the type and method, pass no selection
if(args.length === 2) {
method = sel;
sel = "";
}
// call internal on method in the scope of this instance
instance._on(this, type, sel, method, data);
return this;
};
// call events, dont do it if your the base element
if(parent.hasOwnProperty("_events") && !parent.proto().hasOwnProperty("_construct")) {
instance._events();
}
// if the parent element has a constructor, call it on the instances
if(parent.hasOwnProperty("_construct") && !parent.proto().hasOwnProperty("_construct")) {
parent._construct.call(instance);
}
// if i have an _init function, call me
if(instance.hasOwnProperty("_init")) { instance._init(); }
// return the new instance
return instance;
},
// convience method
create : function() {
return this.inherit.apply(this,arguments);
},
// helper on function to shorten syntax when using events
// on the stored dom element for this instance
// this.on(type,selector,method) || this.on(type,method)
on : function(type, selector, method) {
var args = Array.prototype.slice.call(arguments);
[this.el].on.apply([this.el], args);
return this;
},
_on : function(els, type, selector, callback, data) {
var instance = this,
// use jquery on
func = function(e) {
var args = Array.prototype.slice.call(arguments);
// execute a callback function in the scope of the instance
if(typeof callback == "function") {
callback.apply(instance,[e, this].concat(data, args));
// find the method on the instance object and call that
} else {
instance[callback].apply(instance, [e, this].concat(data, args));
}
};
$(els).on(type, selector, func);
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// Root Collections
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// create the Collection extension
Root.Collection = Root.inherit(Array.prototype).define({
// create a new collection with all the passed values
create : function(vals) {
var args = Array.prototype.slice.call(arguments);
for(var i=0;i<args.length;i++) {
this.push(args[i]);
}
return this;
},
remove : function(obj) {
var index = this.indexOf(obj);
if(index !== -1) this.splice(index,1);
return this;
},
has : function(obj) {
return this.indexOf(obj) !== -1;
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
////// Root Plugins
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// create a plugin extension, that extends Root.DOM
Root.Plugin = Root.DOM.inherit({
// convience method
define : function(name) {
// pull the name out of the first argument
var args = Array.prototype.slice.call(arguments);
args.splice(0,1);
// inherit all of our stuff
var Obj = this.inherit.apply(this,args);
// create the jQuery Plugin
$.fn[name] = function(user_opts) {
var args = Array.prototype.slice.call(arguments);
for(var i=0;i<this.length;i++) {
var self = this[i];
// create the instance
if(!self.instance) Obj.inherit(user_opts,self);
// passing a string calls a method
if(typeof user_opts === "string") {
var method = user_opts, property = user_opts;
// call the method, passing it all params (except first 1)
if(typeof self.instance[method] == "function") {
args.splice(0,1); // first arg is the method name, we dont need this
self.instance[method].apply(self.instance,args);
return self;
} else {
// if there was just a property, get it
if(args.length == 1) {
return self.instance[property];
// if there was a property and a value, set it
} else if (args.length == 2) {
self.instance[property] = args[1];
return args[1];
}
}
// passed an object in
} else {
$.extend(self.instance,user_opts);
}
};
};
// return 'instance' (object definition) back
return Obj;
},
});
})(jQuery, this, document);
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment