paper.js/lib/bootstrap.js
2011-03-04 21:46:50 +00:00

251 lines
7 KiB
JavaScript

/**
* Bootstrap JavaScript Library
* (c) 2006 - 2010 Juerg Lehni, http://scratchdisk.com/
*
* Bootstrap is released under the MIT license
* http://bootstrap-js.net/
*
* Inspirations:
* http://dean.edwards.name/weblog/2006/03/base/
* http://dev.helma.org/Wiki/JavaScript+Inheritance+Sugar/
* http://prototypejs.org/
* http://mootools.net/
*
* Some code in this file is based on Mootools.net and adapted to the
* architecture of Bootstrap, with added changes in design and architecture
* where deemeded necessary.
* See http://www.bootstrap-js.net/wiki/MootoolsDifferences
*/
var Base = new function() {
var fix = !this.__proto__,
has = fix ? function(name) {
return name != '__proto__' && this.hasOwnProperty(name);
} : {}.hasOwnProperty,
slice = Array.prototype.slice,
forEach = Array.prototype.forEach || function(iter, bind) {
for (var i = 0, l = this.length; i < l; i++)
iter.call(bind, this[i], i, this);
},
isArray = Array.isArray || function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
},
_define = Object.defineProperty,
_describe = Object.getOwnPropertyDescriptor;
function define(obj, name, desc) {
if (_define)
try { delete obj[name]; return _define(obj, name, desc); } catch (e) {}
if ((desc.get || desc.set) && obj.__defineGetter__) {
if (desc.get) obj.__defineGetter__(name, desc.get);
if (desc.set) obj.__defineSetter__(name, desc.set);
} else {
obj[name] = desc.value;
}
return obj;
}
function describe(obj, name) {
if (_describe)
try { return _describe(obj, name); } catch (e) {}
var get = obj.__lookupGetter__ && obj.__lookupGetter__(name);
return get
? { enumerable: true, configurable: true, get: get, set: obj.__lookupSetter__(name) }
: has.call(obj, name)
? { enumerable: true, configurable: true, writable: true, value: obj[name] }
: null;
}
function inject(dest, src, enumerable, base, preserve, generics) {
var beans, bean;
function field(name, val, dontCheck, generics) {
var val = val || (val = describe(src, name)) && (val.get ? val : val.value),
func = typeof val == 'function', res = val,
prev = preserve || func ? (val && val.get ? name in dest : dest[name]) : null;
if (generics && func && (!preserve || !generics[name])) generics[name] = function(bind) {
return bind && dest[name].apply(bind, slice.call(arguments, 1));
}
if ((dontCheck || val !== undefined && has.call(src, name)) && (!preserve || !prev)) {
if (func) {
if (prev && /\bthis\.base\b/.test(val)) {
var fromBase = base && base[name] == prev;
res = (function() {
var tmp = describe(this, 'base');
define(this, 'base', { value: fromBase ? base[name] : prev, configurable: true });
try { return val.apply(this, arguments); }
finally { tmp ? define(this, 'base', tmp) : delete this.base; }
}).pretend(val);
}
if (beans && (bean = name.match(/^(get|is)(([A-Z])(.*))$/)))
beans.push([ bean[3].toLowerCase() + bean[4], bean[2] ]);
}
if (!res || func || !res.get && !res.set)
res = { value: res, writable: true };
if ((describe(dest, name) || { configurable: true }).configurable) {
res.configurable = true;
res.enumerable = enumerable;
}
define(dest, name, res);
}
}
if (src) {
beans = src.beans && [];
for (var name in src)
if (has.call(src, name) && !/^(statics|generics|preserve|beans|prototype|__proto__|toString|valueOf)$/.test(name))
field(name, null, true, generics);
field('toString');
field('valueOf');
for (var i = 0, l = beans && beans.length; i < l; i++)
try {
var bean = beans[i], part = bean[1];
field(bean[0], {
get: dest['get' + part] || dest['is' + part],
set: dest['set' + part]
}, true);
} catch (e) {}
}
}
function extend(obj) {
function ctor(dont) {
if (fix) define(this, '__proto__', { value: obj });
if (this.initialize && dont !== ctor.dont)
return this.initialize.apply(this, arguments);
}
ctor.prototype = obj;
ctor.toString = function() {
return (this.prototype.initialize || function() {}).toString();
}
return ctor;
}
inject(Function.prototype, {
inject: function(src) {
if (src) {
var proto = this.prototype, base = proto.__proto__ && proto.__proto__.constructor;
inject(proto, src, false, base && base.prototype, src.preserve, src.generics && this);
inject(this, src.statics, true, base, src.preserve);
}
for (var i = 1, l = arguments.length; i < l; i++)
this.inject(arguments[i]);
return this;
},
extend: function(src) {
var proto = new this(this.dont), ctor = extend(proto);
define(proto, 'constructor', { value: ctor, writable: true, configurable: true });
ctor.dont = {};
inject(ctor, this, true);
return arguments.length ? this.inject.apply(ctor, arguments) : ctor;
},
pretend: function(fn) {
this.toString = function() {
return fn.toString();
}
this.valueOf = function() {
return fn.valueOf();
}
return this;
}
});
function each(iter, bind) {
var bind = bind || this, iter = iterator(iter);
try {
if (isArray(this)) {
forEach.call(this, iter, bind);
} else {
for (var i in this)
if (this.hasOwnProperty(i))
iter.call(bind, this[i], i, this);
}
} catch (e) {
if (e !== Base.stop) throw e;
}
return bind;
}
function iterator(iter) {
return !iter
? function(val) { return val }
: typeof iter != 'function'
? function(val) { return val == iter }
: iter;
}
function clone(obj) {
return each.call(obj, function(val, i) {
this[i] = val;
}, new obj.constructor());
}
return Object.extend({
has: has,
each: each,
inject: function() {
for (var i = 0, l = arguments.length; i < l; i++)
inject(this, arguments[i]);
return this;
},
extend: function() {
var res = new (extend(this));
return res.inject.apply(res, arguments);
},
clone: function() {
return clone(this);
},
statics: {
// TODO: Use generics?
has: function(obj, name) {
return has.call(obj, name);
},
each: function(obj, iter, bind) {
return each.call(obj, iter, bind);
},
clone: clone,
define: define,
describe: describe,
iterator: iterator,
isArray: isArray,
type: function(obj) {
return (obj || obj === 0) && (obj._type || typeof obj) || null;
},
check: function(obj) {
return !!(obj || obj === 0);
},
pick: function() {
for (var i = 0, l = arguments.length; i < l; i++)
if (arguments[i] !== undefined)
return arguments[i];
return null;
},
read: function(args, index, length) {
var index = index || 0, length = length || args.length - index;
if (length <= 1) {
var arg = args[index];
// Return null when nothing was provided
if (arg instanceof this || arg == null)
return arg;
}
var obj = new this(this.dont);
obj = obj.initialize.apply(obj, index > 0 || length < args.length
? slice.call(args, index, index + length)
: args) || obj;
return obj;
},
stop: {}
}
});
}