Created
April 30, 2010 01:08
-
-
Save stefanpenner/384554 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// Set up simple-inheritance (Classical) | |
// Inspired by base2 and Prototype | |
(function(){ | |
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; | |
// The base Class implementation (does nothing) | |
this.Class = function(){}; | |
// Create a new Class that inherits from this class | |
Class.extend = function(prop) { | |
var _super = this.prototype; | |
// Instantiate a base class (but only create the instance, | |
// don't run the init constructor) | |
initializing = true; | |
var prototype = new this(); | |
initializing = false; | |
// Copy the properties over onto the new prototype | |
for (var name in prop) { | |
// Check if we're overwriting an existing function | |
prototype[name] = typeof prop[name] == "function" && | |
typeof _super[name] == "function" && fnTest.test(prop[name]) ? | |
(function(name, fn){ | |
return function() { | |
var tmp = this._super; | |
// Add a new ._super() method that is the same method | |
// but on the super-class | |
this._super = _super[name]; | |
// The method only need to be bound temporarily, so we | |
// remove it when we're done executing | |
var ret = fn.apply(this, arguments); | |
this._super = tmp; | |
return ret; | |
}; | |
})(name, prop[name]) : | |
prop[name]; | |
} | |
// The dummy class constructor | |
function Class() { | |
// All construction is actually done in the init method | |
if ( !initializing && this.init ) | |
this.init.apply(this, arguments); | |
} | |
// Populate our constructed prototype object | |
Class.prototype = prototype; | |
// Enforce the constructor to be what we expect | |
Class.constructor = Class; | |
// And make this class extendable | |
Class.extend = arguments.callee; | |
return Class; | |
}; | |
})(); | |
// Create a closure for namespace safety | |
(function($){ | |
////////////////////////////////////////////////// | |
// Define our Objects | |
////////////////////////////////////////////////// | |
/** | |
* Class Person | |
* | |
* A simple representation of a person. | |
*/ | |
var Person = Class.extend({ | |
init : function (options, elem) { | |
// Overload the passed in options with any default options | |
this.options = $.extend({}, this.options, options); | |
// Set the relative element as the passed in element | |
this.element = elem; | |
// Initiate the dom building method | |
this.buildDom(); | |
}, | |
options : { | |
className: "person", | |
smartz: 1 | |
}, | |
getName : function () { | |
return this.options.name; | |
}, | |
buildDom : function() { | |
$(this.element) | |
.addClass(this.options.className) | |
.html(this.getName() + '<span class="smartz">('+this.options.smartz+')</span>'); | |
} | |
}); | |
/** | |
* Class Attendee | |
* | |
* A Person with the added interface for a conference attendee | |
*/ | |
var Attendee = Person.extend((function(){ | |
// A private function via the module pattern | |
var addSmartz = function(points) { | |
if (this.options.smartz) { | |
this.options.smartz += points; | |
} | |
else { | |
this.options.smartz = points; | |
} | |
// Update the indicator | |
$(this.element).find('.smartz').text('('+this.options.smartz+')'); | |
}; | |
// Return the object literal that we would normally just type | |
// if we weren't using the module pattern. | |
return { | |
// A function to add to the smartness level | |
listen : function() { | |
// Call our private function with the context of this object | |
addSmartz.call(this, 1); | |
}, | |
options: { | |
className: "attendee" | |
} | |
}; | |
// Notice that this is a self executing function | |
})()); | |
/** | |
* Class Speaker | |
* | |
* An Attendee that has speaking powers | |
*/ | |
var Speaker = Attendee.extend({ | |
// The speaking function only decreases Smartz | |
speak : function(attendees) { | |
// Decrement smartz | |
this.options.smartz -= 1; | |
// Loop through attendees and make them listen | |
for (var i in attendees) { | |
attendees[i].listen(); | |
} | |
// Update the indicator | |
$(this.element).find('.smartz').text('('+this.options.smartz+')'); | |
// This makes this method chainable | |
return this; | |
}, | |
options: { | |
className: "speaker" | |
}, | |
buildDom : function() { | |
// Use the super class! | |
this._super(); | |
$(this.element).append('<a href="#speak" class="spk">[speak]</a>'); | |
} | |
}); | |
///////////////////////////////////////////////// | |
// Pluginify! | |
///////////////////////////////////////////////// | |
$.fn.extend({ | |
'person': function(options) { | |
return this.each(function(){ | |
// Create a new person | |
var myPerson = new Person(options, this); | |
// Save the reference to the person in the elem's data object | |
$(this).data('person', myPerson); | |
}); | |
}, | |
// Do the same for attendee and speaker | |
'attendee': function(options) { | |
return this.each(function(){ | |
var myAttendee = new Attendee(options, this); | |
$(this).data('attendee', myAttendee); | |
}); | |
}, | |
'speaker': function(options) { | |
return this.each(function(){ | |
var mySpeaker = new Speaker(options, this); | |
$(this).data('speaker', mySpeaker); | |
}); | |
} | |
}); | |
//////////////////////////////////////////////// | |
// Use our new plugins for our website! - NOTHING CHANGES IN OUR INTERFACE TO OUR APP | |
//////////////////////////////////////////////// | |
// Run when the document is ready | |
$(document).ready(function(){ | |
// Cache the elements where our people will be placed | |
var personList = $('#personList'), | |
attendeeList = $('#attendeeList'), | |
speakerList = $('#speakerList'); | |
// Create storage for our people | |
var everyone = { | |
persons: [], | |
attendees: [], | |
speakers: [] | |
}; | |
// Handle the add Person button | |
$('#add_person').click(function(e){ | |
// Generate a person | |
var generatedPerson = $('<li />').person({ | |
name : "Person " + everyone.persons.length, | |
smartz : 20 | |
}); | |
// Add the Person Object to the everyone storage | |
everyone.persons.push(generatedPerson.data('person')); | |
// Append the dom element to the list of persons | |
personList.append(generatedPerson); | |
// Update the count | |
personList.prev().text(everyone.persons.length); | |
// Prevent the link from following | |
return false; | |
}); | |
// Handle the add Attendee button | |
$('#add_attendee').click(function(e){ | |
// Generate an attendee | |
var generatedAttendee = $('<li />').attendee({ | |
name : "Attendee " + everyone.attendees.length, | |
smartz : 50 | |
}); | |
// Add the Attendee Object to the everyone storage | |
everyone.attendees.push(generatedAttendee.data('attendee')); | |
// Append the dom element to the list of attendees | |
attendeeList.append(generatedAttendee); | |
// Update the count | |
attendeeList.prev().text(everyone.attendees.length); | |
// Prevent the link from following | |
return false; | |
}); | |
// Handle the add Speaker button | |
$('#add_speaker').click(function(e){ | |
// Generate an speaker | |
var generatedSpeaker = $('<li />').speaker({ | |
name : "Speaker " + everyone.speakers.length, | |
smartz : 10 | |
}); | |
// Add the Attendee Object to the everyone storage | |
everyone.speakers.push(generatedSpeaker.data('speaker')); | |
// Append the dom element to the list of speakers | |
speakerList.append(generatedSpeaker); | |
// Update the count | |
speakerList.prev().text(everyone.speakers.length); | |
// Prevent the link from following | |
return false; | |
}); | |
speakerList.find('a.spk').live('click', function(e){ | |
// Get our speaker instance from the data cache | |
var speakingSpeaker = $(this).closest('li').data('speaker'); | |
// Invoke the speaking function on our object | |
speakingSpeaker.speak(everyone.attendees); | |
// Prevent the link from following | |
return false; | |
}); | |
}); | |
})(jQuery); |
This file contains hidden or 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
// Set up prototypal inheritance - if it doesn't exist | |
if (typeof Object.create !== 'function') { | |
Object.create = function (o) { | |
function F() {} | |
F.prototype = o; | |
return new F(); | |
}; | |
} | |
// Create a closure for namespace safety | |
(function($){ | |
////////////////////////////////////////////////// | |
// Define our Objects | |
////////////////////////////////////////////////// | |
/** | |
* Object Person | |
* | |
* A simple representation of a person. | |
*/ | |
var Person = { | |
init : function (options, elem) { | |
// Overload the passed in options with any default options | |
this.options = $.extend({}, this.options, options); | |
// Set the relative element as the passed in element | |
this.element = elem; | |
// Initiate the dom building method | |
this.buildDom(); | |
}, | |
options : { | |
className: "person", | |
smartz: 1 | |
}, | |
getName : function () { | |
return this.options.name; | |
}, | |
buildDom : function() { | |
$(this.element) | |
.addClass(this.options.className) | |
.html(this.getName() + '<span class="smartz">('+this.options.smartz+')</span>'); | |
} | |
}; | |
/** | |
* Object Attendee | |
* | |
* A Person with the added interface for a conference attendee | |
*/ | |
var Attendee = $.extend(Object.create(Person), (function(){ | |
// A private function via the module pattern | |
var addSmartz = function(points) { | |
if (this.options.smartz) { | |
this.options.smartz += points; | |
} | |
else { | |
this.options.smartz = points; | |
} | |
// Update the indicator | |
$(this.element).find('.smartz').text('('+this.options.smartz+')'); | |
}; | |
// Return the object literal that we would normally just type | |
// if we weren't using the module pattern. | |
return { | |
// A function to add to the smartness level | |
listen : function() { | |
// Call our private function with the context of this object | |
addSmartz.call(this, 1); | |
}, | |
options: { | |
className: "attendee" | |
} | |
}; | |
// Notice that this is a self executing function | |
})()); | |
/** | |
* Object Speaker | |
* | |
* An Attendee that has speaking powers | |
*/ | |
var Speaker = $.extend(Object.create(Attendee), { | |
// The speaking function only decreases Smartz | |
speak : function(attendees) { | |
// Decrement smartz | |
this.options.smartz -= 1; | |
// Loop through attendees and make them listen | |
for (var i in attendees) { | |
attendees[i].listen(); | |
} | |
// Update the indicator | |
$(this.element).find('.smartz').text('('+this.options.smartz+')'); | |
// This makes this method chainable | |
return this; | |
}, | |
options: { | |
className: "speaker" | |
}, | |
buildDom : function() { | |
$(this.element) | |
.addClass(this.options.className) | |
.html(this.getName() + '<span class="smartz">('+this.options.smartz+')</span>') | |
.append('<a href="#speak" class="spk">[speak]</a>'); | |
} | |
}); | |
// Redefine the getName function for Person to show that differential inheritance is retroactive | |
Person.getName = function() { | |
return this.options.name + '!'; | |
}; | |
///////////////////////////////////////////////// | |
// Pluginify! | |
///////////////////////////////////////////////// | |
$.fn.extend({ | |
'person': function(options) { | |
return this.each(function(){ | |
// Create a new person | |
var myPerson = Object.create(Person); | |
// Set initialize that person with the plugin options | |
myPerson.init(options, this); | |
// Save the reference to the person in the elem's data object | |
$(this).data('person', myPerson); | |
}); | |
}, | |
// Do the same for attendee and speaker | |
'attendee': function(options) { | |
return this.each(function(){ | |
var myAttendee = Object.create(Attendee); | |
myAttendee.init(options, this); | |
$(this).data('attendee', myAttendee); | |
}); | |
}, | |
'speaker': function(options) { | |
return this.each(function(){ | |
var mySpeaker = Object.create(Speaker); | |
mySpeaker.init(options, this); | |
$(this).data('speaker', mySpeaker); | |
}); | |
} | |
}); | |
//////////////////////////////////////////////// | |
// Use our new plugins for our website! | |
//////////////////////////////////////////////// | |
// Run when the document is ready | |
$(document).ready(function(){ | |
// Cache the elements where our people will be placed | |
var personList = $('#personList'), | |
attendeeList = $('#attendeeList'), | |
speakerList = $('#speakerList'); | |
// Create storage for our people | |
var everyone = { | |
persons: [], | |
attendees: [], | |
speakers: [] | |
}; | |
// Handle the add Person button | |
$('#add_person').click(function(e){ | |
// Generate a person | |
var generatedPerson = $('<li />').person({ | |
name : "Person " + everyone.persons.length, | |
smartz : 20 | |
}); | |
// Add the Person Object to the everyone storage | |
everyone.persons.push(generatedPerson.data('person')); | |
// Append the dom element to the list of persons | |
personList.append(generatedPerson); | |
// Update the count | |
personList.prev().text(everyone.persons.length); | |
// Prevent the link from following | |
return false; | |
}); | |
// Handle the add Attendee button | |
$('#add_attendee').click(function(e){ | |
// Generate an attendee | |
var generatedAttendee = $('<li />').attendee({ | |
name : "Attendee " + everyone.attendees.length, | |
smartz : 50 | |
}); | |
// Add the Attendee Object to the everyone storage | |
everyone.attendees.push(generatedAttendee.data('attendee')); | |
// Append the dom element to the list of attendees | |
attendeeList.append(generatedAttendee); | |
// Update the count | |
attendeeList.prev().text(everyone.attendees.length); | |
// Prevent the link from following | |
return false; | |
}); | |
// Handle the add Speaker button | |
$('#add_speaker').click(function(e){ | |
// Generate an speaker | |
var generatedSpeaker = $('<li />').speaker({ | |
name : "Speaker " + everyone.speakers.length, | |
smartz : 10 | |
}); | |
// Add the Attendee Object to the everyone storage | |
everyone.speakers.push(generatedSpeaker.data('speaker')); | |
// Append the dom element to the list of speakers | |
speakerList.append(generatedSpeaker); | |
// Update the count | |
speakerList.prev().text(everyone.speakers.length); | |
// Prevent the link from following | |
return false; | |
}); | |
speakerList.find('a.spk').live('click', function(e){ | |
// Get our speaker instance from the data cache | |
var speakingSpeaker = $(this).closest('li').data('speaker'); | |
// Invoke the speaking function on our object | |
speakingSpeaker.speak(everyone.attendees); | |
// Prevent the link from following | |
return false; | |
}); | |
}); | |
})(jQuery); |
This file contains hidden or 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
// No extras for Pseudo-Classical - we're native! | |
// Create a closure for namespace safety | |
(function($){ | |
////////////////////////////////////////////////// | |
// Define our Objects | |
////////////////////////////////////////////////// | |
/** | |
* Person | |
* | |
* A simple representation of a person. | |
*/ | |
var Person = function(options, elem) { | |
// Call init - to initialize the object | |
this.init(options, elem); | |
}; | |
Person.prototype.init = function(options, elem) { | |
// Overload the passed in options with any default options | |
this.options = $.extend({}, this.options, options); | |
// Set the relative element as the passed in element | |
this.element = elem; | |
// Initiate the dom building method | |
this.buildDom(); | |
}; | |
// Prototype members can be declared after the fact | |
Person.prototype.options = { | |
className: "person", | |
smartz: 1 | |
}; | |
Person.prototype.getName = function () { | |
return this.options.name; | |
}; | |
Person.prototype.buildDom = function() { | |
$(this.element) | |
.addClass(this.options.className) | |
.html(this.getName() + '<span class="smartz">('+this.options.smartz+')</span>'); | |
}; | |
/** | |
* Attendee | |
* | |
* A Person with the added interface for a conference attendee | |
*/ | |
var Attendee = function(options, elem){ | |
this.init(options, elem); | |
}; | |
Attendee.prototype = new Person(); | |
Attendee.prototype.options = {className: "attendee"}; | |
// A private function via the module pattern | |
Attendee.prototype.listen = (function() { | |
// Use a self executing function to return a function with access to a private function | |
var addSmartz = function(points) { | |
if (this.options.smartz) { | |
this.options.smartz += points; | |
} | |
else { | |
this.options.smartz = points; | |
} | |
// Update the indicator | |
$(this.element).find('.smartz').text('('+this.options.smartz+')'); | |
}; | |
// Return the object literal instead of 'this' which usually happens automatically | |
return function() { | |
// Call our private function with the context of this object | |
addSmartz.call(this, 1); | |
}; | |
})(); | |
/** | |
* Speaker | |
* | |
* An Attendee that has speaking powers | |
*/ | |
var Speaker = function(options, elem) { | |
// You can specifically invoke your parent constructor function | |
this.constructor.apply(this, arguments); | |
}; | |
Speaker.prototype = new Attendee(); | |
Speaker.prototype.options = {className: "speaker"}; | |
// The speaking function only decreases Smartz | |
Speaker.prototype.speak = function(attendees) { | |
// Decrement smartz | |
this.options.smartz -= 1; | |
// Loop through attendees and make them listen | |
for (var i in attendees) { | |
attendees[i].listen(); | |
} | |
// Update the indicator | |
$(this.element).find('.smartz').text('('+this.options.smartz+')'); | |
// This makes this method chainable | |
return this; | |
}; | |
Speaker.prototype.buildDom = function() { | |
// Use the super class! | |
this.constructor.prototype.buildDom.call(this); | |
$(this.element).append('<a href="#speak" class="spk">[speak]</a>'); | |
}; | |
///////////////////////////////////////////////// | |
// Pluginify! | |
///////////////////////////////////////////////// | |
$.fn.extend({ | |
'person': function(options) { | |
return this.each(function(){ | |
// Create a new person | |
var myPerson = new Person(options, this); | |
// Save the reference to the person in the elem's data object | |
$(this).data('person', myPerson); | |
}); | |
}, | |
// Do the same for attendee and speaker | |
'attendee': function(options) { | |
return this.each(function(){ | |
var myAttendee = new Attendee(options, this); | |
$(this).data('attendee', myAttendee); | |
}); | |
}, | |
'speaker': function(options) { | |
return this.each(function(){ | |
var mySpeaker = new Speaker(options, this); | |
$(this).data('speaker', mySpeaker); | |
}); | |
} | |
}); | |
//////////////////////////////////////////////// | |
// Use our new plugins for our website! - NOTHING CHANGES IN OUR INTERFACE TO OUR APP | |
//////////////////////////////////////////////// | |
// Run when the document is ready | |
$(document).ready(function(){ | |
// Cache the elements where our people will be placed | |
var personList = $('#personList'), | |
attendeeList = $('#attendeeList'), | |
speakerList = $('#speakerList'); | |
// Create storage for our people | |
var everyone = { | |
persons: [], | |
attendees: [], | |
speakers: [] | |
}; | |
// Handle the add Person button | |
$('#add_person').click(function(e){ | |
// Generate a person | |
var generatedPerson = $('<li />').person({ | |
name : "Person " + everyone.persons.length, | |
smartz : 20 | |
}); | |
// Add the Person Object to the everyone storage | |
everyone.persons.push(generatedPerson.data('person')); | |
// Append the dom element to the list of persons | |
personList.append(generatedPerson); | |
// Update the count | |
personList.prev().text(everyone.persons.length); | |
// Prevent the link from following | |
return false; | |
}); | |
// Handle the add Attendee button | |
$('#add_attendee').click(function(e){ | |
// Generate an attendee | |
var generatedAttendee = $('<li />').attendee({ | |
name : "Attendee " + everyone.attendees.length, | |
smartz : 50 | |
}); | |
// Add the Attendee Object to the everyone storage | |
everyone.attendees.push(generatedAttendee.data('attendee')); | |
// Append the dom element to the list of attendees | |
attendeeList.append(generatedAttendee); | |
// Update the count | |
attendeeList.prev().text(everyone.attendees.length); | |
// Prevent the link from following | |
return false; | |
}); | |
// Handle the add Speaker button | |
$('#add_speaker').click(function(e){ | |
// Generate an speaker | |
var generatedSpeaker = $('<li />').speaker({ | |
name : "Speaker " + everyone.speakers.length, | |
smartz : 10 | |
}); | |
// Add the Attendee Object to the everyone storage | |
everyone.speakers.push(generatedSpeaker.data('speaker')); | |
// Append the dom element to the list of speakers | |
speakerList.append(generatedSpeaker); | |
// Update the count | |
speakerList.prev().text(everyone.speakers.length); | |
// Prevent the link from following | |
return false; | |
}); | |
speakerList.find('a.spk').live('click', function(e){ | |
// Get our speaker instance from the data cache | |
var speakingSpeaker = $(this).closest('li').data('speaker'); | |
// Invoke the speaking function on our object | |
speakingSpeaker.speak(everyone.attendees); | |
// Prevent the link from following | |
return false; | |
}); | |
}); | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment