mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2024-12-29 09:22:22 -05:00
Switch Bootstrap.js version to one with beans support
This commit is contained in:
parent
e234b3735c
commit
59a4c1183b
1 changed files with 96 additions and 31 deletions
127
src/Bootstrap.js
127
src/Bootstrap.js
|
@ -34,23 +34,36 @@ new function() { // Bootstrap scope
|
||||||
* Object.prototype.has, as the local version then seems to be overriden
|
* Object.prototype.has, as the local version then seems to be overriden
|
||||||
* by that. Giving it a idfferent name fixes it.
|
* by that. Giving it a idfferent name fixes it.
|
||||||
*/
|
*/
|
||||||
// Check if environment supports hasOwnProperty, and use a differnt version
|
function has(obj, name) {
|
||||||
// of has if ti does, for higher performance as checking on each has() call.
|
return (!fix || name != '__proto__') && obj.hasOwnProperty(name);
|
||||||
// All Browsers that need (IE and Opera) have hasOwnProperty, so
|
}
|
||||||
// the version without hasOwnProperty does not need to check for __proto__
|
|
||||||
var has = {}.hasOwnProperty
|
// Support a mixed environment of some ECMAScript 5 features present,
|
||||||
? function(obj, name) {
|
// along with __defineGetter/Setter__ functions, as found in browsers today.
|
||||||
return (!fix || name != '__proto__') && obj.hasOwnProperty(name);
|
var _define = Object.defineProperty, _describe = Object.getOwnPropertyDescriptor;
|
||||||
|
|
||||||
|
function define(obj, name, desc) {
|
||||||
|
if (_define)
|
||||||
|
try { return _define(obj, name, desc); } catch (e) {}
|
||||||
|
if ((desc.get || desc.set) && obj.__defineGetter__) {
|
||||||
|
if (desc.get) obj.__defineGetter__(obj, desc.get);
|
||||||
|
if (desc.set) obj.__defineSetter__(obj, desc.set);
|
||||||
|
} else {
|
||||||
|
obj[name] = desc.value;
|
||||||
}
|
}
|
||||||
: function(obj, name) {
|
return obj;
|
||||||
// We need to filter out what does not belong to the object itself.
|
}
|
||||||
// This is done by comparing the value with the value of the same
|
|
||||||
// name in the prototype. If the value is equal it's defined in one
|
function describe(obj, name) {
|
||||||
// of the prototypes, not the object itself.
|
if (_describe)
|
||||||
// Object.prototype is untouched, so we cannot assume __proto__ to
|
try { return _describe(obj, name); } catch (e) {}
|
||||||
// always be defined on legacy browsers.
|
var get = obj.__lookupGetter__ && obj.__lookupGetter__(name);
|
||||||
return obj[name] !== (obj.__proto__ || Object.prototype)[name];
|
return get
|
||||||
};
|
? { enumerable: true, configurable: true, get: get, set: obj.__lookupSetter__(name) }
|
||||||
|
: has(obj, name)
|
||||||
|
? { enumerable: true, configurable: true, writable: true, value: obj[name] }
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private function that injects functions from src into dest, overriding
|
* Private function that injects functions from src into dest, overriding
|
||||||
|
@ -62,9 +75,13 @@ new function() { // Bootstrap scope
|
||||||
/**
|
/**
|
||||||
* Private function that injects one field with given name
|
* Private function that injects one field with given name
|
||||||
*/
|
*/
|
||||||
function field(name, dontCheck, generics) {
|
function field(name, val, dontCheck, generics) {
|
||||||
var val = src[name], func = typeof val == 'function', res = val,
|
// This does even work for prop: 0, as it will just be looked up
|
||||||
prev = dest[name];
|
// again through describe...
|
||||||
|
if (!val)
|
||||||
|
val = (val = describe(src, name)) && (val.get ? val : val.value);
|
||||||
|
var type = typeof val, func = type == 'function', res = val,
|
||||||
|
prev = dest[name], bean;
|
||||||
// Make generics first, as we might jump out bellow in the
|
// Make generics first, as we might jump out bellow in the
|
||||||
// val !== (src.__proto__ || Object.prototype)[name] check,
|
// val !== (src.__proto__ || Object.prototype)[name] check,
|
||||||
// e.g. when explicitely reinjecting Array.prototype methods
|
// e.g. when explicitely reinjecting Array.prototype methods
|
||||||
|
@ -86,14 +103,37 @@ new function() { // Bootstrap scope
|
||||||
// Look up the base function each time if we can,
|
// Look up the base function each time if we can,
|
||||||
// to reflect changes to the base class after
|
// to reflect changes to the base class after
|
||||||
// inheritance.
|
// inheritance.
|
||||||
var tmp = this.base;
|
var tmp = describe(this, 'base');
|
||||||
this.base = fromBase ? base[name] : prev;
|
define(this, 'base', { value: fromBase ? base[name] : prev, configurable: true });
|
||||||
try { return val.apply(this, arguments); }
|
try { return val.apply(this, arguments); }
|
||||||
finally { tmp ? this.base = tmp : delete this.base; }
|
finally { tmp ? define(this, 'base', tmp) : delete this.base; }
|
||||||
}).pretend(val);
|
}).pretend(val);
|
||||||
}
|
}
|
||||||
|
// Only set produce bean properties when getters are
|
||||||
|
// specified. This does not produce properties for setter-
|
||||||
|
// only properties which makes sense and also avoids double-
|
||||||
|
// injection for beans with both getters and setters.
|
||||||
|
if (src.beans && (bean = name.match(/^(get|is)(([A-Z])(.*))$/)))
|
||||||
|
try {
|
||||||
|
field(bean[3].toLowerCase() + bean[4], {
|
||||||
|
get: src['get' + bean[2]] || src['is' + bean[2]],
|
||||||
|
set: src['set' + bean[2]]
|
||||||
|
}, true);
|
||||||
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
dest[name] = res;
|
// No need to look up getter if this is a function already.
|
||||||
|
// This also prevents _collection from becoming a getter, as
|
||||||
|
// DomElements is a constructor function and has both get / set
|
||||||
|
// generics for DomElement#get / #set.
|
||||||
|
if (!res || func || !res.get && !res.set)
|
||||||
|
res = { value: res, writable: true };
|
||||||
|
// Only set/change configurable and enumerable if this field is
|
||||||
|
// configurable
|
||||||
|
if ((describe(dest, name) || { configurable: true }).configurable) {
|
||||||
|
res.configurable = true;
|
||||||
|
res.enumerable = enumerable;
|
||||||
|
}
|
||||||
|
define(dest, name, res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Iterate through all definitions in src with an iteator function
|
// Iterate through all definitions in src with an iteator function
|
||||||
|
@ -105,8 +145,8 @@ new function() { // Bootstrap scope
|
||||||
// dest[name] then is set to either src[name] or the wrapped function.
|
// dest[name] then is set to either src[name] or the wrapped function.
|
||||||
if (src) {
|
if (src) {
|
||||||
for (var name in src)
|
for (var name in src)
|
||||||
if (has(src, name) && !/^(statics|generics|preserve|prototype|constructor|__proto__|toString|valueOf)$/.test(name))
|
if (has(src, name) && !/^(statics|generics|preserve|beans|prototype|__proto__|toString|valueOf)$/.test(name))
|
||||||
field(name, true, generics);
|
field(name, null, true, generics);
|
||||||
// IE (and some other browsers?) never enumerate these, even
|
// IE (and some other browsers?) never enumerate these, even
|
||||||
// if they are simply set on an object. Force their creation.
|
// if they are simply set on an object. Force their creation.
|
||||||
// Do not create generics for these, and check them for not
|
// Do not create generics for these, and check them for not
|
||||||
|
@ -126,7 +166,7 @@ new function() { // Bootstrap scope
|
||||||
// if it is defined.
|
// if it is defined.
|
||||||
function ctor(dont) {
|
function ctor(dont) {
|
||||||
// Fix __proto__
|
// Fix __proto__
|
||||||
if (fix) this.__proto__ = obj;
|
if (fix) define(this, '__proto__', { value: obj });
|
||||||
// Call the constructor function, if defined and we're not inheriting
|
// Call the constructor function, if defined and we're not inheriting
|
||||||
// in which case ctor.dont would be set, see further bellow.
|
// in which case ctor.dont would be set, see further bellow.
|
||||||
if (this.initialize && dont !== ctor.dont)
|
if (this.initialize && dont !== ctor.dont)
|
||||||
|
@ -168,7 +208,8 @@ new function() { // Bootstrap scope
|
||||||
// Fix constructor
|
// Fix constructor
|
||||||
// TODO: Consider using Object.create instead of using this.dont if
|
// TODO: Consider using Object.create instead of using this.dont if
|
||||||
// available?
|
// available?
|
||||||
var proto = new this(this.dont), ctor = proto.constructor = extend(proto);
|
var proto = new this(this.dont), ctor = extend(proto);
|
||||||
|
define(proto, 'constructor', { value: ctor, writable: true, configurable: true });
|
||||||
// An object to be passed as the first parameter in constructors
|
// An object to be passed as the first parameter in constructors
|
||||||
// when initialize should not be called. This needs to be a property
|
// when initialize should not be called. This needs to be a property
|
||||||
// of the created constructor, so that if .extend is called on native
|
// of the created constructor, so that if .extend is called on native
|
||||||
|
@ -254,6 +295,8 @@ new function() { // Bootstrap scope
|
||||||
// Expose some local privates as Base generics.
|
// Expose some local privates as Base generics.
|
||||||
has: has,
|
has: has,
|
||||||
each: each,
|
each: each,
|
||||||
|
define: define,
|
||||||
|
describe: describe,
|
||||||
|
|
||||||
type: function(obj) {
|
type: function(obj) {
|
||||||
// Handle elements, as needed by DomNode.js
|
// Handle elements, as needed by DomNode.js
|
||||||
|
@ -590,11 +633,12 @@ Hash = Base.extend(Enumerable, {
|
||||||
// Do not use Object.keys for iteration as iterators might modify
|
// Do not use Object.keys for iteration as iterators might modify
|
||||||
// the object we're iterating over, making the hasOwnProperty still
|
// the object we're iterating over, making the hasOwnProperty still
|
||||||
// necessary.
|
// necessary.
|
||||||
// Rely on Base.has instead of hasOwnProperty directly.
|
// If is used, we can fully rely on hasOwnProperty,
|
||||||
var bind = bind || this, iter = Base.iterator(iter), has = Base.has;
|
// as even for , define(this, '__proto__', {}) is used.
|
||||||
|
var bind = bind || this, iter = Base.iterator(iter);
|
||||||
try {
|
try {
|
||||||
for (var i in this)
|
for (var i in this)
|
||||||
if (has(this, i))
|
if (this.hasOwnProperty(i))
|
||||||
iter.call(bind, this[i], i, this);
|
iter.call(bind, this[i], i, this);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e !== Base.stop) throw e;
|
if (e !== Base.stop) throw e;
|
||||||
|
@ -752,6 +796,7 @@ Array.inject({
|
||||||
}, Enumerable, {
|
}, Enumerable, {
|
||||||
// TODO: this.each / this.findEntry / this.indexOf breaks many generics!
|
// TODO: this.each / this.findEntry / this.indexOf breaks many generics!
|
||||||
generics: true,
|
generics: true,
|
||||||
|
beans: true,
|
||||||
|
|
||||||
each: function(iter, bind) {
|
each: function(iter, bind) {
|
||||||
try {
|
try {
|
||||||
|
@ -1677,6 +1722,7 @@ DomNode = Base.extend(new function() {
|
||||||
var dont = {};
|
var dont = {};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
beans: true,
|
||||||
// Tells Base.type the type to return when encountering an node.
|
// Tells Base.type the type to return when encountering an node.
|
||||||
_type: 'node',
|
_type: 'node',
|
||||||
_collection: DomNodes,
|
_collection: DomNodes,
|
||||||
|
@ -1934,6 +1980,7 @@ DomNode.inject(new function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var fields = {
|
var fields = {
|
||||||
|
beans: true,
|
||||||
_properties: ['text'],
|
_properties: ['text'],
|
||||||
|
|
||||||
set: function(name, value) {
|
set: function(name, value) {
|
||||||
|
@ -2234,6 +2281,7 @@ DomElements = DomNodes.extend();
|
||||||
// DomElement
|
// DomElement
|
||||||
|
|
||||||
DomElement = DomNode.extend({
|
DomElement = DomNode.extend({
|
||||||
|
beans: true,
|
||||||
// Tells Base.type the type to return when encountering an element.
|
// Tells Base.type the type to return when encountering an element.
|
||||||
_type: 'element',
|
_type: 'element',
|
||||||
_collection: DomElements,
|
_collection: DomElements,
|
||||||
|
@ -2309,6 +2357,7 @@ DomElement.inject(new function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
beans: true,
|
||||||
_properties: ['id'],
|
_properties: ['id'],
|
||||||
|
|
||||||
getTag: function() {
|
getTag: function() {
|
||||||
|
@ -2393,6 +2442,7 @@ DomTextNode = DomNode.extend({
|
||||||
// DomDocument
|
// DomDocument
|
||||||
|
|
||||||
DomDocument = DomElement.extend({
|
DomDocument = DomElement.extend({
|
||||||
|
beans: true,
|
||||||
_type: 'document',
|
_type: 'document',
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
|
@ -2445,6 +2495,7 @@ DomDocument = DomElement.extend({
|
||||||
// Let Window point to DomWindow for now, so new Window(...) can be called.
|
// Let Window point to DomWindow for now, so new Window(...) can be called.
|
||||||
// This makese for nicer code, but might have to change in the future.
|
// This makese for nicer code, but might have to change in the future.
|
||||||
Window = DomWindow = DomElement.extend({
|
Window = DomWindow = DomElement.extend({
|
||||||
|
beans: true,
|
||||||
_type: 'window',
|
_type: 'window',
|
||||||
// Don't automatically call this.base in overridden initialize methods
|
// Don't automatically call this.base in overridden initialize methods
|
||||||
_initialize: false,
|
_initialize: false,
|
||||||
|
@ -2565,6 +2616,7 @@ DomElement.inject(new function() {
|
||||||
var getScrollOffset = cumulate('scroll', 'parentNode');
|
var getScrollOffset = cumulate('scroll', 'parentNode');
|
||||||
|
|
||||||
var fields = {
|
var fields = {
|
||||||
|
beans: true,
|
||||||
|
|
||||||
getSize: function() {
|
getSize: function() {
|
||||||
return body(this)
|
return body(this)
|
||||||
|
@ -2683,6 +2735,7 @@ DomElement.inject(new function() {
|
||||||
[DomDocument, DomWindow].each(function(ctor) {
|
[DomDocument, DomWindow].each(function(ctor) {
|
||||||
ctor.inject(this);
|
ctor.inject(this);
|
||||||
}, {
|
}, {
|
||||||
|
beans: true,
|
||||||
|
|
||||||
getSize: function() {
|
getSize: function() {
|
||||||
if (Browser.PRESTO || Browser.WEBKIT) {
|
if (Browser.PRESTO || Browser.WEBKIT) {
|
||||||
|
@ -3248,6 +3301,7 @@ DomElement.inject(new function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
beans: true,
|
||||||
|
|
||||||
getElements: function(selectors, nowrap) {
|
getElements: function(selectors, nowrap) {
|
||||||
var elements = nowrap ? [] : new this._collection();
|
var elements = nowrap ? [] : new this._collection();
|
||||||
|
@ -3628,6 +3682,7 @@ HtmlElement = DomElement.extend({
|
||||||
// Use the modified inject function from above which injects both into HtmlElement
|
// Use the modified inject function from above which injects both into HtmlElement
|
||||||
// and HtmlElements.
|
// and HtmlElements.
|
||||||
HtmlElement.inject({
|
HtmlElement.inject({
|
||||||
|
beans: true,
|
||||||
_properties: ['html'],
|
_properties: ['html'],
|
||||||
|
|
||||||
getClass: function() {
|
getClass: function() {
|
||||||
|
@ -3813,6 +3868,7 @@ HtmlElement.inject(new function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
var fields = {
|
var fields = {
|
||||||
|
beans: true,
|
||||||
|
|
||||||
getComputedStyle: function(name) {
|
getComputedStyle: function(name) {
|
||||||
if (this.$.currentStyle) return this.$.currentStyle[name.camelize()];
|
if (this.$.currentStyle) return this.$.currentStyle[name.camelize()];
|
||||||
|
@ -3957,6 +4013,7 @@ HtmlElement.inject(new function() {
|
||||||
// HtmlForm related functions, but available in all elements:
|
// HtmlForm related functions, but available in all elements:
|
||||||
|
|
||||||
HtmlElement.inject({
|
HtmlElement.inject({
|
||||||
|
beans: true,
|
||||||
|
|
||||||
getFormElements: function() {
|
getFormElements: function() {
|
||||||
return this.getElements(['input', 'select', 'textarea']);
|
return this.getElements(['input', 'select', 'textarea']);
|
||||||
|
@ -3996,6 +4053,7 @@ HtmlElement.inject({
|
||||||
});
|
});
|
||||||
|
|
||||||
HtmlForm = HtmlElement.extend({
|
HtmlForm = HtmlElement.extend({
|
||||||
|
beans: true,
|
||||||
_tag: 'form',
|
_tag: 'form',
|
||||||
_properties: ['action', 'method', 'target'],
|
_properties: ['action', 'method', 'target'],
|
||||||
_methods: ['submit'],
|
_methods: ['submit'],
|
||||||
|
@ -4014,6 +4072,7 @@ HtmlForm = HtmlElement.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
HtmlFormElement = HtmlElement.extend({
|
HtmlFormElement = HtmlElement.extend({
|
||||||
|
beans: true,
|
||||||
_properties: ['name', 'disabled'],
|
_properties: ['name', 'disabled'],
|
||||||
_methods: ['focus', 'blur'],
|
_methods: ['focus', 'blur'],
|
||||||
|
|
||||||
|
@ -4026,6 +4085,7 @@ HtmlFormElement = HtmlElement.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
HtmlInput = HtmlFormElement.extend({
|
HtmlInput = HtmlFormElement.extend({
|
||||||
|
beans: true,
|
||||||
_tag: 'input',
|
_tag: 'input',
|
||||||
_properties: ['type', 'checked', 'defaultChecked', 'readOnly', 'maxLength'],
|
_properties: ['type', 'checked', 'defaultChecked', 'readOnly', 'maxLength'],
|
||||||
_methods: ['click'],
|
_methods: ['click'],
|
||||||
|
@ -4048,11 +4108,13 @@ HtmlInput = HtmlFormElement.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
HtmlTextArea = HtmlFormElement.extend({
|
HtmlTextArea = HtmlFormElement.extend({
|
||||||
|
beans: true,
|
||||||
_tag: 'textarea',
|
_tag: 'textarea',
|
||||||
_properties: ['value']
|
_properties: ['value']
|
||||||
});
|
});
|
||||||
|
|
||||||
HtmlSelect = HtmlFormElement.extend({
|
HtmlSelect = HtmlFormElement.extend({
|
||||||
|
beans: true,
|
||||||
_tag: 'select',
|
_tag: 'select',
|
||||||
_properties: ['type', 'selectedIndex'],
|
_properties: ['type', 'selectedIndex'],
|
||||||
|
|
||||||
|
@ -4086,6 +4148,7 @@ HtmlSelect = HtmlFormElement.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
HtmlOption = HtmlFormElement.extend({
|
HtmlOption = HtmlFormElement.extend({
|
||||||
|
beans: true,
|
||||||
_tag: 'option',
|
_tag: 'option',
|
||||||
_properties: ['text', 'value', 'selected', 'defaultSelected', 'index']
|
_properties: ['text', 'value', 'selected', 'defaultSelected', 'index']
|
||||||
});
|
});
|
||||||
|
@ -4165,6 +4228,7 @@ HtmlFormElement.inject({
|
||||||
// HtmlImage
|
// HtmlImage
|
||||||
|
|
||||||
HtmlImage = HtmlElement.extend({
|
HtmlImage = HtmlElement.extend({
|
||||||
|
beans: true,
|
||||||
_tag: 'img',
|
_tag: 'img',
|
||||||
_properties: ['src', 'alt', 'title']
|
_properties: ['src', 'alt', 'title']
|
||||||
});
|
});
|
||||||
|
@ -5193,4 +5257,5 @@ Fx.Transitions.inject(['Quad', 'Cubic', 'Quart', 'Quint'].each(function(name, i)
|
||||||
this[name] = function(p) {
|
this[name] = function(p) {
|
||||||
return Math.pow(p, i + 2);
|
return Math.pow(p, i + 2);
|
||||||
}
|
}
|
||||||
}, {}));
|
}, {}));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue