-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
231 additions
and
318 deletions.
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,133 +1,104 @@ | ||
/** | ||
* Heir v1.0.1 - http://git.io/F87mKg | ||
* Heir v2.0.0 - http://git.io/F87mKg | ||
* Oliver Caldwell | ||
* MIT license | ||
*/ | ||
|
||
(function () { | ||
(function (name, root, factory) { | ||
if (typeof define === 'function' && define.amd) { | ||
define(factory); | ||
} | ||
else if (typeof exports === 'object') { | ||
module.exports = factory(); | ||
} | ||
else { | ||
root[name] = factory(); | ||
} | ||
}('heir', this, function () { | ||
/*global define,module*/ | ||
'use strict'; | ||
|
||
/** | ||
* Works out if a variable is a true object (created with {} etc) and not an array or anything else that usually shows up as an object. | ||
* | ||
* @param {Mixed} chk The variable to check to see if it is an object. It must be a pure object, not even a prototype. | ||
* @return {Boolean} True if it is a true object, false if it is anything else. | ||
*/ | ||
function isObject(chk) { | ||
return (chk && Object.prototype.toString.call(chk) === '[object Object]') === true; | ||
} | ||
|
||
/** | ||
* Recursively merges two objects. Object `a` will be overridden by the values in object `b`. | ||
* Please run the values through a cloning function first, this function does not try to clone them for you. | ||
* The base object will be edited directly, please be careful! | ||
* | ||
* @param {Object} a The base object to merge into. | ||
* @param {Object} b The object to merge down into object `a`. | ||
* @return {Object} This is object `a` but merged with `b`. | ||
*/ | ||
function merge(a, b) { | ||
// Loop over all values in b. If they are not found in a then set them | ||
// If both values are objects then recursively merge them | ||
for (var key in b) { | ||
// Make sure the value is not in __proto__ or something like that | ||
if (b.hasOwnProperty(key)) { | ||
// If they are both objects then merge recursively | ||
if (isObject(a[key]) && isObject(b[key])) { | ||
merge(a[key], b[key]); | ||
} | ||
|
||
// Otherwise just replace the base value | ||
else { | ||
a[key] = b[key]; | ||
} | ||
var heir = { | ||
/** | ||
* Causes your desired class to inherit from a source class. This uses | ||
* prototypical inheritance so you can override methods without ruining | ||
* the parent class. | ||
* | ||
* This will alter the actual destination class though, it does not | ||
* create a new class. | ||
* | ||
* @param {Function} destination The target class for the inheritance. | ||
* @param {Function} source Class to inherit from. | ||
* @param {Boolean} addSuper Should we add the _super property to the prototype? Defaults to true. | ||
*/ | ||
inherit: function inherit(destination, source, addSuper) { | ||
var proto = destination.prototype = heir.createObject(source.prototype); | ||
proto.constructor = destination; | ||
|
||
if (addSuper || typeof addSuper === 'undefined') { | ||
proto._super = source.prototype; | ||
} | ||
} | ||
}, | ||
|
||
// Return the merged object | ||
return a; | ||
} | ||
/** | ||
* Creates a new object with the source object nestled within its | ||
* prototype chain. | ||
* | ||
* @param {Object} source Method to insert into the new object's prototype. | ||
* @return {Object} An empty object with the source object in it's prototype chain. | ||
*/ | ||
createObject: Object.create || function createObject(source) { | ||
var Host = function () {}; | ||
Host.prototype = source; | ||
return new Host(); | ||
}, | ||
|
||
/** | ||
* Returns a recursive clone of the passed object. | ||
* So when you edit the original the clone will not change. | ||
* Used in prototypical inheritance. | ||
* It will not clone arrays. | ||
* | ||
* @param {Object} orig The original object to clone. | ||
* @return {Object} The cloned version of orig that can be edited without changing the original. | ||
*/ | ||
function clone(orig) { | ||
// Initialise variables | ||
var cl = {}; | ||
var key; | ||
/** | ||
* Mixes the specified object into your class. This can be used to add | ||
* certain capabilities and helper methods to a class that is already | ||
* inheriting from some other class. You can mix in as many object as | ||
* you want, but only inherit from one. | ||
* | ||
* These values are mixed into the actual prototype object of your | ||
* class, they are not added to the prototype chain like inherit. | ||
* | ||
* @param {Function} destination Class to mix the object into. | ||
* @param {Object} source Object to mix into the class. | ||
*/ | ||
mixin: function mixin(destination, source) { | ||
return heir.merge(destination.prototype, source); | ||
}, | ||
|
||
// Loop over all values in the object | ||
// If the value is an object then clone recursively | ||
// Otherwise just copy the value | ||
for (key in orig) { | ||
if (orig.hasOwnProperty(key)) { | ||
cl[key] = isObject(orig[key]) ? clone(orig[key]) : orig[key]; | ||
} | ||
} | ||
/** | ||
* Merges one object into another, change the object in place. | ||
* | ||
* @param {Object} destination The destination for the merge. | ||
* @param {Object} source The source of the properties to merge. | ||
*/ | ||
merge: function merge(destination, source) { | ||
var key; | ||
|
||
// Return the clone | ||
return cl; | ||
} | ||
|
||
/** | ||
* Inherits other functions prototype objects into the current function. | ||
* | ||
* @param {Function|Function[]} parent A function which should have it's prototype cloned and placed into the current functions prototype. If you pass an array of functions they will all be inherited from. | ||
* @param {Function} [forceFn] Optional function to use as the current function which is inheriting the other prototypes. It will default to `this`. | ||
* @return {Function} The current function to allow chaining. | ||
*/ | ||
function inherit(parent, forceFn) { | ||
// Initialise variables | ||
var fn = forceFn || this; | ||
var i; | ||
|
||
// If the parent variable is not a function then it must be an array | ||
// So we have to loop over it and inherit each of them | ||
// Remember to pass the current function instance! | ||
if (typeof parent !== 'function') { | ||
i = parent.length; | ||
while (i--) { | ||
inherit(parent[i], fn); | ||
for (key in source) { | ||
if (heir.hasOwn(source, key)) { | ||
destination[key] = source[key]; | ||
} | ||
} | ||
} | ||
else { | ||
// It is not an array, it is a plain function | ||
// Merge it's prototype into this one | ||
merge(fn.prototype, clone(parent.prototype)); | ||
} | ||
|
||
// Return the current function to allow chaining | ||
return fn; | ||
} | ||
}, | ||
|
||
// Expose the inherit function by placing it in the Function prototype | ||
Function.prototype.inherit = inherit; | ||
|
||
// Create a nice little namespace to expose | ||
var ns = { | ||
isObject: isObject, | ||
merge: merge, | ||
clone: clone, | ||
inherit: inherit | ||
/** | ||
* Shortcut for `Object.prototype.hasOwnProperty`. | ||
* | ||
* Uses `Object.prototype.hasOwnPropety` rather than | ||
* `object.hasOwnProperty` as it could be overwritten. | ||
* | ||
* @param {Object} object The object to check | ||
* @param {String} key The key to check for. | ||
* @return {Boolean} Does object have key as an own propety? | ||
*/ | ||
hasOwn: function hasOwn(object, key) { | ||
return Object.prototype.hasOwnProperty.call(object, key); | ||
} | ||
}; | ||
|
||
// And expose everything else either via AMD or a global object | ||
if (typeof define === 'function' && define.amd) { | ||
define(function () { | ||
return ns; | ||
}); | ||
} | ||
else if (typeof module === 'object' && module.exports) { | ||
module.exports = ns; | ||
} | ||
else { | ||
this.heir = ns; | ||
} | ||
}.call(this)); | ||
return heir; | ||
})); |
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
Oops, something went wrong.