Comparing version 1.1.0-a to 1.1.1
280
Base.js
/* | ||
Based on Base.js 1.1a (c) 2006-2010, Dean Edwards | ||
Updated to pass JSHint and converted into a module by Kenneth Powers | ||
License: http://www.opensource.org/licenses/mit-license.php | ||
Based on Base.js 1.1a (c) 2006-2010, Dean Edwards | ||
Updated to pass JSHint and converted into a module by Kenneth Powers | ||
License: http://www.opensource.org/licenses/mit-license.php | ||
*/ | ||
/*globals define:true window:true module:true*/ | ||
/*jshint boss:true eqeqeq:true*/ | ||
(function () { | ||
// Base Object | ||
var Base = function () {}; | ||
/*global define:true module:true*/ | ||
/*jshint eqeqeq:true*/ | ||
(function (name, global, definition) { | ||
if (typeof module !== 'undefined') { | ||
module.exports = definition(); | ||
} else if (typeof define !== 'undefined' && typeof define.amd === 'object') { | ||
define(definition); | ||
} else { | ||
global[name] = definition(); | ||
} | ||
})('Base', this, function () { | ||
// Base Object | ||
var Base = function () {}; | ||
// Define AMD module or attach Base object to head object | ||
if (typeof define !== 'undefined') | ||
// AMD Module | ||
define(function () { | ||
return Base; | ||
}); | ||
else if (typeof window !== 'undefined') | ||
// Browser | ||
window.Base = Base; | ||
else | ||
// CommonJS | ||
module.exports = Base; | ||
// Implementation | ||
Base.extend = function (_instance, _static) { // subclass | ||
var extend = Base.prototype.extend; | ||
// build the prototype | ||
Base._prototyping = true; | ||
var proto = new this(); | ||
extend.call(proto, _instance); | ||
proto.base = function () { | ||
// call this method from any other method to invoke that method's ancestor | ||
}; | ||
delete Base._prototyping; | ||
// create the wrapper for the constructor function | ||
//var constructor = proto.constructor.valueOf(); //-dean | ||
var constructor = proto.constructor; | ||
var klass = proto.constructor = function () { | ||
if (!Base._prototyping) { | ||
if (this._constructing || this.constructor === klass) { // instantiation | ||
this._constructing = true; | ||
constructor.apply(this, arguments); | ||
delete this._constructing; | ||
} else if (arguments[0] !== null) { // casting | ||
return (arguments[0].extend || extend).call(arguments[0], proto); | ||
} | ||
} | ||
}; | ||
// build the class interface | ||
klass.ancestor = this; | ||
klass.extend = this.extend; | ||
klass.forEach = this.forEach; | ||
klass.implement = this.implement; | ||
klass.prototype = proto; | ||
klass.toString = this.toString; | ||
klass.valueOf = function (type) { | ||
return (type === 'object') ? klass : constructor.valueOf(); | ||
}; | ||
extend.call(klass, _static); | ||
// class initialization | ||
if (typeof klass.init === 'function') klass.init(); | ||
return klass; | ||
}; | ||
// Implementation | ||
Base.extend = function (_instance, _static) { // subclass | ||
var extend = Base.prototype.extend; | ||
// build the prototype | ||
Base._prototyping = true; | ||
var proto = new this(); | ||
extend.call(proto, _instance); | ||
proto.base = function () { | ||
// call this method from any other method to invoke that method's ancestor | ||
}; | ||
delete Base._prototyping; | ||
// create the wrapper for the constructor function | ||
//var constructor = proto.constructor.valueOf(); //-dean | ||
var constructor = proto.constructor; | ||
var klass = proto.constructor = function () { | ||
if (!Base._prototyping) { | ||
if (this._constructing || this.constructor === klass) { // instantiation | ||
this._constructing = true; | ||
constructor.apply(this, arguments); | ||
delete this._constructing; | ||
} else if (arguments[0] !== null) { // casting | ||
return (arguments[0].extend || extend).call(arguments[0], proto); | ||
} | ||
} | ||
}; | ||
// build the class interface | ||
klass.ancestor = this; | ||
klass.extend = this.extend; | ||
klass.forEach = this.forEach; | ||
klass.implement = this.implement; | ||
klass.prototype = proto; | ||
klass.toString = this.toString; | ||
klass.valueOf = function (type) { | ||
return (type === 'object') ? klass : constructor.valueOf(); | ||
}; | ||
extend.call(klass, _static); | ||
// class initialization | ||
if (typeof klass.init === 'function') klass.init(); | ||
return klass; | ||
}; | ||
Base.prototype = { | ||
extend: function (source, value) { | ||
if (arguments.length > 1) { // extending with a name/value pair | ||
var ancestor = this[source]; | ||
if (ancestor && (typeof value === 'function') && // overriding a method? | ||
// the valueOf() comparison is to avoid circular references | ||
(!ancestor.valueOf || ancestor.valueOf() !== value.valueOf()) && /\bbase\b/.test(value)) { | ||
// get the underlying method | ||
var method = value.valueOf(); | ||
// override | ||
value = function () { | ||
var previous = this.base || Base.prototype.base; | ||
this.base = ancestor; | ||
var returnValue = method.apply(this, arguments); | ||
this.base = previous; | ||
return returnValue; | ||
}; | ||
// point to the underlying method | ||
value.valueOf = function (type) { | ||
return (type === 'object') ? value : method; | ||
}; | ||
value.toString = Base.toString; | ||
} | ||
this[source] = value; | ||
} else if (source) { // extending with an object literal | ||
var extend = Base.prototype.extend; | ||
// if this object has a customized extend method then use it | ||
if (!Base._prototyping && typeof this !== 'function') { | ||
extend = this.extend || extend; | ||
} | ||
var proto = { | ||
toSource: null | ||
}; | ||
// do the "toString" and other methods manually | ||
var hidden = ['constructor', 'toString', 'valueOf']; | ||
// if we are prototyping then include the constructor | ||
for (var i = Base._prototyping ? 0 : 1; i < hidden.length; i++) { | ||
var h = hidden[i]; | ||
if (source[h] !== proto[h]) | ||
extend.call(this, h, source[h]); | ||
} | ||
// copy each of the source object's properties to this object | ||
for (var key in source) { | ||
if (!proto[key]) extend.call(this, key, source[key]); | ||
} | ||
} | ||
return this; | ||
} | ||
}; | ||
Base.prototype = { | ||
extend: function (source, value) { | ||
if (arguments.length > 1) { // extending with a name/value pair | ||
var ancestor = this[source]; | ||
if (ancestor && (typeof value === 'function') && // overriding a method? | ||
// the valueOf() comparison is to avoid circular references | ||
(!ancestor.valueOf || ancestor.valueOf() !== value.valueOf()) && /\bbase\b/.test(value)) { | ||
// get the underlying method | ||
var method = value.valueOf(); | ||
// override | ||
value = function () { | ||
var previous = this.base || Base.prototype.base; | ||
this.base = ancestor; | ||
var returnValue = method.apply(this, arguments); | ||
this.base = previous; | ||
return returnValue; | ||
}; | ||
// point to the underlying method | ||
value.valueOf = function (type) { | ||
return (type === 'object') ? value : method; | ||
}; | ||
value.toString = Base.toString; | ||
} | ||
this[source] = value; | ||
} else if (source) { // extending with an object literal | ||
var extend = Base.prototype.extend; | ||
// if this object has a customized extend method then use it | ||
if (!Base._prototyping && typeof this !== 'function') { | ||
extend = this.extend || extend; | ||
} | ||
var proto = { | ||
toSource: null | ||
}; | ||
// do the "toString" and other methods manually | ||
var hidden = ['constructor', 'toString', 'valueOf']; | ||
// if we are prototyping then include the constructor | ||
for (var i = Base._prototyping ? 0 : 1; i < hidden.length; i++) { | ||
var h = hidden[i]; | ||
if (source[h] !== proto[h]) | ||
extend.call(this, h, source[h]); | ||
} | ||
// copy each of the source object's properties to this object | ||
for (var key in source) { | ||
if (!proto[key]) extend.call(this, key, source[key]); | ||
} | ||
} | ||
return this; | ||
} | ||
}; | ||
// initialize | ||
Base = Base.extend({ | ||
constructor: function () { | ||
this.extend(arguments[0]); | ||
} | ||
}, { | ||
ancestor: Object, | ||
version: '1.1', | ||
forEach: function (object, block, context) { | ||
for (var key in object) { | ||
if (this.prototype[key] === undefined) { | ||
block.call(context, object[key], key, object); | ||
} | ||
} | ||
}, | ||
implement: function () { | ||
for (var i = 0; i < arguments.length; i++) { | ||
if (typeof arguments[i] === 'function') { | ||
// if it's a function, call it | ||
arguments[i](this.prototype); | ||
} else { | ||
// add the interface using the extend method | ||
this.prototype.extend(arguments[i]); | ||
} | ||
} | ||
return this; | ||
}, | ||
toString: function () { | ||
return String(this.valueOf()); | ||
} | ||
}); | ||
// initialize | ||
Base = Base.extend({ | ||
constructor: function () { | ||
this.extend(arguments[0]); | ||
} | ||
}, { | ||
ancestor: Object, | ||
version: '1.1', | ||
forEach: function (object, block, context) { | ||
for (var key in object) { | ||
if (this.prototype[key] === undefined) { | ||
block.call(context, object[key], key, object); | ||
} | ||
} | ||
}, | ||
implement: function () { | ||
for (var i = 0; i < arguments.length; i++) { | ||
if (typeof arguments[i] === 'function') { | ||
// if it's a function, call it | ||
arguments[i](this.prototype); | ||
} else { | ||
// add the interface using the extend method | ||
this.prototype.extend(arguments[i]); | ||
} | ||
} | ||
return this; | ||
}, | ||
toString: function () { | ||
return String(this.valueOf()); | ||
} | ||
}); | ||
})(); | ||
// Return Base implementation | ||
return Base; | ||
}); |
{ | ||
"name": "basejs", | ||
"description": "Simple class-based inheritance for JavaScript (based on Dean Edwards' Base.js).", | ||
"version": "1.1.0a", | ||
"version": "1.1.1", | ||
"author": { | ||
@@ -15,2 +15,2 @@ "name": "Kenneth Powers", | ||
] | ||
} | ||
} |
108
README.md
# Base.js Module | ||
This is a modular version of Dean Edward's [Base.js](http://dean.edwards.name/weblog/2006/03/base/). The script first checks to see if it is in an [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD) environment and if it is defines an AMD module. If the current environment is not an AMD environment then the script checks to see if it is in a web browser and attaches the `Base` constructor to the `window` object. If those two tests fail then it is assumed that the script is running in a CommonJS environment and it assigns `module.exports` to be a reference to the `Base` constructor. | ||
This is a modular version of Dean Edward's [Base.js](http://dean.edwards.name/weblog/2006/03/base/). The same script will work the same in CommonJS Environments (such as [node.js](http://nodejs.org/)), AMD Environments (such as [RequireJS](http://requirejs.org/)), and plain browser environments. | ||
@@ -9,20 +9,16 @@ In addition to modularizing the code I have also updated the entire implementation so that it passes [JSHint](http://www.jshint.com/) (with default settings in the installed version -- the web version turns on `strict` by default). | ||
<script src="/path/to/Base.js"></script> | ||
<script src="/path/to/Base.js"></script> | ||
The second way to get started is to include the script as a dependency for an AMD application or module (using something such as [RequireJS](http://requirejs.org/)): | ||
:::javascript | ||
require('/path/to/Base', function (Base) { | ||
// You may now use Base.js as "Base" here. | ||
// Remember, AMD modules don't use the .js extension! | ||
}); | ||
require('/path/to/Base', function (Base) { | ||
// You may now use Base.js as "Base" here. | ||
}); | ||
The third and final way to get started is to `require` the module in a CommonJS environment (such as [node.js](http://nodejs.org/)): | ||
:::javascript | ||
var Base = require('./path/to/Base'); | ||
var Base = require('./path/to/Base'); | ||
If you are using [node.js](http://nodejs.org/) with [npm](http://npmjs.org) then you can also install the module as follows: | ||
:::text | ||
npm install basejs | ||
@@ -32,4 +28,3 @@ | ||
:::javascript | ||
var Base = require('basejs'); | ||
var Base = require('basejs'); | ||
@@ -39,35 +34,35 @@ # Defining Classes | ||
:::javascript | ||
// Define Animal class | ||
var Animal = Base.extend({ | ||
constructor: function (name) { | ||
this.name = name; | ||
}, | ||
name: '', | ||
eat: function () { | ||
this.say('Yum!'); | ||
}, | ||
say: function (message) { | ||
console.log((this.name !== '' ? this.name + ': ' : this.name) + message); | ||
} | ||
}); | ||
// Define Animal class | ||
var Animal = Base.extend({ | ||
constructor: function (name) { | ||
this.name = name; | ||
}, | ||
name: '', | ||
eat: function () { | ||
this.say('Yum!'); | ||
}, | ||
say: function (message) { | ||
console.log((this.name !== '' ? this.name + ': ' : this.name) + message); | ||
} | ||
}); | ||
// Define the Cat class which extends Animal | ||
var Cat = Animal.extend({ | ||
eat: function (food) { | ||
if (food instanceof Mouse) | ||
this.base(); | ||
else | ||
this.say('Yuk! I only eat mice.'); | ||
} | ||
}); | ||
// Define the Cat class which extends Animal | ||
var Cat = Animal.extend({ | ||
eat: function (food) { | ||
if (food instanceof Mouse) { | ||
this.base(); | ||
} else { | ||
this.say('Yuk! I only eat mice.'); | ||
} | ||
} | ||
}); | ||
// Define the a few more animals | ||
var Mouse = Animal.extend(); | ||
var Dog = Animal.extend(); | ||
// Define a few more animals | ||
var Mouse = Animal.extend(); | ||
var Dog = Animal.extend(); | ||
// Try out the classes | ||
var kitty = new Cat('Kitty'); | ||
kitty.eat(new Mouse()); // logs "Yum!" | ||
kitty.eat(new Dog()); // logs "Yuk! I only eat mice." | ||
// Try out the classes | ||
var kitty = new Cat('Kitty'); | ||
kitty.eat(new Mouse()); // logs "Yum!" | ||
kitty.eat(new Dog()); // logs "Yuk! I only eat mice." | ||
@@ -78,15 +73,14 @@ Notice the use of `this.base()`. `this.base()` is how you access the parent's method. This works in all methods (including constructors). | ||
:::javascript | ||
var Circle = Shape.extend({ // instance properties / methods | ||
constructor: function (x, y, radius) { | ||
this.base(x, y); | ||
this.radius = radius; | ||
}, | ||
radius: 0, | ||
getCircumference: function () { | ||
return 2 * Circle.PI * this.radius; | ||
} | ||
}, { // class properties / methods | ||
PI: 3.14 | ||
}); | ||
var Circle = Shape.extend({ // instance properties / methods | ||
constructor: function (x, y, radius) { | ||
this.base(x, y); | ||
this.radius = radius; | ||
}, | ||
radius: 0, | ||
getCircumference: function () { | ||
return 2 * Circle.PI * this.radius; | ||
} | ||
}, { // class properties / methods | ||
PI: 3.14 | ||
}); | ||
@@ -99,3 +93,3 @@ For more details including private data and singleton objects check out Dean Edward's [original documentation](http://dean.edwards.name/weblog/2006/03/base/). | ||
Based on Base.js 1.1a (c) 2006 - 2010 Dean Edwards | ||
Based on Base.js 1.1a (c) 2006 - 2010 Dean Edwards | ||
Updated to pass JSHint and converted into a Module format by Kenneth Powers | ||
@@ -107,2 +101,2 @@ | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
10751
1
0
141
97