More Bootstrap.js simplifications.

This commit is contained in:
Jürg Lehni 2012-11-03 22:24:42 -07:00
parent 6ed1d67ada
commit a51f5af9c8

65
lib/bootstrap.js vendored
View file

@ -39,18 +39,16 @@ var Base = new function() { // Bootstrap scope
if (this.hasOwnProperty(i))
iter.call(bind, this[i], i, this);
},
_create = Object.create,
// A ahort cut to a simplified version of Object.create that only
// supports the first parameter (in the emulation):
create = Object.create || function(proto) {
// From all browsers that do not offer Object.create(), we only
// support Firefox 3.5 & 3.5, but luckily this hack works there:
return { __proto__: proto };
},
_define = Object.defineProperty,
_describe = Object.getOwnPropertyDescriptor;
function create(ctor) {
return _create
? _create(ctor.prototype)
// We only support Firefox 3.5 that does not offer Object.create,
// but luckily it supports this hack:
: { __proto__: ctor.prototype };
}
// Support a mixed environment of some ECMAScript 5 features present,
// along with __defineGetter/Setter__ functions, as found in browsers today.
function define(obj, name, desc) {
@ -205,27 +203,6 @@ var Base = new function() { // Bootstrap scope
return dest;
}
/**
* Private function that creates a constructor to extend the given object.
* When this constructor is called through new, a new object is craeted
* that inherits all from obj.
*/
function extend(obj) {
// Create the constructor for the new prototype that calls initialize
// if it is defined.
var ctor = function() {
// Call the constructor function, if defined
if (this.initialize)
return this.initialize.apply(this, arguments);
};
ctor.prototype = obj;
// Add a toString function that delegates to initialize if possible
ctor.toString = function() {
return (this.prototype.initialize || function() {}).toString();
};
return ctor;
}
/**
* Converts the argument to an iterator function. If none is specified, the
* identity function is returned.
@ -287,11 +264,19 @@ var Base = new function() { // Bootstrap scope
},
extend: function(src/* , ... */) {
var proto = create(this),
ctor = extend(proto);
var ctor = function() {
// Call the constructor function, if defined
if (this.initialize)
return this.initialize.apply(this, arguments);
};
ctor.prototype = create(this.prototype);
// Add a toString function that delegates to initialize if possible
ctor.toString = function() {
return (this.prototype.initialize || function() {}).toString();
};
// The new prototype extends the constructor on which extend is
// called. Fix constructor.
define(proto, 'constructor',
define(ctor.prototype, 'constructor',
{ value: ctor, writable: true, configurable: true });
// Copy over static fields, as prototype-like inheritance
// is not possible for static fields. Mark them as enumerable
@ -332,13 +317,7 @@ var Base = new function() { // Bootstrap scope
* of Function.prototype.extend.
*/
extend: function(/* src, ... */) {
// Notice the "new" here: the private extend returns a constructor
// as it's used for Function.prototype.extend as well. But when
// extending objects, we want to return a new object that inherits
// from "this". In that case, the constructor is never used again,
// its just created to create a new object with the proper
// inheritance set and is garbage collected right after.
var res = new (extend(this));
var res = create(this);
return res.inject.apply(res, arguments);
},
@ -358,7 +337,11 @@ var Base = new function() { // Bootstrap scope
// Expose some local privates as Base generics.
each: each,
clone: clone,
create: create,
// Base.create does something different from Object.create, it only
// works on constructors and uses their prototype.
create: function(ctor) {
return create(ctor.prototype);
},
define: define,
describe: describe,
iterator: iterator,