MDL-22538 importing new YUI 3.1.1

This commit is contained in:
Petr Skoda 2010-05-21 12:14:09 +00:00
parent e9b4e764e3
commit c20792b145
905 changed files with 184716 additions and 0 deletions

View file

@ -0,0 +1,631 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-base', function(Y) {
/**
* The Animation Utility provides an API for creating advanced transitions.
* @module anim
*/
/**
* Provides the base Anim class, for animating numeric properties.
*
* @module anim
* @submodule anim-base
*/
/**
* A class for constructing animation instances.
* @class Anim
* @for Anim
* @constructor
* @extends Base
*/
var RUNNING = 'running',
START_TIME = 'startTime',
ELAPSED_TIME = 'elapsedTime',
/**
* @for Anim
* @event start
* @description fires when an animation begins.
* @param {Event} ev The start event.
* @type Event.Custom
*/
START = 'start',
/**
* @event tween
* @description fires every frame of the animation.
* @param {Event} ev The tween event.
* @type Event.Custom
*/
TWEEN = 'tween',
/**
* @event end
* @description fires after the animation completes.
* @param {Event} ev The end event.
* @type Event.Custom
*/
END = 'end',
NODE = 'node',
PAUSED = 'paused',
REVERSE = 'reverse', // TODO: cleanup
ITERATION_COUNT = 'iterationCount',
NUM = Number;
var _running = {},
_instances = {},
_timer;
Y.Anim = function() {
Y.Anim.superclass.constructor.apply(this, arguments);
_instances[Y.stamp(this)] = this;
};
Y.Anim.NAME = 'anim';
/**
* Regex of properties that should use the default unit.
*
* @property RE_DEFAULT_UNIT
* @static
*/
Y.Anim.RE_DEFAULT_UNIT = /^width|height|top|right|bottom|left|margin.*|padding.*|border.*$/i;
/**
* The default unit to use with properties that pass the RE_DEFAULT_UNIT test.
*
* @property DEFAULT_UNIT
* @static
*/
Y.Anim.DEFAULT_UNIT = 'px';
Y.Anim.DEFAULT_EASING = function (t, b, c, d) {
return c * t / d + b; // linear easing
};
/**
* Time in milliseconds passed to setInterval for frame processing
*
* @property intervalTime
* @default 20
* @static
*/
Y.Anim._intervalTime = 20;
/**
* Bucket for custom getters and setters
*
* @property behaviors
* @static
*/
Y.Anim.behaviors = {
left: {
get: function(anim, attr) {
return anim._getOffset(attr);
}
}
};
Y.Anim.behaviors.top = Y.Anim.behaviors.left;
/**
* The default setter to use when setting object properties.
*
* @property DEFAULT_SETTER
* @static
*/
Y.Anim.DEFAULT_SETTER = function(anim, att, from, to, elapsed, duration, fn, unit) {
unit = unit || '';
anim._node.setStyle(att, fn(elapsed, NUM(from), NUM(to) - NUM(from), duration) + unit);
};
/**
* The default getter to use when getting object properties.
*
* @property DEFAULT_GETTER
* @static
*/
Y.Anim.DEFAULT_GETTER = function(anim, prop) {
return anim._node.getComputedStyle(prop);
};
Y.Anim.ATTRS = {
/**
* The object to be animated.
* @attribute node
* @type Node
*/
node: {
setter: function(node) {
node = Y.one(node);
this._node = node;
if (!node) {
Y.log(node + ' is not a valid node', 'warn', 'Anim');
}
return node;
}
},
/**
* The length of the animation. Defaults to "1" (second).
* @attribute duration
* @type NUM
*/
duration: {
value: 1
},
/**
* The method that will provide values to the attribute(s) during the animation.
* Defaults to "Easing.easeNone".
* @attribute easing
* @type Function
*/
easing: {
value: Y.Anim.DEFAULT_EASING,
setter: function(val) {
if (typeof val === 'string' && Y.Easing) {
return Y.Easing[val];
}
}
},
/**
* The starting values for the animated properties.
* Fields may be strings, numbers, or functions.
* If a function is used, the return value becomes the from value.
* If no from value is specified, the DEFAULT_GETTER will be used.
* @attribute from
* @type Object
* supports any unit, provided it matches the "to" (or default)
* unit (e.g. "{width: 10em', color: 'rgb(0, 0 0)', borderColor: '#ccc'}".
* If using the default ('px' for length-based units), the unit may be omitted (
* (e.g. "{width: 100}, borderColor: 'ccc'}", which defaults to pixels
* and hex, respectively).
*/
from: {},
/**
* The ending values for the animated properties.
* Fields may be strings, numbers, or functions.
* @attribute to
* @type Object
* supports any unit, provided it matches the "from" (or default)
* unit (e.g. "{width: '50%', color: 'red', borderColor: '#ccc'}".
* If using the default ('px' for length-based units), the unit may be omitted (
* (e.g. "{width: 100}, borderColor: 'ccc'}", which defaults to pixels
* and hex, respectively).
*/
to: {},
/**
* Date stamp for the first frame of the animation.
* @attribute startTime
* @type Int
* @default 0
* @readOnly
*/
startTime: {
value: 0,
readOnly: true
},
/**
* Current time the animation has been running.
* @attribute elapsedTime
* @type Int
* @default 0
* @readOnly
*/
elapsedTime: {
value: 0,
readOnly: true
},
/**
* Whether or not the animation is currently running.
* @attribute running
* @type Boolean
* @default false
* @readOnly
*/
running: {
getter: function() {
return !!_running[Y.stamp(this)];
},
value: false,
readOnly: true
},
/**
* The number of times the animation should run
* @attribute iterations
* @type Int
* @default 1
*/
iterations: {
value: 1
},
/**
* The number of iterations that have occurred.
* Resets when an animation ends (reaches iteration count or stop() called).
* @attribute iterationCount
* @type Int
* @default 0
* @readOnly
*/
iterationCount: {
value: 0,
readOnly: true
},
/**
* How iterations of the animation should behave.
* Possible values are "normal" and "alternate".
* Normal will repeat the animation, alternate will reverse on every other pass.
*
* @attribute direction
* @type String
* @default "normal"
*/
direction: {
value: 'normal' // | alternate (fwd on odd, rev on even per spec)
},
/**
* Whether or not the animation is currently paused.
* @attribute paused
* @type Boolean
* @default false
* @readOnly
*/
paused: {
readOnly: true,
value: false
},
/**
* If true, animation begins from last frame
* @attribute reverse
* @type Boolean
* @default false
*/
reverse: {
value: false
}
};
/**
* Runs all animation instances.
* @method run
* @static
*/
Y.Anim.run = function() {
for (var i in _instances) {
if (_instances[i].run) {
_instances[i].run();
}
}
};
/**
* Pauses all animation instances.
* @method pause
* @static
*/
Y.Anim.pause = function() {
for (var i in _running) { // stop timer if nothing running
if (_running[i].pause) {
_running[i].pause();
}
}
Y.Anim._stopTimer();
};
/**
* Stops all animation instances.
* @method stop
* @static
*/
Y.Anim.stop = function() {
for (var i in _running) { // stop timer if nothing running
if (_running[i].stop) {
_running[i].stop();
}
}
Y.Anim._stopTimer();
};
Y.Anim._startTimer = function() {
if (!_timer) {
_timer = setInterval(Y.Anim._runFrame, Y.Anim._intervalTime);
}
};
Y.Anim._stopTimer = function() {
clearInterval(_timer);
_timer = 0;
};
/**
* Called per Interval to handle each animation frame.
* @method _runFrame
* @private
* @static
*/
Y.Anim._runFrame = function() {
var done = true;
for (var anim in _running) {
if (_running[anim]._runFrame) {
done = false;
_running[anim]._runFrame();
}
}
if (done) {
Y.Anim._stopTimer();
}
};
Y.Anim.RE_UNITS = /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/;
var proto = {
/**
* Starts or resumes an animation.
* @method run
* @chainable
*/
run: function() {
if (this.get(PAUSED)) {
this._resume();
} else if (!this.get(RUNNING)) {
this._start();
}
return this;
},
/**
* Pauses the animation and
* freezes it in its current state and time.
* Calling run() will continue where it left off.
* @method pause
* @chainable
*/
pause: function() {
if (this.get(RUNNING)) {
this._pause();
}
return this;
},
/**
* Stops the animation and resets its time.
* @method stop
* @chainable
*/
stop: function(finish) {
if (this.get(RUNNING) || this.get(PAUSED)) {
this._end(finish);
}
return this;
},
_added: false,
_start: function() {
this._set(START_TIME, new Date() - this.get(ELAPSED_TIME));
this._actualFrames = 0;
if (!this.get(PAUSED)) {
this._initAnimAttr();
}
_running[Y.stamp(this)] = this;
Y.Anim._startTimer();
this.fire(START);
},
_pause: function() {
this._set(START_TIME, null);
this._set(PAUSED, true);
delete _running[Y.stamp(this)];
/**
* @event pause
* @description fires when an animation is paused.
* @param {Event} ev The pause event.
* @type Event.Custom
*/
this.fire('pause');
},
_resume: function() {
this._set(PAUSED, false);
_running[Y.stamp(this)] = this;
/**
* @event resume
* @description fires when an animation is resumed (run from pause).
* @param {Event} ev The pause event.
* @type Event.Custom
*/
this.fire('resume');
},
_end: function(finish) {
var duration = this.get('duration') * 1000;
if (finish) { // jump to last frame
this._runAttrs(duration, duration, this.get(REVERSE));
}
this._set(START_TIME, null);
this._set(ELAPSED_TIME, 0);
this._set(PAUSED, false);
delete _running[Y.stamp(this)];
this.fire(END, {elapsed: this.get(ELAPSED_TIME)});
},
_runFrame: function() {
var d = this._runtimeAttr.duration,
t = new Date() - this.get(START_TIME),
reverse = this.get(REVERSE),
done = (t >= d),
attribute,
setter;
this._runAttrs(t, d, reverse);
this._actualFrames += 1;
this._set(ELAPSED_TIME, t);
this.fire(TWEEN);
if (done) {
this._lastFrame();
}
},
_runAttrs: function(t, d, reverse) {
var attr = this._runtimeAttr,
customAttr = Y.Anim.behaviors,
easing = attr.easing,
lastFrame = d,
attribute,
setter,
i;
if (reverse) {
t = d - t;
lastFrame = 0;
}
for (i in attr) {
if (attr[i].to) {
attribute = attr[i];
setter = (i in customAttr && 'set' in customAttr[i]) ?
customAttr[i].set : Y.Anim.DEFAULT_SETTER;
if (t < d) {
setter(this, i, attribute.from, attribute.to, t, d, easing, attribute.unit);
} else {
setter(this, i, attribute.from, attribute.to, lastFrame, d, easing, attribute.unit);
}
}
}
},
_lastFrame: function() {
var iter = this.get('iterations'),
iterCount = this.get(ITERATION_COUNT);
iterCount += 1;
if (iter === 'infinite' || iterCount < iter) {
if (this.get('direction') === 'alternate') {
this.set(REVERSE, !this.get(REVERSE)); // flip it
}
/**
* @event iteration
* @description fires when an animation begins an iteration.
* @param {Event} ev The iteration event.
* @type Event.Custom
*/
this.fire('iteration');
} else {
iterCount = 0;
this._end();
}
this._set(START_TIME, new Date());
this._set(ITERATION_COUNT, iterCount);
},
_initAnimAttr: function() {
var from = this.get('from') || {},
to = this.get('to') || {},
attr = {
duration: this.get('duration') * 1000,
easing: this.get('easing')
},
customAttr = Y.Anim.behaviors,
node = this.get(NODE), // implicit attr init
unit, begin, end;
Y.each(to, function(val, name) {
if (typeof val === 'function') {
val = val.call(this, node);
}
begin = from[name];
if (begin === undefined) {
begin = (name in customAttr && 'get' in customAttr[name]) ?
customAttr[name].get(this, name) : Y.Anim.DEFAULT_GETTER(this, name);
} else if (typeof begin === 'function') {
begin = begin.call(this, node);
}
var mFrom = Y.Anim.RE_UNITS.exec(begin);
var mTo = Y.Anim.RE_UNITS.exec(val);
begin = mFrom ? mFrom[1] : begin;
end = mTo ? mTo[1] : val;
unit = mTo ? mTo[2] : mFrom ? mFrom[2] : ''; // one might be zero TODO: mixed units
if (!unit && Y.Anim.RE_DEFAULT_UNIT.test(name)) {
unit = Y.Anim.DEFAULT_UNIT;
}
if (!begin || !end) {
Y.error('invalid "from" or "to" for "' + name + '"', 'Anim');
return;
}
attr[name] = {
from: begin,
to: end,
unit: unit
};
}, this);
this._runtimeAttr = attr;
},
// TODO: move to computedStyle? (browsers dont agree on default computed offsets)
_getOffset: function(attr) {
var node = this._node,
val = node.getComputedStyle(attr),
get = (attr === 'left') ? 'getX': 'getY',
set = (attr === 'left') ? 'setX': 'setY';
if (val === 'auto') {
var position = node.getStyle('position');
if (position === 'absolute' || position === 'fixed') {
val = node[get]();
node[set](val);
} else {
val = 0;
}
}
return val;
}
};
Y.extend(Y.Anim, Y.Base, proto);
}, '3.1.1' ,{requires:['base-base', 'node-style']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("anim-base",function(B){var C="running",N="startTime",L="elapsedTime",J="start",I="tween",M="end",D="node",K="paused",P="reverse",H="iterationCount",A=Number;var F={},O={},E;B.Anim=function(){B.Anim.superclass.constructor.apply(this,arguments);O[B.stamp(this)]=this;};B.Anim.NAME="anim";B.Anim.RE_DEFAULT_UNIT=/^width|height|top|right|bottom|left|margin.*|padding.*|border.*$/i;B.Anim.DEFAULT_UNIT="px";B.Anim.DEFAULT_EASING=function(R,Q,T,S){return T*R/S+Q;};B.Anim._intervalTime=20;B.Anim.behaviors={left:{get:function(R,Q){return R._getOffset(Q);}}};B.Anim.behaviors.top=B.Anim.behaviors.left;B.Anim.DEFAULT_SETTER=function(U,R,X,W,Q,V,S,T){T=T||"";U._node.setStyle(R,S(Q,A(X),A(W)-A(X),V)+T);};B.Anim.DEFAULT_GETTER=function(Q,R){return Q._node.getComputedStyle(R);};B.Anim.ATTRS={node:{setter:function(Q){Q=B.one(Q);this._node=Q;if(!Q){}return Q;}},duration:{value:1},easing:{value:B.Anim.DEFAULT_EASING,setter:function(Q){if(typeof Q==="string"&&B.Easing){return B.Easing[Q];}}},from:{},to:{},startTime:{value:0,readOnly:true},elapsedTime:{value:0,readOnly:true},running:{getter:function(){return !!F[B.stamp(this)];},value:false,readOnly:true},iterations:{value:1},iterationCount:{value:0,readOnly:true},direction:{value:"normal"},paused:{readOnly:true,value:false},reverse:{value:false}};B.Anim.run=function(){for(var Q in O){if(O[Q].run){O[Q].run();}}};B.Anim.pause=function(){for(var Q in F){if(F[Q].pause){F[Q].pause();}}B.Anim._stopTimer();};B.Anim.stop=function(){for(var Q in F){if(F[Q].stop){F[Q].stop();}}B.Anim._stopTimer();};B.Anim._startTimer=function(){if(!E){E=setInterval(B.Anim._runFrame,B.Anim._intervalTime);}};B.Anim._stopTimer=function(){clearInterval(E);E=0;};B.Anim._runFrame=function(){var Q=true;for(var R in F){if(F[R]._runFrame){Q=false;F[R]._runFrame();}}if(Q){B.Anim._stopTimer();}};B.Anim.RE_UNITS=/^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/;var G={run:function(){if(this.get(K)){this._resume();}else{if(!this.get(C)){this._start();}}return this;},pause:function(){if(this.get(C)){this._pause();}return this;},stop:function(Q){if(this.get(C)||this.get(K)){this._end(Q);}return this;},_added:false,_start:function(){this._set(N,new Date()-this.get(L));this._actualFrames=0;if(!this.get(K)){this._initAnimAttr();}F[B.stamp(this)]=this;B.Anim._startTimer();this.fire(J);},_pause:function(){this._set(N,null);this._set(K,true);delete F[B.stamp(this)];this.fire("pause");},_resume:function(){this._set(K,false);F[B.stamp(this)]=this;this.fire("resume");},_end:function(Q){var R=this.get("duration")*1000;if(Q){this._runAttrs(R,R,this.get(P));}this._set(N,null);this._set(L,0);this._set(K,false);delete F[B.stamp(this)];this.fire(M,{elapsed:this.get(L)});},_runFrame:function(){var U=this._runtimeAttr.duration,S=new Date()-this.get(N),R=this.get(P),Q=(S>=U),T,V;this._runAttrs(S,U,R);this._actualFrames+=1;this._set(L,S);this.fire(I);if(Q){this._lastFrame();}},_runAttrs:function(Z,Y,V){var W=this._runtimeAttr,S=B.Anim.behaviors,X=W.easing,Q=Y,R,T,U;if(V){Z=Y-Z;Q=0;}for(U in W){if(W[U].to){R=W[U];T=(U in S&&"set" in S[U])?S[U].set:B.Anim.DEFAULT_SETTER;if(Z<Y){T(this,U,R.from,R.to,Z,Y,X,R.unit);}else{T(this,U,R.from,R.to,Q,Y,X,R.unit);}}}},_lastFrame:function(){var Q=this.get("iterations"),R=this.get(H);R+=1;if(Q==="infinite"||R<Q){if(this.get("direction")==="alternate"){this.set(P,!this.get(P));}this.fire("iteration");}else{R=0;this._end();}this._set(N,new Date());this._set(H,R);},_initAnimAttr:function(){var X=this.get("from")||{},W=this.get("to")||{},Q={duration:this.get("duration")*1000,easing:this.get("easing")},S=B.Anim.behaviors,V=this.get(D),U,T,R;B.each(W,function(b,Z){if(typeof b==="function"){b=b.call(this,V);}T=X[Z];if(T===undefined){T=(Z in S&&"get" in S[Z])?S[Z].get(this,Z):B.Anim.DEFAULT_GETTER(this,Z);}else{if(typeof T==="function"){T=T.call(this,V);}}var Y=B.Anim.RE_UNITS.exec(T);var a=B.Anim.RE_UNITS.exec(b);T=Y?Y[1]:T;R=a?a[1]:b;U=a?a[2]:Y?Y[2]:"";if(!U&&B.Anim.RE_DEFAULT_UNIT.test(Z)){U=B.Anim.DEFAULT_UNIT;}if(!T||!R){B.error('invalid "from" or "to" for "'+Z+'"',"Anim");return;}Q[Z]={from:T,to:R,unit:U};},this);this._runtimeAttr=Q;},_getOffset:function(R){var T=this._node,U=T.getComputedStyle(R),S=(R==="left")?"getX":"getY",V=(R==="left")?"setX":"setY";if(U==="auto"){var Q=T.getStyle("position");if(Q==="absolute"||Q==="fixed"){U=T[S]();T[V](U);}else{U=0;}}return U;}};B.extend(B.Anim,B.Base,G);},"3.1.1",{requires:["base-base","node-style"]});

View file

@ -0,0 +1,630 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-base', function(Y) {
/**
* The Animation Utility provides an API for creating advanced transitions.
* @module anim
*/
/**
* Provides the base Anim class, for animating numeric properties.
*
* @module anim
* @submodule anim-base
*/
/**
* A class for constructing animation instances.
* @class Anim
* @for Anim
* @constructor
* @extends Base
*/
var RUNNING = 'running',
START_TIME = 'startTime',
ELAPSED_TIME = 'elapsedTime',
/**
* @for Anim
* @event start
* @description fires when an animation begins.
* @param {Event} ev The start event.
* @type Event.Custom
*/
START = 'start',
/**
* @event tween
* @description fires every frame of the animation.
* @param {Event} ev The tween event.
* @type Event.Custom
*/
TWEEN = 'tween',
/**
* @event end
* @description fires after the animation completes.
* @param {Event} ev The end event.
* @type Event.Custom
*/
END = 'end',
NODE = 'node',
PAUSED = 'paused',
REVERSE = 'reverse', // TODO: cleanup
ITERATION_COUNT = 'iterationCount',
NUM = Number;
var _running = {},
_instances = {},
_timer;
Y.Anim = function() {
Y.Anim.superclass.constructor.apply(this, arguments);
_instances[Y.stamp(this)] = this;
};
Y.Anim.NAME = 'anim';
/**
* Regex of properties that should use the default unit.
*
* @property RE_DEFAULT_UNIT
* @static
*/
Y.Anim.RE_DEFAULT_UNIT = /^width|height|top|right|bottom|left|margin.*|padding.*|border.*$/i;
/**
* The default unit to use with properties that pass the RE_DEFAULT_UNIT test.
*
* @property DEFAULT_UNIT
* @static
*/
Y.Anim.DEFAULT_UNIT = 'px';
Y.Anim.DEFAULT_EASING = function (t, b, c, d) {
return c * t / d + b; // linear easing
};
/**
* Time in milliseconds passed to setInterval for frame processing
*
* @property intervalTime
* @default 20
* @static
*/
Y.Anim._intervalTime = 20;
/**
* Bucket for custom getters and setters
*
* @property behaviors
* @static
*/
Y.Anim.behaviors = {
left: {
get: function(anim, attr) {
return anim._getOffset(attr);
}
}
};
Y.Anim.behaviors.top = Y.Anim.behaviors.left;
/**
* The default setter to use when setting object properties.
*
* @property DEFAULT_SETTER
* @static
*/
Y.Anim.DEFAULT_SETTER = function(anim, att, from, to, elapsed, duration, fn, unit) {
unit = unit || '';
anim._node.setStyle(att, fn(elapsed, NUM(from), NUM(to) - NUM(from), duration) + unit);
};
/**
* The default getter to use when getting object properties.
*
* @property DEFAULT_GETTER
* @static
*/
Y.Anim.DEFAULT_GETTER = function(anim, prop) {
return anim._node.getComputedStyle(prop);
};
Y.Anim.ATTRS = {
/**
* The object to be animated.
* @attribute node
* @type Node
*/
node: {
setter: function(node) {
node = Y.one(node);
this._node = node;
if (!node) {
}
return node;
}
},
/**
* The length of the animation. Defaults to "1" (second).
* @attribute duration
* @type NUM
*/
duration: {
value: 1
},
/**
* The method that will provide values to the attribute(s) during the animation.
* Defaults to "Easing.easeNone".
* @attribute easing
* @type Function
*/
easing: {
value: Y.Anim.DEFAULT_EASING,
setter: function(val) {
if (typeof val === 'string' && Y.Easing) {
return Y.Easing[val];
}
}
},
/**
* The starting values for the animated properties.
* Fields may be strings, numbers, or functions.
* If a function is used, the return value becomes the from value.
* If no from value is specified, the DEFAULT_GETTER will be used.
* @attribute from
* @type Object
* supports any unit, provided it matches the "to" (or default)
* unit (e.g. "{width: 10em', color: 'rgb(0, 0 0)', borderColor: '#ccc'}".
* If using the default ('px' for length-based units), the unit may be omitted (
* (e.g. "{width: 100}, borderColor: 'ccc'}", which defaults to pixels
* and hex, respectively).
*/
from: {},
/**
* The ending values for the animated properties.
* Fields may be strings, numbers, or functions.
* @attribute to
* @type Object
* supports any unit, provided it matches the "from" (or default)
* unit (e.g. "{width: '50%', color: 'red', borderColor: '#ccc'}".
* If using the default ('px' for length-based units), the unit may be omitted (
* (e.g. "{width: 100}, borderColor: 'ccc'}", which defaults to pixels
* and hex, respectively).
*/
to: {},
/**
* Date stamp for the first frame of the animation.
* @attribute startTime
* @type Int
* @default 0
* @readOnly
*/
startTime: {
value: 0,
readOnly: true
},
/**
* Current time the animation has been running.
* @attribute elapsedTime
* @type Int
* @default 0
* @readOnly
*/
elapsedTime: {
value: 0,
readOnly: true
},
/**
* Whether or not the animation is currently running.
* @attribute running
* @type Boolean
* @default false
* @readOnly
*/
running: {
getter: function() {
return !!_running[Y.stamp(this)];
},
value: false,
readOnly: true
},
/**
* The number of times the animation should run
* @attribute iterations
* @type Int
* @default 1
*/
iterations: {
value: 1
},
/**
* The number of iterations that have occurred.
* Resets when an animation ends (reaches iteration count or stop() called).
* @attribute iterationCount
* @type Int
* @default 0
* @readOnly
*/
iterationCount: {
value: 0,
readOnly: true
},
/**
* How iterations of the animation should behave.
* Possible values are "normal" and "alternate".
* Normal will repeat the animation, alternate will reverse on every other pass.
*
* @attribute direction
* @type String
* @default "normal"
*/
direction: {
value: 'normal' // | alternate (fwd on odd, rev on even per spec)
},
/**
* Whether or not the animation is currently paused.
* @attribute paused
* @type Boolean
* @default false
* @readOnly
*/
paused: {
readOnly: true,
value: false
},
/**
* If true, animation begins from last frame
* @attribute reverse
* @type Boolean
* @default false
*/
reverse: {
value: false
}
};
/**
* Runs all animation instances.
* @method run
* @static
*/
Y.Anim.run = function() {
for (var i in _instances) {
if (_instances[i].run) {
_instances[i].run();
}
}
};
/**
* Pauses all animation instances.
* @method pause
* @static
*/
Y.Anim.pause = function() {
for (var i in _running) { // stop timer if nothing running
if (_running[i].pause) {
_running[i].pause();
}
}
Y.Anim._stopTimer();
};
/**
* Stops all animation instances.
* @method stop
* @static
*/
Y.Anim.stop = function() {
for (var i in _running) { // stop timer if nothing running
if (_running[i].stop) {
_running[i].stop();
}
}
Y.Anim._stopTimer();
};
Y.Anim._startTimer = function() {
if (!_timer) {
_timer = setInterval(Y.Anim._runFrame, Y.Anim._intervalTime);
}
};
Y.Anim._stopTimer = function() {
clearInterval(_timer);
_timer = 0;
};
/**
* Called per Interval to handle each animation frame.
* @method _runFrame
* @private
* @static
*/
Y.Anim._runFrame = function() {
var done = true;
for (var anim in _running) {
if (_running[anim]._runFrame) {
done = false;
_running[anim]._runFrame();
}
}
if (done) {
Y.Anim._stopTimer();
}
};
Y.Anim.RE_UNITS = /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/;
var proto = {
/**
* Starts or resumes an animation.
* @method run
* @chainable
*/
run: function() {
if (this.get(PAUSED)) {
this._resume();
} else if (!this.get(RUNNING)) {
this._start();
}
return this;
},
/**
* Pauses the animation and
* freezes it in its current state and time.
* Calling run() will continue where it left off.
* @method pause
* @chainable
*/
pause: function() {
if (this.get(RUNNING)) {
this._pause();
}
return this;
},
/**
* Stops the animation and resets its time.
* @method stop
* @chainable
*/
stop: function(finish) {
if (this.get(RUNNING) || this.get(PAUSED)) {
this._end(finish);
}
return this;
},
_added: false,
_start: function() {
this._set(START_TIME, new Date() - this.get(ELAPSED_TIME));
this._actualFrames = 0;
if (!this.get(PAUSED)) {
this._initAnimAttr();
}
_running[Y.stamp(this)] = this;
Y.Anim._startTimer();
this.fire(START);
},
_pause: function() {
this._set(START_TIME, null);
this._set(PAUSED, true);
delete _running[Y.stamp(this)];
/**
* @event pause
* @description fires when an animation is paused.
* @param {Event} ev The pause event.
* @type Event.Custom
*/
this.fire('pause');
},
_resume: function() {
this._set(PAUSED, false);
_running[Y.stamp(this)] = this;
/**
* @event resume
* @description fires when an animation is resumed (run from pause).
* @param {Event} ev The pause event.
* @type Event.Custom
*/
this.fire('resume');
},
_end: function(finish) {
var duration = this.get('duration') * 1000;
if (finish) { // jump to last frame
this._runAttrs(duration, duration, this.get(REVERSE));
}
this._set(START_TIME, null);
this._set(ELAPSED_TIME, 0);
this._set(PAUSED, false);
delete _running[Y.stamp(this)];
this.fire(END, {elapsed: this.get(ELAPSED_TIME)});
},
_runFrame: function() {
var d = this._runtimeAttr.duration,
t = new Date() - this.get(START_TIME),
reverse = this.get(REVERSE),
done = (t >= d),
attribute,
setter;
this._runAttrs(t, d, reverse);
this._actualFrames += 1;
this._set(ELAPSED_TIME, t);
this.fire(TWEEN);
if (done) {
this._lastFrame();
}
},
_runAttrs: function(t, d, reverse) {
var attr = this._runtimeAttr,
customAttr = Y.Anim.behaviors,
easing = attr.easing,
lastFrame = d,
attribute,
setter,
i;
if (reverse) {
t = d - t;
lastFrame = 0;
}
for (i in attr) {
if (attr[i].to) {
attribute = attr[i];
setter = (i in customAttr && 'set' in customAttr[i]) ?
customAttr[i].set : Y.Anim.DEFAULT_SETTER;
if (t < d) {
setter(this, i, attribute.from, attribute.to, t, d, easing, attribute.unit);
} else {
setter(this, i, attribute.from, attribute.to, lastFrame, d, easing, attribute.unit);
}
}
}
},
_lastFrame: function() {
var iter = this.get('iterations'),
iterCount = this.get(ITERATION_COUNT);
iterCount += 1;
if (iter === 'infinite' || iterCount < iter) {
if (this.get('direction') === 'alternate') {
this.set(REVERSE, !this.get(REVERSE)); // flip it
}
/**
* @event iteration
* @description fires when an animation begins an iteration.
* @param {Event} ev The iteration event.
* @type Event.Custom
*/
this.fire('iteration');
} else {
iterCount = 0;
this._end();
}
this._set(START_TIME, new Date());
this._set(ITERATION_COUNT, iterCount);
},
_initAnimAttr: function() {
var from = this.get('from') || {},
to = this.get('to') || {},
attr = {
duration: this.get('duration') * 1000,
easing: this.get('easing')
},
customAttr = Y.Anim.behaviors,
node = this.get(NODE), // implicit attr init
unit, begin, end;
Y.each(to, function(val, name) {
if (typeof val === 'function') {
val = val.call(this, node);
}
begin = from[name];
if (begin === undefined) {
begin = (name in customAttr && 'get' in customAttr[name]) ?
customAttr[name].get(this, name) : Y.Anim.DEFAULT_GETTER(this, name);
} else if (typeof begin === 'function') {
begin = begin.call(this, node);
}
var mFrom = Y.Anim.RE_UNITS.exec(begin);
var mTo = Y.Anim.RE_UNITS.exec(val);
begin = mFrom ? mFrom[1] : begin;
end = mTo ? mTo[1] : val;
unit = mTo ? mTo[2] : mFrom ? mFrom[2] : ''; // one might be zero TODO: mixed units
if (!unit && Y.Anim.RE_DEFAULT_UNIT.test(name)) {
unit = Y.Anim.DEFAULT_UNIT;
}
if (!begin || !end) {
Y.error('invalid "from" or "to" for "' + name + '"', 'Anim');
return;
}
attr[name] = {
from: begin,
to: end,
unit: unit
};
}, this);
this._runtimeAttr = attr;
},
// TODO: move to computedStyle? (browsers dont agree on default computed offsets)
_getOffset: function(attr) {
var node = this._node,
val = node.getComputedStyle(attr),
get = (attr === 'left') ? 'getX': 'getY',
set = (attr === 'left') ? 'setX': 'setY';
if (val === 'auto') {
var position = node.getStyle('position');
if (position === 'absolute' || position === 'fixed') {
val = node[get]();
node[set](val);
} else {
val = 0;
}
}
return val;
}
};
Y.extend(Y.Anim, Y.Base, proto);
}, '3.1.1' ,{requires:['base-base', 'node-style']});

View file

@ -0,0 +1,55 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-color', function(Y) {
/**
* Adds support for color properties in <code>to</code>
* and <code>from</code> attributes.
* @module anim
* @submodule anim-color
*/
var NUM = Number;
Y.Anim.behaviors.color = {
set: function(anim, att, from, to, elapsed, duration, fn) {
from = Y.Color.re_RGB.exec(Y.Color.toRGB(from));
to = Y.Color.re_RGB.exec(Y.Color.toRGB(to));
if (!from || from.length < 3 || !to || to.length < 3) {
Y.error('invalid from or to passed to color behavior');
}
anim._node.setStyle(att, 'rgb(' + [
Math.floor(fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)),
Math.floor(fn(elapsed, NUM(from[2]), NUM(to[2]) - NUM(from[2]), duration)),
Math.floor(fn(elapsed, NUM(from[3]), NUM(to[3]) - NUM(from[3]), duration))
].join(', ') + ')');
},
// TODO: default bgcolor const
get: function(anim, att) {
var val = anim._node.getComputedStyle(att);
val = (val === 'transparent') ? 'rgb(255, 255, 255)' : val;
return val;
}
};
Y.each(['backgroundColor',
'borderColor',
'borderTopColor',
'borderRightColor',
'borderBottomColor',
'borderLeftColor'],
function(v, i) {
Y.Anim.behaviors[v] = Y.Anim.behaviors.color;
}
);
}, '3.1.1' ,{requires:['anim-base']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("anim-color",function(B){var A=Number;B.Anim.behaviors.color={set:function(F,D,I,H,C,G,E){I=B.Color.re_RGB.exec(B.Color.toRGB(I));H=B.Color.re_RGB.exec(B.Color.toRGB(H));if(!I||I.length<3||!H||H.length<3){B.error("invalid from or to passed to color behavior");}F._node.setStyle(D,"rgb("+[Math.floor(E(C,A(I[1]),A(H[1])-A(I[1]),G)),Math.floor(E(C,A(I[2]),A(H[2])-A(I[2]),G)),Math.floor(E(C,A(I[3]),A(H[3])-A(I[3]),G))].join(", ")+")");},get:function(D,C){var E=D._node.getComputedStyle(C);E=(E==="transparent")?"rgb(255, 255, 255)":E;return E;}};B.each(["backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],function(C,D){B.Anim.behaviors[C]=B.Anim.behaviors.color;});},"3.1.1",{requires:["anim-base"]});

View file

@ -0,0 +1,55 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-color', function(Y) {
/**
* Adds support for color properties in <code>to</code>
* and <code>from</code> attributes.
* @module anim
* @submodule anim-color
*/
var NUM = Number;
Y.Anim.behaviors.color = {
set: function(anim, att, from, to, elapsed, duration, fn) {
from = Y.Color.re_RGB.exec(Y.Color.toRGB(from));
to = Y.Color.re_RGB.exec(Y.Color.toRGB(to));
if (!from || from.length < 3 || !to || to.length < 3) {
Y.error('invalid from or to passed to color behavior');
}
anim._node.setStyle(att, 'rgb(' + [
Math.floor(fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)),
Math.floor(fn(elapsed, NUM(from[2]), NUM(to[2]) - NUM(from[2]), duration)),
Math.floor(fn(elapsed, NUM(from[3]), NUM(to[3]) - NUM(from[3]), duration))
].join(', ') + ')');
},
// TODO: default bgcolor const
get: function(anim, att) {
var val = anim._node.getComputedStyle(att);
val = (val === 'transparent') ? 'rgb(255, 255, 255)' : val;
return val;
}
};
Y.each(['backgroundColor',
'borderColor',
'borderTopColor',
'borderRightColor',
'borderBottomColor',
'borderLeftColor'],
function(v, i) {
Y.Anim.behaviors[v] = Y.Anim.behaviors.color;
}
);
}, '3.1.1' ,{requires:['anim-base']});

View file

@ -0,0 +1,64 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-curve', function(Y) {
/**
* Adds support for the <code>curve</code> property for the <code>to</code>
* attribute. A curve is zero or more control points and an end point.
* @module anim
* @submodule anim-curve
*/
Y.Anim.behaviors.curve = {
set: function(anim, att, from, to, elapsed, duration, fn) {
from = from.slice.call(from);
to = to.slice.call(to);
var t = fn(elapsed, 0, 100, duration) / 100;
to.unshift(from);
anim._node.setXY(Y.Anim.getBezier(to, t));
},
get: function(anim, att) {
return anim._node.getXY();
}
};
/**
* Get the current position of the animated element based on t.
* Each point is an array of "x" and "y" values (0 = x, 1 = y)
* At least 2 points are required (start and end).
* First point is start. Last point is end.
* Additional control points are optional.
* @for Anim
* @method getBezier
* @static
* @param {Array} points An array containing Bezier points
* @param {Number} t A number between 0 and 1 which is the basis for determining current position
* @return {Array} An array containing int x and y member data
*/
Y.Anim.getBezier = function(points, t) {
var n = points.length;
var tmp = [];
for (var i = 0; i < n; ++i){
tmp[i] = [points[i][0], points[i][1]]; // save input
}
for (var j = 1; j < n; ++j) {
for (i = 0; i < n - j; ++i) {
tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
}
}
return [ tmp[0][0], tmp[0][1] ];
};
}, '3.1.1' ,{requires:['anim-xy']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("anim-curve",function(A){A.Anim.behaviors.curve={set:function(F,C,I,H,B,G,E){I=I.slice.call(I);H=H.slice.call(H);var D=E(B,0,100,G)/100;H.unshift(I);F._node.setXY(A.Anim.getBezier(H,D));},get:function(C,B){return C._node.getXY();}};A.Anim.getBezier=function(F,E){var G=F.length;var D=[];for(var C=0;C<G;++C){D[C]=[F[C][0],F[C][1]];}for(var B=1;B<G;++B){for(C=0;C<G-B;++C){D[C][0]=(1-E)*D[C][0]+E*D[parseInt(C+1,10)][0];D[C][1]=(1-E)*D[C][1]+E*D[parseInt(C+1,10)][1];}}return[D[0][0],D[0][1]];};},"3.1.1",{requires:["anim-xy"]});

View file

@ -0,0 +1,64 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-curve', function(Y) {
/**
* Adds support for the <code>curve</code> property for the <code>to</code>
* attribute. A curve is zero or more control points and an end point.
* @module anim
* @submodule anim-curve
*/
Y.Anim.behaviors.curve = {
set: function(anim, att, from, to, elapsed, duration, fn) {
from = from.slice.call(from);
to = to.slice.call(to);
var t = fn(elapsed, 0, 100, duration) / 100;
to.unshift(from);
anim._node.setXY(Y.Anim.getBezier(to, t));
},
get: function(anim, att) {
return anim._node.getXY();
}
};
/**
* Get the current position of the animated element based on t.
* Each point is an array of "x" and "y" values (0 = x, 1 = y)
* At least 2 points are required (start and end).
* First point is start. Last point is end.
* Additional control points are optional.
* @for Anim
* @method getBezier
* @static
* @param {Array} points An array containing Bezier points
* @param {Number} t A number between 0 and 1 which is the basis for determining current position
* @return {Array} An array containing int x and y member data
*/
Y.Anim.getBezier = function(points, t) {
var n = points.length;
var tmp = [];
for (var i = 0; i < n; ++i){
tmp[i] = [points[i][0], points[i][1]]; // save input
}
for (var j = 1; j < n; ++j) {
for (i = 0; i < n - j; ++i) {
tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
}
}
return [ tmp[0][0], tmp[0][1] ];
};
}, '3.1.1' ,{requires:['anim-xy']});

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,355 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-easing', function(Y) {
/*
TERMS OF USE - EASING EQUATIONS
Open source under the BSD License.
Copyright 2001 Robert Penner All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The easing module provides methods for customizing
* how an animation behaves during each run.
* @class Easing
* @module anim
* @submodule anim-easing
*/
Y.Easing = {
/**
* Uniform speed between points.
* @for Easing
* @method easeNone
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeNone: function (t, b, c, d) {
return c*t/d + b;
},
/**
* Begins slowly and accelerates towards end. (quadratic)
* @method easeIn
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeIn: function (t, b, c, d) {
return c*(t/=d)*t + b;
},
/**
* Begins quickly and decelerates towards end. (quadratic)
* @method easeOut
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeOut: function (t, b, c, d) {
return -c *(t/=d)*(t-2) + b;
},
/**
* Begins slowly and decelerates towards end. (quadratic)
* @method easeBoth
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeBoth: function (t, b, c, d) {
if ((t/=d/2) < 1) {
return c/2*t*t + b;
}
return -c/2 * ((--t)*(t-2) - 1) + b;
},
/**
* Begins slowly and accelerates towards end. (quartic)
* @method easeInStrong
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeInStrong: function (t, b, c, d) {
return c*(t/=d)*t*t*t + b;
},
/**
* Begins quickly and decelerates towards end. (quartic)
* @method easeOutStrong
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeOutStrong: function (t, b, c, d) {
return -c * ((t=t/d-1)*t*t*t - 1) + b;
},
/**
* Begins slowly and decelerates towards end. (quartic)
* @method easeBothStrong
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeBothStrong: function (t, b, c, d) {
if ((t/=d/2) < 1) {
return c/2*t*t*t*t + b;
}
return -c/2 * ((t-=2)*t*t*t - 2) + b;
},
/**
* Snap in elastic effect.
* @method elasticIn
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} a Amplitude (optional)
* @param {Number} p Period (optional)
* @return {Number} The computed value for the current animation frame
*/
elasticIn: function (t, b, c, d, a, p) {
var s;
if (t === 0) {
return b;
}
if ( (t /= d) === 1 ) {
return b+c;
}
if (!p) {
p = d* 0.3;
}
if (!a || a < Math.abs(c)) {
a = c;
s = p/4;
}
else {
s = p/(2*Math.PI) * Math.asin (c/a);
}
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
},
/**
* Snap out elastic effect.
* @method elasticOut
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} a Amplitude (optional)
* @param {Number} p Period (optional)
* @return {Number} The computed value for the current animation frame
*/
elasticOut: function (t, b, c, d, a, p) {
var s;
if (t === 0) {
return b;
}
if ( (t /= d) === 1 ) {
return b+c;
}
if (!p) {
p=d * 0.3;
}
if (!a || a < Math.abs(c)) {
a = c;
s = p / 4;
}
else {
s = p/(2*Math.PI) * Math.asin (c/a);
}
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
},
/**
* Snap both elastic effect.
* @method elasticBoth
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} a Amplitude (optional)
* @param {Number} p Period (optional)
* @return {Number} The computed value for the current animation frame
*/
elasticBoth: function (t, b, c, d, a, p) {
var s;
if (t === 0) {
return b;
}
if ( (t /= d/2) === 2 ) {
return b+c;
}
if (!p) {
p = d*(0.3*1.5);
}
if ( !a || a < Math.abs(c) ) {
a = c;
s = p/4;
}
else {
s = p/(2*Math.PI) * Math.asin (c/a);
}
if (t < 1) {
return -0.5*(a*Math.pow(2,10*(t-=1)) *
Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
}
return a*Math.pow(2,-10*(t-=1)) *
Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;
},
/**
* Backtracks slightly, then reverses direction and moves to end.
* @method backIn
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} s Overshoot (optional)
* @return {Number} The computed value for the current animation frame
*/
backIn: function (t, b, c, d, s) {
if (s === undefined) {
s = 1.70158;
}
if (t === d) {
t -= 0.001;
}
return c*(t/=d)*t*((s+1)*t - s) + b;
},
/**
* Overshoots end, then reverses and comes back to end.
* @method backOut
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} s Overshoot (optional)
* @return {Number} The computed value for the current animation frame
*/
backOut: function (t, b, c, d, s) {
if (typeof s === 'undefined') {
s = 1.70158;
}
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
},
/**
* Backtracks slightly, then reverses direction, overshoots end,
* then reverses and comes back to end.
* @method backBoth
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} s Overshoot (optional)
* @return {Number} The computed value for the current animation frame
*/
backBoth: function (t, b, c, d, s) {
if (typeof s === 'undefined') {
s = 1.70158;
}
if ((t /= d/2 ) < 1) {
return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
}
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
},
/**
* Bounce off of start.
* @method bounceIn
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
bounceIn: function (t, b, c, d) {
return c - Y.Easing.bounceOut(d-t, 0, c, d) + b;
},
/**
* Bounces off end.
* @method bounceOut
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
bounceOut: function (t, b, c, d) {
if ((t/=d) < (1/2.75)) {
return c*(7.5625*t*t) + b;
} else if (t < (2/2.75)) {
return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
} else if (t < (2.5/2.75)) {
return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
}
return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
},
/**
* Bounces off start and end.
* @method bounceBoth
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
bounceBoth: function (t, b, c, d) {
if (t < d/2) {
return Y.Easing.bounceIn(t * 2, 0, c, d) * 0.5 + b;
}
return Y.Easing.bounceOut(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;
}
};
}, '3.1.1' ,{requires:['anim-base']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("anim-easing",function(A){A.Easing={easeNone:function(C,B,E,D){return E*C/D+B;},easeIn:function(C,B,E,D){return E*(C/=D)*C+B;},easeOut:function(C,B,E,D){return -E*(C/=D)*(C-2)+B;},easeBoth:function(C,B,E,D){if((C/=D/2)<1){return E/2*C*C+B;}return -E/2*((--C)*(C-2)-1)+B;},easeInStrong:function(C,B,E,D){return E*(C/=D)*C*C*C+B;},easeOutStrong:function(C,B,E,D){return -E*((C=C/D-1)*C*C*C-1)+B;},easeBothStrong:function(C,B,E,D){if((C/=D/2)<1){return E/2*C*C*C*C+B;}return -E/2*((C-=2)*C*C*C-2)+B;},elasticIn:function(D,B,H,G,C,F){var E;if(D===0){return B;}if((D/=G)===1){return B+H;}if(!F){F=G*0.3;}if(!C||C<Math.abs(H)){C=H;E=F/4;}else{E=F/(2*Math.PI)*Math.asin(H/C);}return -(C*Math.pow(2,10*(D-=1))*Math.sin((D*G-E)*(2*Math.PI)/F))+B;},elasticOut:function(D,B,H,G,C,F){var E;if(D===0){return B;}if((D/=G)===1){return B+H;}if(!F){F=G*0.3;}if(!C||C<Math.abs(H)){C=H;E=F/4;}else{E=F/(2*Math.PI)*Math.asin(H/C);}return C*Math.pow(2,-10*D)*Math.sin((D*G-E)*(2*Math.PI)/F)+H+B;},elasticBoth:function(D,B,H,G,C,F){var E;if(D===0){return B;}if((D/=G/2)===2){return B+H;}if(!F){F=G*(0.3*1.5);}if(!C||C<Math.abs(H)){C=H;E=F/4;}else{E=F/(2*Math.PI)*Math.asin(H/C);}if(D<1){return -0.5*(C*Math.pow(2,10*(D-=1))*Math.sin((D*G-E)*(2*Math.PI)/F))+B;}return C*Math.pow(2,-10*(D-=1))*Math.sin((D*G-E)*(2*Math.PI)/F)*0.5+H+B;},backIn:function(C,B,F,E,D){if(D===undefined){D=1.70158;}if(C===E){C-=0.001;}return F*(C/=E)*C*((D+1)*C-D)+B;},backOut:function(C,B,F,E,D){if(typeof D==="undefined"){D=1.70158;}return F*((C=C/E-1)*C*((D+1)*C+D)+1)+B;},backBoth:function(C,B,F,E,D){if(typeof D==="undefined"){D=1.70158;}if((C/=E/2)<1){return F/2*(C*C*(((D*=(1.525))+1)*C-D))+B;}return F/2*((C-=2)*C*(((D*=(1.525))+1)*C+D)+2)+B;},bounceIn:function(C,B,E,D){return E-A.Easing.bounceOut(D-C,0,E,D)+B;},bounceOut:function(C,B,E,D){if((C/=D)<(1/2.75)){return E*(7.5625*C*C)+B;}else{if(C<(2/2.75)){return E*(7.5625*(C-=(1.5/2.75))*C+0.75)+B;}else{if(C<(2.5/2.75)){return E*(7.5625*(C-=(2.25/2.75))*C+0.9375)+B;}}}return E*(7.5625*(C-=(2.625/2.75))*C+0.984375)+B;},bounceBoth:function(C,B,E,D){if(C<D/2){return A.Easing.bounceIn(C*2,0,E,D)*0.5+B;}return A.Easing.bounceOut(C*2-D,0,E,D)*0.5+E*0.5+B;}};},"3.1.1",{requires:["anim-base"]});

View file

@ -0,0 +1,355 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-easing', function(Y) {
/*
TERMS OF USE - EASING EQUATIONS
Open source under the BSD License.
Copyright 2001 Robert Penner All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The easing module provides methods for customizing
* how an animation behaves during each run.
* @class Easing
* @module anim
* @submodule anim-easing
*/
Y.Easing = {
/**
* Uniform speed between points.
* @for Easing
* @method easeNone
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeNone: function (t, b, c, d) {
return c*t/d + b;
},
/**
* Begins slowly and accelerates towards end. (quadratic)
* @method easeIn
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeIn: function (t, b, c, d) {
return c*(t/=d)*t + b;
},
/**
* Begins quickly and decelerates towards end. (quadratic)
* @method easeOut
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeOut: function (t, b, c, d) {
return -c *(t/=d)*(t-2) + b;
},
/**
* Begins slowly and decelerates towards end. (quadratic)
* @method easeBoth
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeBoth: function (t, b, c, d) {
if ((t/=d/2) < 1) {
return c/2*t*t + b;
}
return -c/2 * ((--t)*(t-2) - 1) + b;
},
/**
* Begins slowly and accelerates towards end. (quartic)
* @method easeInStrong
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeInStrong: function (t, b, c, d) {
return c*(t/=d)*t*t*t + b;
},
/**
* Begins quickly and decelerates towards end. (quartic)
* @method easeOutStrong
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeOutStrong: function (t, b, c, d) {
return -c * ((t=t/d-1)*t*t*t - 1) + b;
},
/**
* Begins slowly and decelerates towards end. (quartic)
* @method easeBothStrong
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeBothStrong: function (t, b, c, d) {
if ((t/=d/2) < 1) {
return c/2*t*t*t*t + b;
}
return -c/2 * ((t-=2)*t*t*t - 2) + b;
},
/**
* Snap in elastic effect.
* @method elasticIn
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} a Amplitude (optional)
* @param {Number} p Period (optional)
* @return {Number} The computed value for the current animation frame
*/
elasticIn: function (t, b, c, d, a, p) {
var s;
if (t === 0) {
return b;
}
if ( (t /= d) === 1 ) {
return b+c;
}
if (!p) {
p = d* 0.3;
}
if (!a || a < Math.abs(c)) {
a = c;
s = p/4;
}
else {
s = p/(2*Math.PI) * Math.asin (c/a);
}
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
},
/**
* Snap out elastic effect.
* @method elasticOut
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} a Amplitude (optional)
* @param {Number} p Period (optional)
* @return {Number} The computed value for the current animation frame
*/
elasticOut: function (t, b, c, d, a, p) {
var s;
if (t === 0) {
return b;
}
if ( (t /= d) === 1 ) {
return b+c;
}
if (!p) {
p=d * 0.3;
}
if (!a || a < Math.abs(c)) {
a = c;
s = p / 4;
}
else {
s = p/(2*Math.PI) * Math.asin (c/a);
}
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
},
/**
* Snap both elastic effect.
* @method elasticBoth
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} a Amplitude (optional)
* @param {Number} p Period (optional)
* @return {Number} The computed value for the current animation frame
*/
elasticBoth: function (t, b, c, d, a, p) {
var s;
if (t === 0) {
return b;
}
if ( (t /= d/2) === 2 ) {
return b+c;
}
if (!p) {
p = d*(0.3*1.5);
}
if ( !a || a < Math.abs(c) ) {
a = c;
s = p/4;
}
else {
s = p/(2*Math.PI) * Math.asin (c/a);
}
if (t < 1) {
return -0.5*(a*Math.pow(2,10*(t-=1)) *
Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
}
return a*Math.pow(2,-10*(t-=1)) *
Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;
},
/**
* Backtracks slightly, then reverses direction and moves to end.
* @method backIn
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} s Overshoot (optional)
* @return {Number} The computed value for the current animation frame
*/
backIn: function (t, b, c, d, s) {
if (s === undefined) {
s = 1.70158;
}
if (t === d) {
t -= 0.001;
}
return c*(t/=d)*t*((s+1)*t - s) + b;
},
/**
* Overshoots end, then reverses and comes back to end.
* @method backOut
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} s Overshoot (optional)
* @return {Number} The computed value for the current animation frame
*/
backOut: function (t, b, c, d, s) {
if (typeof s === 'undefined') {
s = 1.70158;
}
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
},
/**
* Backtracks slightly, then reverses direction, overshoots end,
* then reverses and comes back to end.
* @method backBoth
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} s Overshoot (optional)
* @return {Number} The computed value for the current animation frame
*/
backBoth: function (t, b, c, d, s) {
if (typeof s === 'undefined') {
s = 1.70158;
}
if ((t /= d/2 ) < 1) {
return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
}
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
},
/**
* Bounce off of start.
* @method bounceIn
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
bounceIn: function (t, b, c, d) {
return c - Y.Easing.bounceOut(d-t, 0, c, d) + b;
},
/**
* Bounces off end.
* @method bounceOut
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
bounceOut: function (t, b, c, d) {
if ((t/=d) < (1/2.75)) {
return c*(7.5625*t*t) + b;
} else if (t < (2/2.75)) {
return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
} else if (t < (2.5/2.75)) {
return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
}
return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
},
/**
* Bounces off start and end.
* @method bounceBoth
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
bounceBoth: function (t, b, c, d) {
if (t < d/2) {
return Y.Easing.bounceIn(t * 2, 0, c, d) * 0.5 + b;
}
return Y.Easing.bounceOut(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;
}
};
}, '3.1.1' ,{requires:['anim-base']});

9
lib/yui/3.1.1/build/anim/anim-min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,33 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-node-plugin', function(Y) {
/**
* Binds an Anim instance to a Node instance
* @module anim
* @class Plugin.NodeFX
* @extends Base
* @submodule anim-node-plugin
*/
var NodeFX = function(config) {
config = (config) ? Y.merge(config) : {};
config.node = config.host;
NodeFX.superclass.constructor.apply(this, arguments);
};
NodeFX.NAME = "nodefx";
NodeFX.NS = "fx";
Y.extend(NodeFX, Y.Anim);
Y.namespace('Plugin');
Y.Plugin.NodeFX = NodeFX;
}, '3.1.1' ,{requires:['node-pluginhost', 'anim-base']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("anim-node-plugin",function(B){var A=function(C){C=(C)?B.merge(C):{};C.node=C.host;A.superclass.constructor.apply(this,arguments);};A.NAME="nodefx";A.NS="fx";B.extend(A,B.Anim);B.namespace("Plugin");B.Plugin.NodeFX=A;},"3.1.1",{requires:["node-pluginhost","anim-base"]});

View file

@ -0,0 +1,33 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-node-plugin', function(Y) {
/**
* Binds an Anim instance to a Node instance
* @module anim
* @class Plugin.NodeFX
* @extends Base
* @submodule anim-node-plugin
*/
var NodeFX = function(config) {
config = (config) ? Y.merge(config) : {};
config.node = config.host;
NodeFX.superclass.constructor.apply(this, arguments);
};
NodeFX.NAME = "nodefx";
NodeFX.NS = "fx";
Y.extend(NodeFX, Y.Anim);
Y.namespace('Plugin');
Y.Plugin.NodeFX = NodeFX;
}, '3.1.1' ,{requires:['node-pluginhost', 'anim-base']});

View file

@ -0,0 +1,45 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-scroll', function(Y) {
/**
* Adds support for the <code>scroll</code> property in <code>to</code>
* and <code>from</code> attributes.
* @module anim
* @submodule anim-scroll
*/
var NUM = Number;
//TODO: deprecate for scrollTop/Left properties?
Y.Anim.behaviors.scroll = {
set: function(anim, att, from, to, elapsed, duration, fn) {
var
node = anim._node,
val = ([
fn(elapsed, NUM(from[0]), NUM(to[0]) - NUM(from[0]), duration),
fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)
]);
if (val[0]) {
node.set('scrollLeft', val[0]);
}
if (val[1]) {
node.set('scrollTop', val[1]);
}
},
get: function(anim) {
var node = anim._node;
return [node.get('scrollLeft'), node.get('scrollTop')];
}
};
}, '3.1.1' ,{requires:['anim-base']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("anim-scroll",function(B){var A=Number;B.Anim.behaviors.scroll={set:function(F,G,I,J,K,E,H){var D=F._node,C=([H(K,A(I[0]),A(J[0])-A(I[0]),E),H(K,A(I[1]),A(J[1])-A(I[1]),E)]);if(C[0]){D.set("scrollLeft",C[0]);}if(C[1]){D.set("scrollTop",C[1]);}},get:function(D){var C=D._node;return[C.get("scrollLeft"),C.get("scrollTop")];}};},"3.1.1",{requires:["anim-base"]});

View file

@ -0,0 +1,45 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-scroll', function(Y) {
/**
* Adds support for the <code>scroll</code> property in <code>to</code>
* and <code>from</code> attributes.
* @module anim
* @submodule anim-scroll
*/
var NUM = Number;
//TODO: deprecate for scrollTop/Left properties?
Y.Anim.behaviors.scroll = {
set: function(anim, att, from, to, elapsed, duration, fn) {
var
node = anim._node,
val = ([
fn(elapsed, NUM(from[0]), NUM(to[0]) - NUM(from[0]), duration),
fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)
]);
if (val[0]) {
node.set('scrollLeft', val[0]);
}
if (val[1]) {
node.set('scrollTop', val[1]);
}
},
get: function(anim) {
var node = anim._node;
return [node.get('scrollLeft'), node.get('scrollTop')];
}
};
}, '3.1.1' ,{requires:['anim-base']});

View file

@ -0,0 +1,33 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-xy', function(Y) {
/**
* Adds support for the <code>xy</code> property in <code>from</code> and
* <code>to</code> attributes.
* @module anim
* @submodule anim-xy
*/
var NUM = Number;
Y.Anim.behaviors.xy = {
set: function(anim, att, from, to, elapsed, duration, fn) {
anim._node.setXY([
fn(elapsed, NUM(from[0]), NUM(to[0]) - NUM(from[0]), duration),
fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)
]);
},
get: function(anim) {
return anim._node.getXY();
}
};
}, '3.1.1' ,{requires:['anim-base', 'node-screen']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("anim-xy",function(B){var A=Number;B.Anim.behaviors.xy={set:function(F,D,I,H,C,G,E){F._node.setXY([E(C,A(I[0]),A(H[0])-A(I[0]),G),E(C,A(I[1]),A(H[1])-A(I[1]),G)]);},get:function(C){return C._node.getXY();}};},"3.1.1",{requires:["anim-base","node-screen"]});

View file

@ -0,0 +1,33 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('anim-xy', function(Y) {
/**
* Adds support for the <code>xy</code> property in <code>from</code> and
* <code>to</code> attributes.
* @module anim
* @submodule anim-xy
*/
var NUM = Number;
Y.Anim.behaviors.xy = {
set: function(anim, att, from, to, elapsed, duration, fn) {
anim._node.setXY([
fn(elapsed, NUM(from[0]), NUM(to[0]) - NUM(from[0]), duration),
fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)
]);
},
get: function(anim) {
return anim._node.getXY();
}
};
}, '3.1.1' ,{requires:['anim-base', 'node-screen']});

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
.yui3-skin-sam .yui3-console-ft .yui3-console-filters-categories,.yui3-skin-sam .yui3-console-ft .yui3-console-filters-sources{text-align:left;padding:5px 0;border:1px inset;margin:0 2px;}.yui3-skin-sam .yui3-console-ft .yui3-console-filters-categories{background:#fff;border-bottom:2px ridge;}.yui3-skin-sam .yui3-console-ft .yui3-console-filters-sources{background:#fff;margin-bottom:2px;border-top:0 none;border-bottom-right-radius:10px;border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-moz-border-radius-bottomleft:10px;-webkit-border-bottom-right-radius:10px;-webkit-border-bottom-left-radius:10px;}.yui3-skin-sam .yui3-console-filter-label{white-space:nowrap;margin-left:1ex;}

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
.yui3-skin-sam .yui3-separate-console{position:absolute;right:1em;top:1em;z-index:999;}.yui3-skin-sam .yui3-inline-console{display:-moz-inline-stack;display:inline-block;*display:inline;zoom:1;vertical-align:top;}.yui3-skin-sam .yui3-inline-console .yui3-console-content{position:relative;}.yui3-skin-sam .yui3-console-content{background:#777;_background:#D8D8DA url(bg.png) repeat-x 0 0;font:normal 13px/1.3 Arial,sans-serif;text-align:left;border:1px solid #777;border-radius:10px;-moz-border-radius:10px;-webkit-border-radius:10px;}.yui3-skin-sam .yui3-console-hd,.yui3-skin-sam .yui3-console-bd,.yui3-skin-sam .yui3-console-ft{position:relative;}.yui3-skin-sam .yui3-console-hd,.yui3-skin-sam .yui3-console-ft .yui3-console-controls{text-align:right;}.yui3-skin-sam .yui3-console-hd{background:#D8D8DA url(bg.png) repeat-x 0 0;padding:1ex;border:1px solid transparent;_border:0 none;border-top-right-radius:10px;border-top-left-radius:10px;-moz-border-radius-topright:10px;-moz-border-radius-topleft:10px;-webkit-border-top-right-radius:10px;-webkit-border-top-left-radius:10px;}.yui3-skin-sam .yui3-console-bd{background:#fff;border-top:1px solid #777;border-bottom:1px solid #777;color:#000;font-size:11px;overflow:auto;overflow-x:auto;overflow-y:scroll;_width:100%;}.yui3-skin-sam .yui3-console-ft{background:#D8D8DA url(bg.png) repeat-x 0 0;border:1px solid transparent;_border:0 none;border-bottom-right-radius:10px;border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-moz-border-radius-bottomleft:10px;-webkit-border-bottom-right-radius:10px;-webkit-border-bottom-left-radius:10px;}.yui3-skin-sam .yui3-console-controls{padding:4px 1ex;zoom:1;}.yui3-skin-sam .yui3-console-title{color:#000;display:inline;float:left;font-weight:bold;font-size:13px;height:24px;line-height:24px;margin:0;padding-left:1ex;}.yui3-skin-sam .yui3-console-pause-label{float:left;}.yui3-skin-sam .yui3-console-button{line-height:1.3;}.yui3-skin-sam .yui3-console-collapsed .yui3-console-bd,.yui3-skin-sam .yui3-console-collapsed .yui3-console-ft{display:none;}.yui3-skin-sam .yui3-console-content.yui3-console-collapsed{-webkit-border-radius:0;}.yui3-skin-sam .yui3-console-collapsed .yui3-console-hd{border-radius:10px;-moz-border-radius:10px;-webkit-border-radius:0;}.yui3-skin-sam .yui3-console-entry{border-bottom:1px solid #aaa;min-height:32px;_height:32px;}.yui3-skin-sam .yui3-console-entry-meta{margin:0;overflow:hidden;}.yui3-skin-sam .yui3-console-entry-content{margin:0;padding:0 1ex;white-space:pre-wrap;word-wrap:break-word;}.yui3-skin-sam .yui3-console-entry-meta .yui3-console-entry-src{color:#000;font-style:italic;font-weight:bold;float:right;margin:2px 5px 0 0;}.yui3-skin-sam .yui3-console-entry-meta .yui3-console-entry-time{color:#777;padding-left:1ex;}.yui3-skin-sam .yui3-console-entry-warn .yui3-console-entry-meta .yui3-console-entry-time{color:#555;}.yui3-skin-sam .yui3-console-entry-info .yui3-console-entry-meta .yui3-console-entry-cat,.yui3-skin-sam .yui3-console-entry-warn .yui3-console-entry-meta .yui3-console-entry-cat,.yui3-skin-sam .yui3-console-entry-error .yui3-console-entry-meta .yui3-console-entry-cat{display:none;}.yui3-skin-sam .yui3-console-entry-warn{background:#aee url(warn_error.png) no-repeat -15px 15px;}.yui3-skin-sam .yui3-console-entry-error{background:#ffa url(warn_error.png) no-repeat 5px -24px;color:#900;}.yui3-skin-sam .yui3-console-entry-warn .yui3-console-entry-content,.yui3-skin-sam .yui3-console-entry-error .yui3-console-entry-content{padding-left:24px;}.yui3-skin-sam .yui3-console-entry-cat{text-transform:uppercase;padding:1px 4px;background-color:#ccc;}.yui3-skin-sam .yui3-console-entry-info .yui3-console-entry-cat{background-color:#ac2;}.yui3-skin-sam .yui3-console-entry-warn .yui3-console-entry-cat{background-color:#e81;}.yui3-skin-sam .yui3-console-entry-error .yui3-console-entry-cat{background-color:#b00;color:#fff;}.yui3-skin-sam .yui3-console-hidden{display:none;}

Binary file not shown.

After

Width:  |  Height:  |  Size: 879 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
.yui3-overlay{position:absolute;}.yui3-overlay-hidden{visibility:hidden;}.yui3-widget-tmp-forcesize .yui3-overlay-content{overflow:hidden!important;}

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
.yui3-slider,.yui3-slider-rail{display:-moz-inline-stack;display:inline-block;*display:inline;zoom:1;vertical-align:middle;}.yui3-slider-content{position:relative;display:block;}.yui3-slider-rail{position:relative;}.yui3-slider-rail-cap-top,.yui3-slider-rail-cap-left,.yui3-slider-rail-cap-bottom,.yui3-slider-rail-cap-right,.yui3-slider-thumb,.yui3-slider-thumb-image,.yui3-slider-thumb-shadow{position:absolute;}.yui3-slider-thumb{overflow:hidden;}.yui3-skin-sam .yui3-slider-x .yui3-slider-rail,.yui3-skin-sam .yui3-slider-x .yui3-slider-rail-cap-left,.yui3-skin-sam .yui3-slider-x .yui3-slider-rail-cap-right{background-image:url(rail-x.png);background-repeat:repeat-x;}.yui3-skin-sam .yui3-slider-x .yui3-slider-rail{height:26px;}.yui3-skin-sam .yui3-slider-x .yui3-slider-thumb{height:26px;width:15px;}.yui3-skin-sam .yui3-slider-x .yui3-slider-rail-cap-left{background-position:0 -20px;height:20px;left:-2px;width:5px;}.yui3-skin-sam .yui3-slider-x .yui3-slider-rail-cap-right{background-position:0 -40px;height:20px;right:-2px;width:5px;}.yui3-skin-sam .yui3-slider-x .yui3-slider-thumb-image{left:0;top:-10px;}.yui3-skin-sam .yui3-slider-x .yui3-slider-thumb-shadow{left:0;opacity:.15;filter:alpha(opacity=15);top:-50px;}.yui3-skin-sam .yui3-slider-y .yui3-slider-rail,.yui3-skin-sam .yui3-slider-y .yui3-slider-rail-cap-top,.yui3-skin-sam .yui3-slider-y .yui3-slider-rail-cap-bottom{background-image:url(rail-y.png);background-repeat:repeat-y;}.yui3-skin-sam .yui3-slider-y .yui3-slider-rail{width:26px;}.yui3-skin-sam .yui3-slider-y .yui3-slider-thumb{width:26px;height:15px;}.yui3-skin-sam .yui3-slider-y .yui3-slider-rail-cap-top{background-position:-20px 0;width:20px;top:-2px;height:5px;}.yui3-skin-sam .yui3-slider-y .yui3-slider-rail-cap-bottom{background-position:-40px 0;width:20px;bottom:-2px;height:5px;}.yui3-skin-sam .yui3-slider-y .yui3-slider-thumb-image{left:-10px;top:0;}.yui3-skin-sam .yui3-slider-y .yui3-slider-thumb-shadow{left:-50px;opacity:.15;filter:alpha(opacity=15);top:0;}

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
.yui3-slider,.yui3-slider-rail{display:-moz-inline-stack;display:inline-block;*display:inline;zoom:1;vertical-align:middle;}.yui3-slider-content{position:relative;display:block;}.yui3-slider-rail{position:relative;}.yui3-slider-rail-cap-top,.yui3-slider-rail-cap-left,.yui3-slider-rail-cap-bottom,.yui3-slider-rail-cap-right,.yui3-slider-thumb,.yui3-slider-thumb-image,.yui3-slider-thumb-shadow{position:absolute;}.yui3-slider-thumb{overflow:hidden;}.yui3-skin-sam .yui3-slider-x .yui3-slider-rail,.yui3-skin-sam .yui3-slider-x .yui3-slider-rail-cap-left,.yui3-skin-sam .yui3-slider-x .yui3-slider-rail-cap-right{background-image:url(rail-x.png);background-repeat:repeat-x;}.yui3-skin-sam .yui3-slider-x .yui3-slider-rail{height:26px;}.yui3-skin-sam .yui3-slider-x .yui3-slider-thumb{height:26px;width:15px;}.yui3-skin-sam .yui3-slider-x .yui3-slider-rail-cap-left{background-position:0 -20px;height:20px;left:-2px;width:5px;}.yui3-skin-sam .yui3-slider-x .yui3-slider-rail-cap-right{background-position:0 -40px;height:20px;right:-2px;width:5px;}.yui3-skin-sam .yui3-slider-x .yui3-slider-thumb-image{left:0;top:-10px;}.yui3-skin-sam .yui3-slider-x .yui3-slider-thumb-shadow{left:0;opacity:.15;filter:alpha(opacity=15);top:-50px;}.yui3-skin-sam .yui3-slider-y .yui3-slider-rail,.yui3-skin-sam .yui3-slider-y .yui3-slider-rail-cap-top,.yui3-skin-sam .yui3-slider-y .yui3-slider-rail-cap-bottom{background-image:url(rail-y.png);background-repeat:repeat-y;}.yui3-skin-sam .yui3-slider-y .yui3-slider-rail{width:26px;}.yui3-skin-sam .yui3-slider-y .yui3-slider-thumb{width:26px;height:15px;}.yui3-skin-sam .yui3-slider-y .yui3-slider-rail-cap-top{background-position:-20px 0;width:20px;top:-2px;height:5px;}.yui3-skin-sam .yui3-slider-y .yui3-slider-rail-cap-bottom{background-position:-40px 0;width:20px;bottom:-2px;height:5px;}.yui3-skin-sam .yui3-slider-y .yui3-slider-thumb-image{left:-10px;top:0;}.yui3-skin-sam .yui3-slider-y .yui3-slider-thumb-shadow{left:-50px;opacity:.15;filter:alpha(opacity=15);top:0;}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
.yui3-tab-panel{display:none;}.yui3-tab-panel-selected{display:block;}.yui3-tabview-list,.yui3-tab{margin:0;padding:0;list-style:none;}.yui3-tabview{position:relative;}.yui3-tabview,.yui3-tabview-list,.yui3-tabview-panel,.yui3-tab,.yui3-tab-panel{zoom:1;}.yui3-tab{display:inline-block;*display:inline;vertical-align:bottom;cursor:pointer;}.yui3-tab-label{display:block;display:inline-block;padding:6px 10px;position:relative;text-decoration:none;vertical-align:bottom;}.yui3-skin-sam .yui3-tabview-list{border:solid #2647a0;border-width:0 0 5px;zoom:1;}.yui3-skin-sam .yui3-tab{margin:0 .2em 0 0;padding:1px 0 0;zoom:1;}.yui3-skin-sam .yui3-tab-selected{margin-bottom:-1px;}.yui3-skin-sam .yui3-tab-label{background:#d8d8d8 url(sprite.png) repeat-x;border:solid #a3a3a3;border-width:1px 1px 0 1px;color:#000;cursor:hand;font-size:85%;padding:.3em .75em;text-decoration:none;}.yui3-skin-sam .yui3-tab-label:hover,.yui3-skin-sam .yui3-tab-label:focus{background:#bfdaff url(sprite.png) repeat-x left -1300px;outline:0;}.yui3-skin-sam .yui3-tab-selected .yui3-tab-label,.yui3-skin-sam .yui3-tab-selected .yui3-tab-label:focus,.yui3-skin-sam .yui3-tab-selected .yui3-tab-label:hover{background:#2647a0 url(sprite.png) repeat-x left -1400px;color:#fff;}.yui3-skin-sam .yui3-tab-selected .yui3-tab-label{padding:.4em .75em;}.yui3-skin-sam .yui3-tab-selected .yui3-tab-label{border-color:#243356;}.yui3-skin-sam .yui3-tabview-panel{background:#edf5ff;}.yui3-skin-sam .yui3-tabview-panel{border:1px solid #808080;border-top-color:#243356;padding:.25em .5em;}

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
.yui3-skin-sam .yui3-console-entry-pass .yui3-console-entry-cat{background-color:green;color:#fff;}.yui3-skin-sam .yui3-console-entry-fail .yui3-console-entry-cat{background-color:red;color:#fff;}.yui3-skin-sam .yui3-console-entry-ignore .yui3-console-entry-cat{background-color:#666;}

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 B

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
.yui3-widget-hidden{display:none;}.yui3-widget-content{overflow:hidden;}.yui3-widget-content-expanded{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;height:100%;}.yui3-widget-tmp-forcesize{overflow:hidden!important;}

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
.yui3-widget-stacked .yui3-widget-shim{opacity:0;filter:alpha(opacity=0);position:absolute;border:none;top:0;left:0;padding:0;margin:0;z-index:-1;width:100%;height:100%;_width:0;_height:0;}

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
.yui3-widget-hidden{display:none;}.yui3-widget-content{overflow:hidden;}.yui3-widget-content-expanded{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;height:100%;}.yui3-widget-tmp-forcesize{overflow:hidden!important;}

View file

@ -0,0 +1,529 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('async-queue', function(Y) {
/**
* <p>AsyncQueue allows you create a chain of function callbacks executed
* via setTimeout (or synchronously) that are guaranteed to run in order.
* Items in the queue can be promoted or removed. Start or resume the
* execution chain with run(). pause() to temporarily delay execution, or
* stop() to halt and clear the queue.</p>
*
* @module async-queue
*/
/**
* <p>A specialized queue class that supports scheduling callbacks to execute
* sequentially, iteratively, even asynchronously.</p>
*
* <p>Callbacks can be function refs or objects with the following keys. Only
* the <code>fn</code> key is required.</p>
*
* <ul>
* <li><code>fn</code> -- The callback function</li>
* <li><code>context</code> -- The execution context for the callbackFn.</li>
* <li><code>args</code> -- Arguments to pass to callbackFn.</li>
* <li><code>timeout</code> -- Millisecond delay before executing callbackFn.
* (Applies to each iterative execution of callback)</li>
* <li><code>iterations</code> -- Number of times to repeat the callback.
* <li><code>until</code> -- Repeat the callback until this function returns
* true. This setting trumps iterations.</li>
* <li><code>autoContinue</code> -- Set to false to prevent the AsyncQueue from
* executing the next callback in the Queue after
* the callback completes.</li>
* <li><code>id</code> -- Name that can be used to get, promote, get the
* indexOf, or delete this callback.</li>
* </ul>
*
* @class AsyncQueue
* @extends EventTarget
* @constructor
* @param callback* {Function|Object} 0..n callbacks to seed the queue
*/
Y.AsyncQueue = function() {
this._init();
this.add.apply(this, arguments);
};
var Queue = Y.AsyncQueue,
EXECUTE = 'execute',
SHIFT = 'shift',
PROMOTE = 'promote',
REMOVE = 'remove',
isObject = Y.Lang.isObject,
isFunction = Y.Lang.isFunction;
/**
* <p>Static default values used to populate callback configuration properties.
* Preconfigured defaults include:</p>
*
* <ul>
* <li><code>autoContinue</code>: <code>true</code></li>
* <li><code>iterations</code>: 1</li>
* <li><code>timeout</code>: 10 (10ms between callbacks)</li>
* <li><code>until</code>: (function to run until iterations &lt;= 0)</li>
* </ul>
*
* @property AsyncQueue.defaults
* @type {Object}
* @static
*/
Queue.defaults = Y.mix({
autoContinue : true,
iterations : 1,
timeout : 10,
until : function () {
this.iterations |= 0;
return this.iterations <= 0;
}
}, Y.config.queueDefaults || {});
Y.extend(Queue, Y.EventTarget, {
/**
* Used to indicate the queue is currently executing a callback.
*
* @property _running
* @type {Boolean|Object} true for synchronous callback execution, the
* return handle from Y.later for async callbacks.
* Otherwise false.
* @protected
*/
_running : false,
/**
* Initializes the AsyncQueue instance properties and events.
*
* @method _init
* @protected
*/
_init : function () {
Y.EventTarget.call(this, { emitFacade: true });
this._q = [];
/**
* Callback defaults for this instance. Static defaults that are not
* overridden are also included.
*
* @property defaults
* @type {Object}
*/
this.defaults = {};
this._initEvents();
},
/**
* Initializes the instance events.
*
* @method _initEvents
* @protected
*/
_initEvents : function () {
this.publish({
'execute' : { defaultFn : this._defExecFn, emitFacade: true },
'shift' : { defaultFn : this._defShiftFn, emitFacade: true },
'add' : { defaultFn : this._defAddFn, emitFacade: true },
'promote' : { defaultFn : this._defPromoteFn, emitFacade: true },
'remove' : { defaultFn : this._defRemoveFn, emitFacade: true }
});
},
/**
* Returns the next callback needing execution. If a callback is
* configured to repeat via iterations or until, it will be returned until
* the completion criteria is met.
*
* When the queue is empty, null is returned.
*
* @method next
* @return {Function} the callback to execute
*/
next : function () {
var callback;
while (this._q.length) {
callback = this._q[0] = this._prepare(this._q[0]);
if (callback && callback.until()) {
this.fire(SHIFT, { callback: callback });
callback = null;
} else {
break;
}
}
return callback || null;
},
/**
* Default functionality for the &quot;shift&quot; event. Shifts the
* callback stored in the event object's <em>callback</em> property from
* the queue if it is the first item.
*
* @method _defShiftFn
* @param e {Event} The event object
* @protected
*/
_defShiftFn : function (e) {
if (this.indexOf(e.callback) === 0) {
this._q.shift();
}
},
/**
* Creates a wrapper function to execute the callback using the aggregated
* configuration generated by combining the static AsyncQueue.defaults, the
* instance defaults, and the specified callback settings.
*
* The wrapper function is decorated with the callback configuration as
* properties for runtime modification.
*
* @method _prepare
* @param callback {Object|Function} the raw callback
* @return {Function} a decorated function wrapper to execute the callback
* @protected
*/
_prepare: function (callback) {
if (isFunction(callback) && callback._prepared) {
return callback;
}
var config = Y.merge(
Queue.defaults,
{ context : this, args: [], _prepared: true },
this.defaults,
(isFunction(callback) ? { fn: callback } : callback)),
wrapper = Y.bind(function () {
if (!wrapper._running) {
wrapper.iterations--;
}
if (isFunction(wrapper.fn)) {
wrapper.fn.apply(wrapper.context || Y,
Y.Array(wrapper.args));
}
}, this);
return Y.mix(wrapper, config);
},
/**
* Sets the queue in motion. All queued callbacks will be executed in
* order unless pause() or stop() is called or if one of the callbacks is
* configured with autoContinue: false.
*
* @method run
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
run : function () {
var callback,
cont = true;
for (callback = this.next();
cont && callback && !this.isRunning();
callback = this.next())
{
cont = (callback.timeout < 0) ?
this._execute(callback) :
this._schedule(callback);
}
if (!callback) {
/**
* Event fired after the last queued callback is executed.
* @event complete
*/
this.fire('complete');
}
return this;
},
/**
* Handles the execution of callbacks. Returns a boolean indicating
* whether it is appropriate to continue running.
*
* @method _execute
* @param callback {Object} the callback object to execute
* @return {Boolean} whether the run loop should continue
* @protected
*/
_execute : function (callback) {
this._running = callback._running = true;
callback.iterations--;
this.fire(EXECUTE, { callback: callback });
var cont = this._running && callback.autoContinue;
this._running = callback._running = false;
return cont;
},
/**
* Schedules the execution of asynchronous callbacks.
*
* @method _schedule
* @param callback {Object} the callback object to execute
* @return {Boolean} whether the run loop should continue
* @protected
*/
_schedule : function (callback) {
this._running = Y.later(callback.timeout, this, function () {
if (this._execute(callback)) {
this.run();
}
});
return false;
},
/**
* Determines if the queue is waiting for a callback to complete execution.
*
* @method isRunning
* @return {Boolean} true if queue is waiting for a
* from any initiated transactions
*/
isRunning : function () {
return !!this._running;
},
/**
* Default functionality for the &quot;execute&quot; event. Executes the
* callback function
*
* @method _defExecFn
* @param e {Event} the event object
* @protected
*/
_defExecFn : function (e) {
e.callback();
},
/**
* Add any number of callbacks to the end of the queue. Callbacks may be
* provided as functions or objects.
*
* @method add
* @param callback* {Function|Object} 0..n callbacks
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
add : function () {
this.fire('add', { callbacks: Y.Array(arguments,0,true) });
return this;
},
/**
* Default functionality for the &quot;add&quot; event. Adds the callbacks
* in the event facade to the queue. Callbacks successfully added to the
* queue are present in the event's <code>added</code> property in the
* after phase.
*
* @method _defAddFn
* @param e {Event} the event object
* @protected
*/
_defAddFn : function(e) {
var _q = this._q,
added = [];
Y.Array.each(e.callbacks, function (c) {
if (isObject(c)) {
_q.push(c);
added.push(c);
}
});
e.added = added;
},
/**
* Pause the execution of the queue after the execution of the current
* callback completes. If called from code outside of a queued callback,
* clears the timeout for the pending callback. Paused queue can be
* restarted with q.run()
*
* @method pause
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
pause: function () {
if (isObject(this._running)) {
this._running.cancel();
}
this._running = false;
return this;
},
/**
* Stop and clear the queue after the current execution of the
* current callback completes.
*
* @method stop
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
stop : function () {
this._q = [];
return this.pause();
},
/**
* Returns the current index of a callback. Pass in either the id or
* callback function from getCallback.
*
* @method indexOf
* @param callback {String|Function} the callback or its specified id
* @return {Number} index of the callback or -1 if not found
*/
indexOf : function (callback) {
var i = 0, len = this._q.length, c;
for (; i < len; ++i) {
c = this._q[i];
if (c === callback || c.id === callback) {
return i;
}
}
return -1;
},
/**
* Retrieve a callback by its id. Useful to modify the configuration
* while the queue is running.
*
* @method getCallback
* @param id {String} the id assigned to the callback
* @return {Object} the callback object
*/
getCallback : function (id) {
var i = this.indexOf(id);
return (i > -1) ? this._q[i] : null;
},
/**
* Promotes the named callback to the top of the queue. If a callback is
* currently executing or looping (via until or iterations), the promotion
* is scheduled to occur after the current callback has completed.
*
* @method promote
* @param callback {String|Object} the callback object or a callback's id
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
promote : function (callback) {
var payload = { callback : callback },e;
if (this.isRunning()) {
e = this.after(SHIFT, function () {
this.fire(PROMOTE, payload);
e.detach();
}, this);
} else {
this.fire(PROMOTE, payload);
}
return this;
},
/**
* <p>Default functionality for the &quot;promote&quot; event. Promotes the
* named callback to the head of the queue.</p>
*
* <p>The event object will contain a property &quot;callback&quot;, which
* holds the id of a callback or the callback object itself.</p>
*
* @method _defPromoteFn
* @param e {Event} the custom event
* @protected
*/
_defPromoteFn : function (e) {
var i = this.indexOf(e.callback),
promoted = (i > -1) ? this._q.splice(i,1)[0] : null;
e.promoted = promoted;
if (promoted) {
this._q.unshift(promoted);
}
},
/**
* Removes the callback from the queue. If the queue is active, the
* removal is scheduled to occur after the current callback has completed.
*
* @method remove
* @param callback {String|Object} the callback object or a callback's id
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
remove : function (callback) {
var payload = { callback : callback },e;
// Can't return the removed callback because of the deferral until
// current callback is complete
if (this.isRunning()) {
e = this.after(SHIFT, function () {
this.fire(REMOVE, payload);
e.detach();
},this);
} else {
this.fire(REMOVE, payload);
}
return this;
},
/**
* <p>Default functionality for the &quot;remove&quot; event. Removes the
* callback from the queue.</p>
*
* <p>The event object will contain a property &quot;callback&quot;, which
* holds the id of a callback or the callback object itself.</p>
*
* @method _defRemoveFn
* @param e {Event} the custom event
* @protected
*/
_defRemoveFn : function (e) {
var i = this.indexOf(e.callback);
e.removed = (i > -1) ? this._q.splice(i,1)[0] : null;
},
/**
* Returns the number of callbacks in the queue.
*
* @method size
* @return {Number}
*/
size : function () {
// next() flushes callbacks that have met their until() criteria and
// therefore shouldn't count since they wouldn't execute anyway.
if (!this.isRunning()) {
this.next();
}
return this._q.length;
}
});
}, '3.1.1' ,{requires:['event-custom']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("async-queue",function(G){G.AsyncQueue=function(){this._init();this.add.apply(this,arguments);};var E=G.AsyncQueue,C="execute",B="shift",D="promote",H="remove",A=G.Lang.isObject,F=G.Lang.isFunction;E.defaults=G.mix({autoContinue:true,iterations:1,timeout:10,until:function(){this.iterations|=0;return this.iterations<=0;}},G.config.queueDefaults||{});G.extend(E,G.EventTarget,{_running:false,_init:function(){G.EventTarget.call(this,{emitFacade:true});this._q=[];this.defaults={};this._initEvents();},_initEvents:function(){this.publish({"execute":{defaultFn:this._defExecFn,emitFacade:true},"shift":{defaultFn:this._defShiftFn,emitFacade:true},"add":{defaultFn:this._defAddFn,emitFacade:true},"promote":{defaultFn:this._defPromoteFn,emitFacade:true},"remove":{defaultFn:this._defRemoveFn,emitFacade:true}});},next:function(){var I;while(this._q.length){I=this._q[0]=this._prepare(this._q[0]);if(I&&I.until()){this.fire(B,{callback:I});I=null;}else{break;}}return I||null;},_defShiftFn:function(I){if(this.indexOf(I.callback)===0){this._q.shift();}},_prepare:function(K){if(F(K)&&K._prepared){return K;}var I=G.merge(E.defaults,{context:this,args:[],_prepared:true},this.defaults,(F(K)?{fn:K}:K)),J=G.bind(function(){if(!J._running){J.iterations--;}if(F(J.fn)){J.fn.apply(J.context||G,G.Array(J.args));}},this);return G.mix(J,I);},run:function(){var J,I=true;for(J=this.next();I&&J&&!this.isRunning();J=this.next()){I=(J.timeout<0)?this._execute(J):this._schedule(J);}if(!J){this.fire("complete");}return this;},_execute:function(J){this._running=J._running=true;J.iterations--;this.fire(C,{callback:J});var I=this._running&&J.autoContinue;this._running=J._running=false;return I;},_schedule:function(I){this._running=G.later(I.timeout,this,function(){if(this._execute(I)){this.run();}});return false;},isRunning:function(){return !!this._running;},_defExecFn:function(I){I.callback();},add:function(){this.fire("add",{callbacks:G.Array(arguments,0,true)});return this;},_defAddFn:function(J){var K=this._q,I=[];G.Array.each(J.callbacks,function(L){if(A(L)){K.push(L);I.push(L);}});J.added=I;},pause:function(){if(A(this._running)){this._running.cancel();}this._running=false;return this;},stop:function(){this._q=[];return this.pause();},indexOf:function(L){var J=0,I=this._q.length,K;for(;J<I;++J){K=this._q[J];if(K===L||K.id===L){return J;}}return -1;},getCallback:function(J){var I=this.indexOf(J);return(I>-1)?this._q[I]:null;},promote:function(K){var J={callback:K},I;if(this.isRunning()){I=this.after(B,function(){this.fire(D,J);I.detach();},this);}else{this.fire(D,J);}return this;},_defPromoteFn:function(K){var I=this.indexOf(K.callback),J=(I>-1)?this._q.splice(I,1)[0]:null;K.promoted=J;if(J){this._q.unshift(J);}},remove:function(K){var J={callback:K},I;if(this.isRunning()){I=this.after(B,function(){this.fire(H,J);I.detach();},this);}else{this.fire(H,J);}return this;},_defRemoveFn:function(J){var I=this.indexOf(J.callback);J.removed=(I>-1)?this._q.splice(I,1)[0]:null;},size:function(){if(!this.isRunning()){this.next();}return this._q.length;}});},"3.1.1",{requires:["event-custom"]});

View file

@ -0,0 +1,529 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('async-queue', function(Y) {
/**
* <p>AsyncQueue allows you create a chain of function callbacks executed
* via setTimeout (or synchronously) that are guaranteed to run in order.
* Items in the queue can be promoted or removed. Start or resume the
* execution chain with run(). pause() to temporarily delay execution, or
* stop() to halt and clear the queue.</p>
*
* @module async-queue
*/
/**
* <p>A specialized queue class that supports scheduling callbacks to execute
* sequentially, iteratively, even asynchronously.</p>
*
* <p>Callbacks can be function refs or objects with the following keys. Only
* the <code>fn</code> key is required.</p>
*
* <ul>
* <li><code>fn</code> -- The callback function</li>
* <li><code>context</code> -- The execution context for the callbackFn.</li>
* <li><code>args</code> -- Arguments to pass to callbackFn.</li>
* <li><code>timeout</code> -- Millisecond delay before executing callbackFn.
* (Applies to each iterative execution of callback)</li>
* <li><code>iterations</code> -- Number of times to repeat the callback.
* <li><code>until</code> -- Repeat the callback until this function returns
* true. This setting trumps iterations.</li>
* <li><code>autoContinue</code> -- Set to false to prevent the AsyncQueue from
* executing the next callback in the Queue after
* the callback completes.</li>
* <li><code>id</code> -- Name that can be used to get, promote, get the
* indexOf, or delete this callback.</li>
* </ul>
*
* @class AsyncQueue
* @extends EventTarget
* @constructor
* @param callback* {Function|Object} 0..n callbacks to seed the queue
*/
Y.AsyncQueue = function() {
this._init();
this.add.apply(this, arguments);
};
var Queue = Y.AsyncQueue,
EXECUTE = 'execute',
SHIFT = 'shift',
PROMOTE = 'promote',
REMOVE = 'remove',
isObject = Y.Lang.isObject,
isFunction = Y.Lang.isFunction;
/**
* <p>Static default values used to populate callback configuration properties.
* Preconfigured defaults include:</p>
*
* <ul>
* <li><code>autoContinue</code>: <code>true</code></li>
* <li><code>iterations</code>: 1</li>
* <li><code>timeout</code>: 10 (10ms between callbacks)</li>
* <li><code>until</code>: (function to run until iterations &lt;= 0)</li>
* </ul>
*
* @property AsyncQueue.defaults
* @type {Object}
* @static
*/
Queue.defaults = Y.mix({
autoContinue : true,
iterations : 1,
timeout : 10,
until : function () {
this.iterations |= 0;
return this.iterations <= 0;
}
}, Y.config.queueDefaults || {});
Y.extend(Queue, Y.EventTarget, {
/**
* Used to indicate the queue is currently executing a callback.
*
* @property _running
* @type {Boolean|Object} true for synchronous callback execution, the
* return handle from Y.later for async callbacks.
* Otherwise false.
* @protected
*/
_running : false,
/**
* Initializes the AsyncQueue instance properties and events.
*
* @method _init
* @protected
*/
_init : function () {
Y.EventTarget.call(this, { emitFacade: true });
this._q = [];
/**
* Callback defaults for this instance. Static defaults that are not
* overridden are also included.
*
* @property defaults
* @type {Object}
*/
this.defaults = {};
this._initEvents();
},
/**
* Initializes the instance events.
*
* @method _initEvents
* @protected
*/
_initEvents : function () {
this.publish({
'execute' : { defaultFn : this._defExecFn, emitFacade: true },
'shift' : { defaultFn : this._defShiftFn, emitFacade: true },
'add' : { defaultFn : this._defAddFn, emitFacade: true },
'promote' : { defaultFn : this._defPromoteFn, emitFacade: true },
'remove' : { defaultFn : this._defRemoveFn, emitFacade: true }
});
},
/**
* Returns the next callback needing execution. If a callback is
* configured to repeat via iterations or until, it will be returned until
* the completion criteria is met.
*
* When the queue is empty, null is returned.
*
* @method next
* @return {Function} the callback to execute
*/
next : function () {
var callback;
while (this._q.length) {
callback = this._q[0] = this._prepare(this._q[0]);
if (callback && callback.until()) {
this.fire(SHIFT, { callback: callback });
callback = null;
} else {
break;
}
}
return callback || null;
},
/**
* Default functionality for the &quot;shift&quot; event. Shifts the
* callback stored in the event object's <em>callback</em> property from
* the queue if it is the first item.
*
* @method _defShiftFn
* @param e {Event} The event object
* @protected
*/
_defShiftFn : function (e) {
if (this.indexOf(e.callback) === 0) {
this._q.shift();
}
},
/**
* Creates a wrapper function to execute the callback using the aggregated
* configuration generated by combining the static AsyncQueue.defaults, the
* instance defaults, and the specified callback settings.
*
* The wrapper function is decorated with the callback configuration as
* properties for runtime modification.
*
* @method _prepare
* @param callback {Object|Function} the raw callback
* @return {Function} a decorated function wrapper to execute the callback
* @protected
*/
_prepare: function (callback) {
if (isFunction(callback) && callback._prepared) {
return callback;
}
var config = Y.merge(
Queue.defaults,
{ context : this, args: [], _prepared: true },
this.defaults,
(isFunction(callback) ? { fn: callback } : callback)),
wrapper = Y.bind(function () {
if (!wrapper._running) {
wrapper.iterations--;
}
if (isFunction(wrapper.fn)) {
wrapper.fn.apply(wrapper.context || Y,
Y.Array(wrapper.args));
}
}, this);
return Y.mix(wrapper, config);
},
/**
* Sets the queue in motion. All queued callbacks will be executed in
* order unless pause() or stop() is called or if one of the callbacks is
* configured with autoContinue: false.
*
* @method run
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
run : function () {
var callback,
cont = true;
for (callback = this.next();
cont && callback && !this.isRunning();
callback = this.next())
{
cont = (callback.timeout < 0) ?
this._execute(callback) :
this._schedule(callback);
}
if (!callback) {
/**
* Event fired after the last queued callback is executed.
* @event complete
*/
this.fire('complete');
}
return this;
},
/**
* Handles the execution of callbacks. Returns a boolean indicating
* whether it is appropriate to continue running.
*
* @method _execute
* @param callback {Object} the callback object to execute
* @return {Boolean} whether the run loop should continue
* @protected
*/
_execute : function (callback) {
this._running = callback._running = true;
callback.iterations--;
this.fire(EXECUTE, { callback: callback });
var cont = this._running && callback.autoContinue;
this._running = callback._running = false;
return cont;
},
/**
* Schedules the execution of asynchronous callbacks.
*
* @method _schedule
* @param callback {Object} the callback object to execute
* @return {Boolean} whether the run loop should continue
* @protected
*/
_schedule : function (callback) {
this._running = Y.later(callback.timeout, this, function () {
if (this._execute(callback)) {
this.run();
}
});
return false;
},
/**
* Determines if the queue is waiting for a callback to complete execution.
*
* @method isRunning
* @return {Boolean} true if queue is waiting for a
* from any initiated transactions
*/
isRunning : function () {
return !!this._running;
},
/**
* Default functionality for the &quot;execute&quot; event. Executes the
* callback function
*
* @method _defExecFn
* @param e {Event} the event object
* @protected
*/
_defExecFn : function (e) {
e.callback();
},
/**
* Add any number of callbacks to the end of the queue. Callbacks may be
* provided as functions or objects.
*
* @method add
* @param callback* {Function|Object} 0..n callbacks
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
add : function () {
this.fire('add', { callbacks: Y.Array(arguments,0,true) });
return this;
},
/**
* Default functionality for the &quot;add&quot; event. Adds the callbacks
* in the event facade to the queue. Callbacks successfully added to the
* queue are present in the event's <code>added</code> property in the
* after phase.
*
* @method _defAddFn
* @param e {Event} the event object
* @protected
*/
_defAddFn : function(e) {
var _q = this._q,
added = [];
Y.Array.each(e.callbacks, function (c) {
if (isObject(c)) {
_q.push(c);
added.push(c);
}
});
e.added = added;
},
/**
* Pause the execution of the queue after the execution of the current
* callback completes. If called from code outside of a queued callback,
* clears the timeout for the pending callback. Paused queue can be
* restarted with q.run()
*
* @method pause
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
pause: function () {
if (isObject(this._running)) {
this._running.cancel();
}
this._running = false;
return this;
},
/**
* Stop and clear the queue after the current execution of the
* current callback completes.
*
* @method stop
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
stop : function () {
this._q = [];
return this.pause();
},
/**
* Returns the current index of a callback. Pass in either the id or
* callback function from getCallback.
*
* @method indexOf
* @param callback {String|Function} the callback or its specified id
* @return {Number} index of the callback or -1 if not found
*/
indexOf : function (callback) {
var i = 0, len = this._q.length, c;
for (; i < len; ++i) {
c = this._q[i];
if (c === callback || c.id === callback) {
return i;
}
}
return -1;
},
/**
* Retrieve a callback by its id. Useful to modify the configuration
* while the queue is running.
*
* @method getCallback
* @param id {String} the id assigned to the callback
* @return {Object} the callback object
*/
getCallback : function (id) {
var i = this.indexOf(id);
return (i > -1) ? this._q[i] : null;
},
/**
* Promotes the named callback to the top of the queue. If a callback is
* currently executing or looping (via until or iterations), the promotion
* is scheduled to occur after the current callback has completed.
*
* @method promote
* @param callback {String|Object} the callback object or a callback's id
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
promote : function (callback) {
var payload = { callback : callback },e;
if (this.isRunning()) {
e = this.after(SHIFT, function () {
this.fire(PROMOTE, payload);
e.detach();
}, this);
} else {
this.fire(PROMOTE, payload);
}
return this;
},
/**
* <p>Default functionality for the &quot;promote&quot; event. Promotes the
* named callback to the head of the queue.</p>
*
* <p>The event object will contain a property &quot;callback&quot;, which
* holds the id of a callback or the callback object itself.</p>
*
* @method _defPromoteFn
* @param e {Event} the custom event
* @protected
*/
_defPromoteFn : function (e) {
var i = this.indexOf(e.callback),
promoted = (i > -1) ? this._q.splice(i,1)[0] : null;
e.promoted = promoted;
if (promoted) {
this._q.unshift(promoted);
}
},
/**
* Removes the callback from the queue. If the queue is active, the
* removal is scheduled to occur after the current callback has completed.
*
* @method remove
* @param callback {String|Object} the callback object or a callback's id
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
remove : function (callback) {
var payload = { callback : callback },e;
// Can't return the removed callback because of the deferral until
// current callback is complete
if (this.isRunning()) {
e = this.after(SHIFT, function () {
this.fire(REMOVE, payload);
e.detach();
},this);
} else {
this.fire(REMOVE, payload);
}
return this;
},
/**
* <p>Default functionality for the &quot;remove&quot; event. Removes the
* callback from the queue.</p>
*
* <p>The event object will contain a property &quot;callback&quot;, which
* holds the id of a callback or the callback object itself.</p>
*
* @method _defRemoveFn
* @param e {Event} the custom event
* @protected
*/
_defRemoveFn : function (e) {
var i = this.indexOf(e.callback);
e.removed = (i > -1) ? this._q.splice(i,1)[0] : null;
},
/**
* Returns the number of callbacks in the queue.
*
* @method size
* @return {Number}
*/
size : function () {
// next() flushes callbacks that have met their until() criteria and
// therefore shouldn't count since they wouldn't execute anyway.
if (!this.isRunning()) {
this.next();
}
return this._q.length;
}
});
}, '3.1.1' ,{requires:['event-custom']});

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,130 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('attribute-complex', function(Y) {
/**
* Adds support for attribute providers to handle complex attributes in the constructor
*
* @module attribute
* @submodule attribute-complex
* @for Attribute
*/
var O = Y.Object,
DOT = ".";
Y.Attribute.Complex = function() {};
Y.Attribute.Complex.prototype = {
/**
* Utility method to split out simple attribute name/value pairs ("x")
* from complex attribute name/value pairs ("x.y.z"), so that complex
* attributes can be keyed by the top level attribute name.
*
* @method _normAttrVals
* @param {Object} valueHash An object with attribute name/value pairs
*
* @return {Object} An object literal with 2 properties - "simple" and "complex",
* containing simple and complex attribute values respectively keyed
* by the top level attribute name, or null, if valueHash is falsey.
*
* @private
*/
_normAttrVals : function(valueHash) {
var vals = {},
subvals = {},
path,
attr,
v, k;
if (valueHash) {
for (k in valueHash) {
if (valueHash.hasOwnProperty(k)) {
if (k.indexOf(DOT) !== -1) {
path = k.split(DOT);
attr = path.shift();
v = subvals[attr] = subvals[attr] || [];
v[v.length] = {
path : path,
value: valueHash[k]
};
} else {
vals[k] = valueHash[k];
}
}
}
return { simple:vals, complex:subvals };
} else {
return null;
}
},
/**
* Returns the initial value of the given attribute from
* either the default configuration provided, or the
* over-ridden value if it exists in the set of initValues
* provided and the attribute is not read-only.
*
* @param {String} attr The name of the attribute
* @param {Object} cfg The attribute configuration object
* @param {Object} initValues The object with simple and complex attribute name/value pairs returned from _normAttrVals
*
* @return {Any} The initial value of the attribute.
*
* @method _getAttrInitVal
* @private
*/
_getAttrInitVal : function(attr, cfg, initValues) {
var val = cfg.value,
valFn = cfg.valueFn,
simple,
complex,
i,
l,
path,
subval,
subvals;
if (valFn) {
if (!valFn.call) {
valFn = this[valFn];
}
if (valFn) {
val = valFn.call(this);
}
}
if (!cfg.readOnly && initValues) {
// Simple Attributes
simple = initValues.simple;
if (simple && simple.hasOwnProperty(attr)) {
val = simple[attr];
}
// Complex Attributes (complex values applied, after simple, incase both are set)
complex = initValues.complex;
if (complex && complex.hasOwnProperty(attr)) {
subvals = complex[attr];
for (i = 0, l = subvals.length; i < l; ++i) {
path = subvals[i].path;
subval = subvals[i].value;
O.setValue(val, path, subval);
}
}
}
return val;
}
};
Y.mix(Y.Attribute, Y.Attribute.Complex, true, null, 1);
}, '3.1.1' ,{requires:['attribute-base']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("attribute-complex",function(B){var A=B.Object,C=".";B.Attribute.Complex=function(){};B.Attribute.Complex.prototype={_normAttrVals:function(G){var I={},H={},J,D,F,E;if(G){for(E in G){if(G.hasOwnProperty(E)){if(E.indexOf(C)!==-1){J=E.split(C);D=J.shift();F=H[D]=H[D]||[];F[F.length]={path:J,value:G[E]};}else{I[E]=G[E];}}}return{simple:I,complex:H};}else{return null;}},_getAttrInitVal:function(K,I,N){var E=I.value,M=I.valueFn,D,F,H,G,O,L,J;if(M){if(!M.call){M=this[M];}if(M){E=M.call(this);}}if(!I.readOnly&&N){D=N.simple;if(D&&D.hasOwnProperty(K)){E=D[K];}F=N.complex;if(F&&F.hasOwnProperty(K)){J=F[K];for(H=0,G=J.length;H<G;++H){O=J[H].path;L=J[H].value;A.setValue(E,O,L);}}}return E;}};B.mix(B.Attribute,B.Attribute.Complex,true,null,1);},"3.1.1",{requires:["attribute-base"]});

View file

@ -0,0 +1,130 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('attribute-complex', function(Y) {
/**
* Adds support for attribute providers to handle complex attributes in the constructor
*
* @module attribute
* @submodule attribute-complex
* @for Attribute
*/
var O = Y.Object,
DOT = ".";
Y.Attribute.Complex = function() {};
Y.Attribute.Complex.prototype = {
/**
* Utility method to split out simple attribute name/value pairs ("x")
* from complex attribute name/value pairs ("x.y.z"), so that complex
* attributes can be keyed by the top level attribute name.
*
* @method _normAttrVals
* @param {Object} valueHash An object with attribute name/value pairs
*
* @return {Object} An object literal with 2 properties - "simple" and "complex",
* containing simple and complex attribute values respectively keyed
* by the top level attribute name, or null, if valueHash is falsey.
*
* @private
*/
_normAttrVals : function(valueHash) {
var vals = {},
subvals = {},
path,
attr,
v, k;
if (valueHash) {
for (k in valueHash) {
if (valueHash.hasOwnProperty(k)) {
if (k.indexOf(DOT) !== -1) {
path = k.split(DOT);
attr = path.shift();
v = subvals[attr] = subvals[attr] || [];
v[v.length] = {
path : path,
value: valueHash[k]
};
} else {
vals[k] = valueHash[k];
}
}
}
return { simple:vals, complex:subvals };
} else {
return null;
}
},
/**
* Returns the initial value of the given attribute from
* either the default configuration provided, or the
* over-ridden value if it exists in the set of initValues
* provided and the attribute is not read-only.
*
* @param {String} attr The name of the attribute
* @param {Object} cfg The attribute configuration object
* @param {Object} initValues The object with simple and complex attribute name/value pairs returned from _normAttrVals
*
* @return {Any} The initial value of the attribute.
*
* @method _getAttrInitVal
* @private
*/
_getAttrInitVal : function(attr, cfg, initValues) {
var val = cfg.value,
valFn = cfg.valueFn,
simple,
complex,
i,
l,
path,
subval,
subvals;
if (valFn) {
if (!valFn.call) {
valFn = this[valFn];
}
if (valFn) {
val = valFn.call(this);
}
}
if (!cfg.readOnly && initValues) {
// Simple Attributes
simple = initValues.simple;
if (simple && simple.hasOwnProperty(attr)) {
val = simple[attr];
}
// Complex Attributes (complex values applied, after simple, incase both are set)
complex = initValues.complex;
if (complex && complex.hasOwnProperty(attr)) {
subvals = complex[attr];
for (i = 0, l = subvals.length; i < l; ++i) {
path = subvals[i].path;
subval = subvals[i].value;
O.setValue(val, path, subval);
}
}
}
return val;
}
};
Y.mix(Y.Attribute, Y.Attribute.Complex, true, null, 1);
}, '3.1.1' ,{requires:['attribute-base']});

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,590 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('base-base', function(Y) {
/**
* The base module provides the Base class, which objects requiring attribute and custom event support can extend.
* The module also provides two ways to reuse code - It augments Base with the Plugin.Host interface which provides
* plugin support and also provides the Base.build method which provides a way to build custom classes using extensions.
*
* @module base
*/
/**
* The base-base submodule provides the Base class without the Plugin support, provided by Plugin.Host,
* and without the extension support provided by Base.build.
*
* @module base
* @submodule base-base
*/
var O = Y.Object,
L = Y.Lang,
DOT = ".",
DESTROY = "destroy",
INIT = "init",
INITIALIZED = "initialized",
DESTROYED = "destroyed",
INITIALIZER = "initializer",
BUBBLETARGETS = "bubbleTargets",
_BUBBLETARGETS = "_bubbleTargets",
OBJECT_CONSTRUCTOR = Object.prototype.constructor,
DEEP = "deep",
SHALLOW = "shallow",
DESTRUCTOR = "destructor",
Attribute = Y.Attribute;
/**
* <p>
* A base class which objects requiring attributes and custom event support can
* extend. Base also handles the chaining of initializer and destructor methods across
* the hierarchy as part of object construction and destruction. Additionally, attributes configured
* through the static <a href="#property_Base.ATTRS">ATTRS</a> property for each class
* in the hierarchy will be initialized by Base.
* </p>
*
* <p>
* The static <a href="#property_Base.NAME">NAME</a> property of each class extending
* from Base will be used as the identifier for the class, and is used by Base to prefix
* all events fired by instances of that class.
* </p>
*
* @class Base
* @constructor
* @uses Attribute
* @uses Plugin.Host
*
* @param {Object} config Object with configuration property name/value pairs. The object can be
* used to provide default values for the objects published attributes.
*
* <p>
* The config object can also contain the following non-attribute properties, providing a convenient
* way to configure events listeners and plugins for the instance, as part of the constructor call:
* </p>
*
* <dl>
* <dt>on</dt>
* <dd>An event name to listener function map, to register event listeners for the "on" moment of the event. A constructor convenience property for the <a href="Base.html#method_on">on</a> method.</dd>
* <dt>after</dt>
* <dd>An event name to listener function map, to register event listeners for the "after" moment of the event. A constructor convenience property for the <a href="Base.html#method_after">after</a> method.</dd>
* <dt>bubbleTargets</dt>
* <dd>An object, or array of objects, to register as bubble targets for bubbled events fired by this instance. A constructor convenience property for the <a href="EventTarget.html#method_addTarget">addTarget</a> method.</dd>
* <dt>plugins</dt>
* <dd>A plugin, or array of plugins to be plugged into the instance (see PluginHost's plug method for signature details). A constructor convenience property for the <a href="Plugin.Host.html#method_plug">plug</a> method.</dd>
* </dl>
*/
function Base() {
Y.log('constructor called', 'life', 'base');
Attribute.call(this);
// If Plugin.Host has been augmented [ through base-pluginhost ], setup it's
// initial state, but don't initialize Plugins yet. That's done after initialization.
var PluginHost = Y.Plugin && Y.Plugin.Host;
if (this._initPlugins && PluginHost) {
PluginHost.call(this);
}
if (this._lazyAddAttrs !== false) { this._lazyAddAttrs = true; }
/**
* The string used to identify the class of this object.
*
* @deprecated Use this.constructor.NAME
* @property name
* @type String
*/
this.name = this.constructor.NAME;
this._eventPrefix = this.constructor.EVENT_PREFIX || this.constructor.NAME;
this.init.apply(this, arguments);
}
/**
* The list of properties which can be configured for
* each attribute (e.g. setter, getter, writeOnce, readOnly etc.)
*
* @property Base._ATTR_CFG
* @type Array
* @static
* @private
*/
Base._ATTR_CFG = Attribute._ATTR_CFG.concat("cloneDefaultValue");
/**
* <p>
* The string to be used to identify instances of
* this class, for example in prefixing events.
* </p>
* <p>
* Classes extending Base, should define their own
* static NAME property, which should be camelCase by
* convention (e.g. MyClass.NAME = "myClass";).
* </p>
* @property Base.NAME
* @type String
* @static
*/
Base.NAME = "base";
/**
* The default set of attributes which will be available for instances of this class, and
* their configuration. In addition to the configuration properties listed by
* Attribute's <a href="Attribute.html#method_addAttr">addAttr</a> method, the attribute
* can also be configured with a "cloneDefaultValue" property, which defines how the statically
* defined value field should be protected ("shallow", "deep" and false are supported values).
*
* By default if the value is an object literal or an array it will be "shallow" cloned, to
* protect the default value.
*
* @property Base.ATTRS
* @type Object
* @static
*/
Base.ATTRS = {
/**
* Flag indicating whether or not this object
* has been through the init lifecycle phase.
*
* @attribute initialized
* @readonly
* @default false
* @type boolean
*/
initialized: {
readOnly:true,
value:false
},
/**
* Flag indicating whether or not this object
* has been through the destroy lifecycle phase.
*
* @attribute destroyed
* @readonly
* @default false
* @type boolean
*/
destroyed: {
readOnly:true,
value:false
}
};
Base.prototype = {
/**
* Init lifecycle method, invoked during construction.
* Fires the init event prior to setting up attributes and
* invoking initializers for the class hierarchy.
*
* @method init
* @final
* @chainable
* @param {Object} config Object with configuration property name/value pairs
* @return {Base} A reference to this object
*/
init: function(config) {
Y.log('init called', 'life', 'base');
this._yuievt.config.prefix = this._eventPrefix;
/**
* <p>
* Lifecycle event for the init phase, fired prior to initialization.
* Invoking the preventDefault() method on the event object provided
* to subscribers will prevent initialization from occuring.
* </p>
* <p>
* Subscribers to the "after" momemt of this event, will be notified
* after initialization of the object is complete (and therefore
* cannot prevent initialization).
* </p>
*
* @event init
* @preventable _defInitFn
* @param {EventFacade} e Event object, with a cfg property which
* refers to the configuration object passed to the constructor.
*/
this.publish(INIT, {
queuable:false,
fireOnce:true,
defaultTargetOnly:true,
defaultFn:this._defInitFn
});
this._preInitEventCfg(config);
this.fire(INIT, {cfg: config});
return this;
},
/**
* Handles the special on, after and target properties which allow the user to
* easily configure on and after listeners as well as bubble targets during
* construction, prior to init.
*
* @method _preInitEventCfg
* @param {Object} config The user configuration object
*/
_preInitEventCfg : function(config) {
if (config) {
if (config.on) {
this.on(config.on);
}
if (config.after) {
this.after(config.after);
}
}
var i, l, target,
userTargets = (config && BUBBLETARGETS in config);
if (userTargets || _BUBBLETARGETS in this) {
target = userTargets ? (config && config.bubbleTargets) : this._bubbleTargets;
if (L.isArray(target)) {
for (i = 0, l = target.length; i < l; i++) {
this.addTarget(target[i]);
}
} else if (target) {
this.addTarget(target);
}
}
},
/**
* <p>
* Destroy lifecycle method. Fires the destroy
* event, prior to invoking destructors for the
* class hierarchy.
* </p>
* <p>
* Subscribers to the destroy
* event can invoke preventDefault on the event object, to prevent destruction
* from proceeding.
* </p>
* @method destroy
* @return {Base} A reference to this object
* @final
* @chainable
*/
destroy: function() {
Y.log('destroy called', 'life', 'base');
/**
* <p>
* Lifecycle event for the destroy phase,
* fired prior to destruction. Invoking the preventDefault
* method on the event object provided to subscribers will
* prevent destruction from proceeding.
* </p>
* <p>
* Subscribers to the "after" moment of this event, will be notified
* after destruction is complete (and as a result cannot prevent
* destruction).
* </p>
* @event destroy
* @preventable _defDestroyFn
* @param {EventFacade} e Event object
*/
this.publish(DESTROY, {
queuable:false,
fireOnce:true,
defaultTargetOnly:true,
defaultFn: this._defDestroyFn
});
this.fire(DESTROY);
this.detachAll();
return this;
},
/**
* Default init event handler
*
* @method _defInitFn
* @param {EventFacade} e Event object, with a cfg property which
* refers to the configuration object passed to the constructor.
* @protected
*/
_defInitFn : function(e) {
this._initHierarchy(e.cfg);
if (this._initPlugins) {
// Need to initPlugins manually, to handle constructor parsing, static Plug parsing
this._initPlugins(e.cfg);
}
this._set(INITIALIZED, true);
},
/**
* Default destroy event handler
*
* @method _defDestroyFn
* @param {EventFacade} e Event object
* @protected
*/
_defDestroyFn : function(e) {
this._destroyHierarchy();
if (this._destroyPlugins) {
this._destroyPlugins();
}
this._set(DESTROYED, true);
},
/**
* Returns the class hierarchy for this object, with Base being the last class in the array.
*
* @method _getClasses
* @protected
* @return {Function[]} An array of classes (constructor functions), making up the class hierarchy for this object.
* This value is cached the first time the method, or _getAttrCfgs, is invoked. Subsequent invocations return the
* cached value.
*/
_getClasses : function() {
if (!this._classes) {
this._initHierarchyData();
}
return this._classes;
},
/**
* Returns an aggregated set of attribute configurations, by traversing the class hierarchy.
*
* @method _getAttrCfgs
* @protected
* @return {Object} The hash of attribute configurations, aggregated across classes in the hierarchy
* This value is cached the first time the method, or _getClasses, is invoked. Subsequent invocations return
* the cached value.
*/
_getAttrCfgs : function() {
if (!this._attrs) {
this._initHierarchyData();
}
return this._attrs;
},
/**
* A helper method used when processing ATTRS across the class hierarchy during
* initialization. Returns a disposable object with the attributes defined for
* the provided class, extracted from the set of all attributes passed in .
*
* @method _filterAttrCfs
* @private
*
* @param {Function} clazz The class for which the desired attributes are required.
* @param {Object} allCfgs The set of all attribute configurations for this instance.
* Attributes will be removed from this set, if they belong to the filtered class, so
* that by the time all classes are processed, allCfgs will be empty.
*
* @return {Object} The set of attributes belonging to the class passed in, in the form
* of an object with attribute name/configuration pairs.
*/
_filterAttrCfgs : function(clazz, allCfgs) {
var cfgs = null, attr, attrs = clazz.ATTRS;
if (attrs) {
for (attr in attrs) {
if (attrs.hasOwnProperty(attr) && allCfgs[attr]) {
cfgs = cfgs || {};
cfgs[attr] = allCfgs[attr];
delete allCfgs[attr];
}
}
}
return cfgs;
},
/**
* A helper method used by _getClasses and _getAttrCfgs, which determines both
* the array of classes and aggregate set of attribute configurations
* across the class hierarchy for the instance.
*
* @method _initHierarchyData
* @private
*/
_initHierarchyData : function() {
var c = this.constructor,
classes = [],
attrs = [];
while (c) {
// Add to classes
classes[classes.length] = c;
// Add to attributes
if (c.ATTRS) {
attrs[attrs.length] = c.ATTRS;
}
c = c.superclass ? c.superclass.constructor : null;
}
this._classes = classes;
this._attrs = this._aggregateAttrs(attrs);
},
/**
* A helper method, used by _initHierarchyData to aggregate
* attribute configuration across the instances class hierarchy.
*
* The method will potect the attribute configuration value to protect the statically defined
* default value in ATTRS if required (if the value is an object literal, array or the
* attribute configuration has cloneDefaultValue set to shallow or deep).
*
* @method _aggregateAttrs
* @private
* @param {Array} allAttrs An array of ATTRS definitions across classes in the hierarchy
* (subclass first, Base last)
* @return {Object} The aggregate set of ATTRS definitions for the instance
*/
_aggregateAttrs : function(allAttrs) {
var attr,
attrs,
cfg,
val,
path,
i,
clone,
cfgProps = Base._ATTR_CFG,
aggAttrs = {};
if (allAttrs) {
for (i = allAttrs.length-1; i >= 0; --i) {
attrs = allAttrs[i];
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
// Protect config passed in
cfg = Y.mix({}, attrs[attr], true, cfgProps);
val = cfg.value;
clone = cfg.cloneDefaultValue;
if (val) {
if ( (clone === undefined && (OBJECT_CONSTRUCTOR === val.constructor || L.isArray(val))) || clone === DEEP || clone === true) {
Y.log('Cloning default value for attribute:' + attr, 'info', 'base');
cfg.value = Y.clone(val);
} else if (clone === SHALLOW) {
Y.log('Merging default value for attribute:' + attr, 'info', 'base');
cfg.value = Y.merge(val);
}
// else if (clone === false), don't clone the static default value.
// It's intended to be used by reference.
}
path = null;
if (attr.indexOf(DOT) !== -1) {
path = attr.split(DOT);
attr = path.shift();
}
if (path && aggAttrs[attr] && aggAttrs[attr].value) {
O.setValue(aggAttrs[attr].value, path, val);
} else if (!path){
if (!aggAttrs[attr]) {
aggAttrs[attr] = cfg;
} else {
Y.mix(aggAttrs[attr], cfg, true, cfgProps);
}
}
}
}
}
}
return aggAttrs;
},
/**
* Initializes the class hierarchy for the instance, which includes
* initializing attributes for each class defined in the class's
* static <a href="#property_Base.ATTRS">ATTRS</a> property and
* invoking the initializer method on the prototype of each class in the hierarchy.
*
* @method _initHierarchy
* @param {Object} userVals Object with configuration property name/value pairs
* @private
*/
_initHierarchy : function(userVals) {
var lazy = this._lazyAddAttrs,
constr,
constrProto,
ci,
ei,
el,
classes = this._getClasses(),
attrCfgs = this._getAttrCfgs();
for (ci = classes.length-1; ci >= 0; ci--) {
constr = classes[ci];
constrProto = constr.prototype;
if (constr._yuibuild && constr._yuibuild.exts) {
for (ei = 0, el = constr._yuibuild.exts.length; ei < el; ei++) {
constr._yuibuild.exts[ei].apply(this, arguments);
}
}
this.addAttrs(this._filterAttrCfgs(constr, attrCfgs), userVals, lazy);
// Using INITIALIZER in hasOwnProperty check, for performance reasons (helps IE6 avoid GC thresholds when
// referencing string literals). Not using it in apply, again, for performance "." is faster.
if (constrProto.hasOwnProperty(INITIALIZER)) {
constrProto.initializer.apply(this, arguments);
}
}
},
/**
* Destroys the class hierarchy for this instance by invoking
* the descructor method on the prototype of each class in the hierarchy.
*
* @method _destroyHierarchy
* @private
*/
_destroyHierarchy : function() {
var constr,
constrProto,
ci, cl,
classes = this._getClasses();
for (ci = 0, cl = classes.length; ci < cl; ci++) {
constr = classes[ci];
constrProto = constr.prototype;
if (constrProto.hasOwnProperty(DESTRUCTOR)) {
constrProto.destructor.apply(this, arguments);
}
}
},
/**
* Default toString implementation. Provides the constructor NAME
* and the instance ID.
*
* @method toString
* @return {String} String representation for this object
*/
toString: function() {
return this.constructor.NAME + "[" + Y.stamp(this) + "]";
}
};
// Straightup augment, no wrapper functions
Y.mix(Base, Attribute, false, null, 1);
// Fix constructor
Base.prototype.constructor = Base;
Y.Base = Base;
}, '3.1.1' ,{requires:['attribute-base']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("base-base",function(B){var I=B.Object,K=B.Lang,J=".",G="destroy",R="init",Q="initialized",H="destroyed",D="initializer",N="bubbleTargets",E="_bubbleTargets",C=Object.prototype.constructor,M="deep",S="shallow",P="destructor",A=B.Attribute;function F(){A.call(this);var L=B.Plugin&&B.Plugin.Host;if(this._initPlugins&&L){L.call(this);}if(this._lazyAddAttrs!==false){this._lazyAddAttrs=true;}this.name=this.constructor.NAME;this._eventPrefix=this.constructor.EVENT_PREFIX||this.constructor.NAME;this.init.apply(this,arguments);}F._ATTR_CFG=A._ATTR_CFG.concat("cloneDefaultValue");F.NAME="base";F.ATTRS={initialized:{readOnly:true,value:false},destroyed:{readOnly:true,value:false}};F.prototype={init:function(L){this._yuievt.config.prefix=this._eventPrefix;this.publish(R,{queuable:false,fireOnce:true,defaultTargetOnly:true,defaultFn:this._defInitFn});this._preInitEventCfg(L);this.fire(R,{cfg:L});return this;},_preInitEventCfg:function(O){if(O){if(O.on){this.on(O.on);}if(O.after){this.after(O.after);}}var T,L,V,U=(O&&N in O);if(U||E in this){V=U?(O&&O.bubbleTargets):this._bubbleTargets;if(K.isArray(V)){for(T=0,L=V.length;T<L;T++){this.addTarget(V[T]);}}else{if(V){this.addTarget(V);}}}},destroy:function(){this.publish(G,{queuable:false,fireOnce:true,defaultTargetOnly:true,defaultFn:this._defDestroyFn});this.fire(G);this.detachAll();return this;},_defInitFn:function(L){this._initHierarchy(L.cfg);if(this._initPlugins){this._initPlugins(L.cfg);}this._set(Q,true);},_defDestroyFn:function(L){this._destroyHierarchy();if(this._destroyPlugins){this._destroyPlugins();}this._set(H,true);},_getClasses:function(){if(!this._classes){this._initHierarchyData();}return this._classes;},_getAttrCfgs:function(){if(!this._attrs){this._initHierarchyData();}return this._attrs;},_filterAttrCfgs:function(V,O){var T=null,L,U=V.ATTRS;if(U){for(L in U){if(U.hasOwnProperty(L)&&O[L]){T=T||{};T[L]=O[L];delete O[L];}}}return T;},_initHierarchyData:function(){var T=this.constructor,O=[],L=[];while(T){O[O.length]=T;if(T.ATTRS){L[L.length]=T.ATTRS;}T=T.superclass?T.superclass.constructor:null;}this._classes=O;this._attrs=this._aggregateAttrs(L);},_aggregateAttrs:function(Y){var V,Z,U,L,a,O,X,T=F._ATTR_CFG,W={};if(Y){for(O=Y.length-1;O>=0;--O){Z=Y[O];for(V in Z){if(Z.hasOwnProperty(V)){U=B.mix({},Z[V],true,T);L=U.value;X=U.cloneDefaultValue;if(L){if((X===undefined&&(C===L.constructor||K.isArray(L)))||X===M||X===true){U.value=B.clone(L);}else{if(X===S){U.value=B.merge(L);}}}a=null;if(V.indexOf(J)!==-1){a=V.split(J);V=a.shift();}if(a&&W[V]&&W[V].value){I.setValue(W[V].value,a,L);}else{if(!a){if(!W[V]){W[V]=U;}else{B.mix(W[V],U,true,T);}}}}}}}return W;},_initHierarchy:function(W){var T=this._lazyAddAttrs,X,Y,Z,U,O,V=this._getClasses(),L=this._getAttrCfgs();for(Z=V.length-1;Z>=0;Z--){X=V[Z];Y=X.prototype;if(X._yuibuild&&X._yuibuild.exts){for(U=0,O=X._yuibuild.exts.length;U<O;U++){X._yuibuild.exts[U].apply(this,arguments);}}this.addAttrs(this._filterAttrCfgs(X,L),W,T);if(Y.hasOwnProperty(D)){Y.initializer.apply(this,arguments);}}},_destroyHierarchy:function(){var V,O,U,L,T=this._getClasses();for(U=0,L=T.length;U<L;U++){V=T[U];O=V.prototype;if(O.hasOwnProperty(P)){O.destructor.apply(this,arguments);}}},toString:function(){return this.constructor.NAME+"["+B.stamp(this)+"]";}};B.mix(F,A,false,null,1);F.prototype.constructor=F;B.Base=F;},"3.1.1",{requires:["attribute-base"]});

View file

@ -0,0 +1,585 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('base-base', function(Y) {
/**
* The base module provides the Base class, which objects requiring attribute and custom event support can extend.
* The module also provides two ways to reuse code - It augments Base with the Plugin.Host interface which provides
* plugin support and also provides the Base.build method which provides a way to build custom classes using extensions.
*
* @module base
*/
/**
* The base-base submodule provides the Base class without the Plugin support, provided by Plugin.Host,
* and without the extension support provided by Base.build.
*
* @module base
* @submodule base-base
*/
var O = Y.Object,
L = Y.Lang,
DOT = ".",
DESTROY = "destroy",
INIT = "init",
INITIALIZED = "initialized",
DESTROYED = "destroyed",
INITIALIZER = "initializer",
BUBBLETARGETS = "bubbleTargets",
_BUBBLETARGETS = "_bubbleTargets",
OBJECT_CONSTRUCTOR = Object.prototype.constructor,
DEEP = "deep",
SHALLOW = "shallow",
DESTRUCTOR = "destructor",
Attribute = Y.Attribute;
/**
* <p>
* A base class which objects requiring attributes and custom event support can
* extend. Base also handles the chaining of initializer and destructor methods across
* the hierarchy as part of object construction and destruction. Additionally, attributes configured
* through the static <a href="#property_Base.ATTRS">ATTRS</a> property for each class
* in the hierarchy will be initialized by Base.
* </p>
*
* <p>
* The static <a href="#property_Base.NAME">NAME</a> property of each class extending
* from Base will be used as the identifier for the class, and is used by Base to prefix
* all events fired by instances of that class.
* </p>
*
* @class Base
* @constructor
* @uses Attribute
* @uses Plugin.Host
*
* @param {Object} config Object with configuration property name/value pairs. The object can be
* used to provide default values for the objects published attributes.
*
* <p>
* The config object can also contain the following non-attribute properties, providing a convenient
* way to configure events listeners and plugins for the instance, as part of the constructor call:
* </p>
*
* <dl>
* <dt>on</dt>
* <dd>An event name to listener function map, to register event listeners for the "on" moment of the event. A constructor convenience property for the <a href="Base.html#method_on">on</a> method.</dd>
* <dt>after</dt>
* <dd>An event name to listener function map, to register event listeners for the "after" moment of the event. A constructor convenience property for the <a href="Base.html#method_after">after</a> method.</dd>
* <dt>bubbleTargets</dt>
* <dd>An object, or array of objects, to register as bubble targets for bubbled events fired by this instance. A constructor convenience property for the <a href="EventTarget.html#method_addTarget">addTarget</a> method.</dd>
* <dt>plugins</dt>
* <dd>A plugin, or array of plugins to be plugged into the instance (see PluginHost's plug method for signature details). A constructor convenience property for the <a href="Plugin.Host.html#method_plug">plug</a> method.</dd>
* </dl>
*/
function Base() {
Attribute.call(this);
// If Plugin.Host has been augmented [ through base-pluginhost ], setup it's
// initial state, but don't initialize Plugins yet. That's done after initialization.
var PluginHost = Y.Plugin && Y.Plugin.Host;
if (this._initPlugins && PluginHost) {
PluginHost.call(this);
}
if (this._lazyAddAttrs !== false) { this._lazyAddAttrs = true; }
/**
* The string used to identify the class of this object.
*
* @deprecated Use this.constructor.NAME
* @property name
* @type String
*/
this.name = this.constructor.NAME;
this._eventPrefix = this.constructor.EVENT_PREFIX || this.constructor.NAME;
this.init.apply(this, arguments);
}
/**
* The list of properties which can be configured for
* each attribute (e.g. setter, getter, writeOnce, readOnly etc.)
*
* @property Base._ATTR_CFG
* @type Array
* @static
* @private
*/
Base._ATTR_CFG = Attribute._ATTR_CFG.concat("cloneDefaultValue");
/**
* <p>
* The string to be used to identify instances of
* this class, for example in prefixing events.
* </p>
* <p>
* Classes extending Base, should define their own
* static NAME property, which should be camelCase by
* convention (e.g. MyClass.NAME = "myClass";).
* </p>
* @property Base.NAME
* @type String
* @static
*/
Base.NAME = "base";
/**
* The default set of attributes which will be available for instances of this class, and
* their configuration. In addition to the configuration properties listed by
* Attribute's <a href="Attribute.html#method_addAttr">addAttr</a> method, the attribute
* can also be configured with a "cloneDefaultValue" property, which defines how the statically
* defined value field should be protected ("shallow", "deep" and false are supported values).
*
* By default if the value is an object literal or an array it will be "shallow" cloned, to
* protect the default value.
*
* @property Base.ATTRS
* @type Object
* @static
*/
Base.ATTRS = {
/**
* Flag indicating whether or not this object
* has been through the init lifecycle phase.
*
* @attribute initialized
* @readonly
* @default false
* @type boolean
*/
initialized: {
readOnly:true,
value:false
},
/**
* Flag indicating whether or not this object
* has been through the destroy lifecycle phase.
*
* @attribute destroyed
* @readonly
* @default false
* @type boolean
*/
destroyed: {
readOnly:true,
value:false
}
};
Base.prototype = {
/**
* Init lifecycle method, invoked during construction.
* Fires the init event prior to setting up attributes and
* invoking initializers for the class hierarchy.
*
* @method init
* @final
* @chainable
* @param {Object} config Object with configuration property name/value pairs
* @return {Base} A reference to this object
*/
init: function(config) {
this._yuievt.config.prefix = this._eventPrefix;
/**
* <p>
* Lifecycle event for the init phase, fired prior to initialization.
* Invoking the preventDefault() method on the event object provided
* to subscribers will prevent initialization from occuring.
* </p>
* <p>
* Subscribers to the "after" momemt of this event, will be notified
* after initialization of the object is complete (and therefore
* cannot prevent initialization).
* </p>
*
* @event init
* @preventable _defInitFn
* @param {EventFacade} e Event object, with a cfg property which
* refers to the configuration object passed to the constructor.
*/
this.publish(INIT, {
queuable:false,
fireOnce:true,
defaultTargetOnly:true,
defaultFn:this._defInitFn
});
this._preInitEventCfg(config);
this.fire(INIT, {cfg: config});
return this;
},
/**
* Handles the special on, after and target properties which allow the user to
* easily configure on and after listeners as well as bubble targets during
* construction, prior to init.
*
* @method _preInitEventCfg
* @param {Object} config The user configuration object
*/
_preInitEventCfg : function(config) {
if (config) {
if (config.on) {
this.on(config.on);
}
if (config.after) {
this.after(config.after);
}
}
var i, l, target,
userTargets = (config && BUBBLETARGETS in config);
if (userTargets || _BUBBLETARGETS in this) {
target = userTargets ? (config && config.bubbleTargets) : this._bubbleTargets;
if (L.isArray(target)) {
for (i = 0, l = target.length; i < l; i++) {
this.addTarget(target[i]);
}
} else if (target) {
this.addTarget(target);
}
}
},
/**
* <p>
* Destroy lifecycle method. Fires the destroy
* event, prior to invoking destructors for the
* class hierarchy.
* </p>
* <p>
* Subscribers to the destroy
* event can invoke preventDefault on the event object, to prevent destruction
* from proceeding.
* </p>
* @method destroy
* @return {Base} A reference to this object
* @final
* @chainable
*/
destroy: function() {
/**
* <p>
* Lifecycle event for the destroy phase,
* fired prior to destruction. Invoking the preventDefault
* method on the event object provided to subscribers will
* prevent destruction from proceeding.
* </p>
* <p>
* Subscribers to the "after" moment of this event, will be notified
* after destruction is complete (and as a result cannot prevent
* destruction).
* </p>
* @event destroy
* @preventable _defDestroyFn
* @param {EventFacade} e Event object
*/
this.publish(DESTROY, {
queuable:false,
fireOnce:true,
defaultTargetOnly:true,
defaultFn: this._defDestroyFn
});
this.fire(DESTROY);
this.detachAll();
return this;
},
/**
* Default init event handler
*
* @method _defInitFn
* @param {EventFacade} e Event object, with a cfg property which
* refers to the configuration object passed to the constructor.
* @protected
*/
_defInitFn : function(e) {
this._initHierarchy(e.cfg);
if (this._initPlugins) {
// Need to initPlugins manually, to handle constructor parsing, static Plug parsing
this._initPlugins(e.cfg);
}
this._set(INITIALIZED, true);
},
/**
* Default destroy event handler
*
* @method _defDestroyFn
* @param {EventFacade} e Event object
* @protected
*/
_defDestroyFn : function(e) {
this._destroyHierarchy();
if (this._destroyPlugins) {
this._destroyPlugins();
}
this._set(DESTROYED, true);
},
/**
* Returns the class hierarchy for this object, with Base being the last class in the array.
*
* @method _getClasses
* @protected
* @return {Function[]} An array of classes (constructor functions), making up the class hierarchy for this object.
* This value is cached the first time the method, or _getAttrCfgs, is invoked. Subsequent invocations return the
* cached value.
*/
_getClasses : function() {
if (!this._classes) {
this._initHierarchyData();
}
return this._classes;
},
/**
* Returns an aggregated set of attribute configurations, by traversing the class hierarchy.
*
* @method _getAttrCfgs
* @protected
* @return {Object} The hash of attribute configurations, aggregated across classes in the hierarchy
* This value is cached the first time the method, or _getClasses, is invoked. Subsequent invocations return
* the cached value.
*/
_getAttrCfgs : function() {
if (!this._attrs) {
this._initHierarchyData();
}
return this._attrs;
},
/**
* A helper method used when processing ATTRS across the class hierarchy during
* initialization. Returns a disposable object with the attributes defined for
* the provided class, extracted from the set of all attributes passed in .
*
* @method _filterAttrCfs
* @private
*
* @param {Function} clazz The class for which the desired attributes are required.
* @param {Object} allCfgs The set of all attribute configurations for this instance.
* Attributes will be removed from this set, if they belong to the filtered class, so
* that by the time all classes are processed, allCfgs will be empty.
*
* @return {Object} The set of attributes belonging to the class passed in, in the form
* of an object with attribute name/configuration pairs.
*/
_filterAttrCfgs : function(clazz, allCfgs) {
var cfgs = null, attr, attrs = clazz.ATTRS;
if (attrs) {
for (attr in attrs) {
if (attrs.hasOwnProperty(attr) && allCfgs[attr]) {
cfgs = cfgs || {};
cfgs[attr] = allCfgs[attr];
delete allCfgs[attr];
}
}
}
return cfgs;
},
/**
* A helper method used by _getClasses and _getAttrCfgs, which determines both
* the array of classes and aggregate set of attribute configurations
* across the class hierarchy for the instance.
*
* @method _initHierarchyData
* @private
*/
_initHierarchyData : function() {
var c = this.constructor,
classes = [],
attrs = [];
while (c) {
// Add to classes
classes[classes.length] = c;
// Add to attributes
if (c.ATTRS) {
attrs[attrs.length] = c.ATTRS;
}
c = c.superclass ? c.superclass.constructor : null;
}
this._classes = classes;
this._attrs = this._aggregateAttrs(attrs);
},
/**
* A helper method, used by _initHierarchyData to aggregate
* attribute configuration across the instances class hierarchy.
*
* The method will potect the attribute configuration value to protect the statically defined
* default value in ATTRS if required (if the value is an object literal, array or the
* attribute configuration has cloneDefaultValue set to shallow or deep).
*
* @method _aggregateAttrs
* @private
* @param {Array} allAttrs An array of ATTRS definitions across classes in the hierarchy
* (subclass first, Base last)
* @return {Object} The aggregate set of ATTRS definitions for the instance
*/
_aggregateAttrs : function(allAttrs) {
var attr,
attrs,
cfg,
val,
path,
i,
clone,
cfgProps = Base._ATTR_CFG,
aggAttrs = {};
if (allAttrs) {
for (i = allAttrs.length-1; i >= 0; --i) {
attrs = allAttrs[i];
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
// Protect config passed in
cfg = Y.mix({}, attrs[attr], true, cfgProps);
val = cfg.value;
clone = cfg.cloneDefaultValue;
if (val) {
if ( (clone === undefined && (OBJECT_CONSTRUCTOR === val.constructor || L.isArray(val))) || clone === DEEP || clone === true) {
cfg.value = Y.clone(val);
} else if (clone === SHALLOW) {
cfg.value = Y.merge(val);
}
// else if (clone === false), don't clone the static default value.
// It's intended to be used by reference.
}
path = null;
if (attr.indexOf(DOT) !== -1) {
path = attr.split(DOT);
attr = path.shift();
}
if (path && aggAttrs[attr] && aggAttrs[attr].value) {
O.setValue(aggAttrs[attr].value, path, val);
} else if (!path){
if (!aggAttrs[attr]) {
aggAttrs[attr] = cfg;
} else {
Y.mix(aggAttrs[attr], cfg, true, cfgProps);
}
}
}
}
}
}
return aggAttrs;
},
/**
* Initializes the class hierarchy for the instance, which includes
* initializing attributes for each class defined in the class's
* static <a href="#property_Base.ATTRS">ATTRS</a> property and
* invoking the initializer method on the prototype of each class in the hierarchy.
*
* @method _initHierarchy
* @param {Object} userVals Object with configuration property name/value pairs
* @private
*/
_initHierarchy : function(userVals) {
var lazy = this._lazyAddAttrs,
constr,
constrProto,
ci,
ei,
el,
classes = this._getClasses(),
attrCfgs = this._getAttrCfgs();
for (ci = classes.length-1; ci >= 0; ci--) {
constr = classes[ci];
constrProto = constr.prototype;
if (constr._yuibuild && constr._yuibuild.exts) {
for (ei = 0, el = constr._yuibuild.exts.length; ei < el; ei++) {
constr._yuibuild.exts[ei].apply(this, arguments);
}
}
this.addAttrs(this._filterAttrCfgs(constr, attrCfgs), userVals, lazy);
// Using INITIALIZER in hasOwnProperty check, for performance reasons (helps IE6 avoid GC thresholds when
// referencing string literals). Not using it in apply, again, for performance "." is faster.
if (constrProto.hasOwnProperty(INITIALIZER)) {
constrProto.initializer.apply(this, arguments);
}
}
},
/**
* Destroys the class hierarchy for this instance by invoking
* the descructor method on the prototype of each class in the hierarchy.
*
* @method _destroyHierarchy
* @private
*/
_destroyHierarchy : function() {
var constr,
constrProto,
ci, cl,
classes = this._getClasses();
for (ci = 0, cl = classes.length; ci < cl; ci++) {
constr = classes[ci];
constrProto = constr.prototype;
if (constrProto.hasOwnProperty(DESTRUCTOR)) {
constrProto.destructor.apply(this, arguments);
}
}
},
/**
* Default toString implementation. Provides the constructor NAME
* and the instance ID.
*
* @method toString
* @return {String} String representation for this object
*/
toString: function() {
return this.constructor.NAME + "[" + Y.stamp(this) + "]";
}
};
// Straightup augment, no wrapper functions
Y.mix(Base, Attribute, false, null, 1);
// Fix constructor
Base.prototype.constructor = Base;
Y.Base = Base;
}, '3.1.1' ,{requires:['attribute-base']});

View file

@ -0,0 +1,291 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('base-build', function(Y) {
/**
* The base-build submodule provides Base.build functionality, which
* can be used to create custom classes, by aggregating extensions onto
* a main class.
*
* @module base
* @submodule base-build
* @for Base
*/
var Base = Y.Base,
L = Y.Lang,
build;
Base._build = function(name, main, extensions, px, sx, cfg) {
var build = Base._build,
builtClass = build._ctor(main, cfg),
buildCfg = build._cfg(main, cfg),
_mixCust = build._mixCust,
aggregates = buildCfg.aggregates,
custom = buildCfg.custom,
dynamic = builtClass._yuibuild.dynamic,
i, l, val, extClass;
if (dynamic && aggregates) {
for (i = 0, l = aggregates.length; i < l; ++i) {
val = aggregates[i];
if (main.hasOwnProperty(val)) {
builtClass[val] = L.isArray(main[val]) ? [] : {};
}
}
}
// Augment/Aggregate
for (i = 0, l = extensions.length; i < l; i++) {
extClass = extensions[i];
// Prototype, old non-displacing augment
Y.mix(builtClass, extClass, true, null, 1);
// Custom Statics
_mixCust(builtClass, extClass, aggregates, custom);
builtClass._yuibuild.exts.push(extClass);
}
if (px) {
Y.mix(builtClass.prototype, px, true);
}
if (sx) {
Y.mix(builtClass, build._clean(sx, aggregates, custom), true);
_mixCust(builtClass, sx, aggregates, custom);
}
builtClass.prototype.hasImpl = build._impl;
if (dynamic) {
builtClass.NAME = name;
builtClass.prototype.constructor = builtClass;
}
return builtClass;
};
build = Base._build;
Y.mix(build, {
_mixCust: function(r, s, aggregates, custom) {
if (aggregates) {
Y.aggregate(r, s, true, aggregates);
}
if (custom) {
for (var j in custom) {
if (custom.hasOwnProperty(j)) {
custom[j](j, r, s);
}
}
}
},
_tmpl: function(main) {
function BuiltClass() {
BuiltClass.superclass.constructor.apply(this, arguments);
}
Y.extend(BuiltClass, main);
return BuiltClass;
},
_impl : function(extClass) {
var classes = this._getClasses(), i, l, cls, exts, ll, j;
for (i = 0, l = classes.length; i < l; i++) {
cls = classes[i];
if (cls._yuibuild) {
exts = cls._yuibuild.exts;
ll = exts.length;
for (j = 0; j < ll; j++) {
if (exts[j] === extClass) {
return true;
}
}
}
}
return false;
},
_ctor : function(main, cfg) {
var dynamic = (cfg && false === cfg.dynamic) ? false : true,
builtClass = (dynamic) ? build._tmpl(main) : main;
builtClass._yuibuild = {
id: null,
exts : [],
dynamic: dynamic
};
return builtClass;
},
_cfg : function(main, cfg) {
var aggr = [],
cust = {},
buildCfg,
cfgAggr = (cfg && cfg.aggregates),
cfgCustBuild = (cfg && cfg.custom),
c = main;
while (c && c.prototype) {
buildCfg = c._buildCfg;
if (buildCfg) {
if (buildCfg.aggregates) {
aggr = aggr.concat(buildCfg.aggregates);
}
if (buildCfg.custom) {
Y.mix(cust, buildCfg.custom, true);
}
}
c = c.superclass ? c.superclass.constructor : null;
}
if (cfgAggr) {
aggr = aggr.concat(cfgAggr);
}
if (cfgCustBuild) {
Y.mix(cust, cfg.cfgBuild, true);
}
return {
aggregates: aggr,
custom: cust
};
},
_clean : function(sx, aggregates, custom) {
var prop, i, l, sxclone = Y.merge(sx);
for (prop in custom) {
if (sxclone.hasOwnProperty(prop)) {
delete sxclone[prop];
}
}
for (i = 0, l = aggregates.length; i < l; i++) {
prop = aggregates[i];
if (sxclone.hasOwnProperty(prop)) {
delete sxclone[prop];
}
}
return sxclone;
}
});
/**
* <p>
* Builds a custom constructor function (class) from the
* main function, and array of extension functions (classes)
* provided. The NAME field for the constructor function is
* defined by the first argument passed in.
* </p>
* <p>
* The cfg object supports the following properties
* </p>
* <dl>
* <dt>dynamic &#60;boolean&#62;</dt>
* <dd>
* <p>If true (default), a completely new class
* is created which extends the main class, and acts as the
* host on which the extension classes are augmented.</p>
* <p>If false, the extensions classes are augmented directly to
* the main class, modifying the main class' prototype.</p>
* </dd>
* <dt>aggregates &#60;String[]&#62;</dt>
* <dd>An array of static property names, which will get aggregated
* on to the built class, in addition to the default properties build
* will always aggregate as defined by the main class' static _buildCfg
* property.
* </dd>
* </dl>
*
* @method Base.build
* @static
* @param {Function} name The name of the new class. Used to defined the NAME property for the new class.
* @param {Function} main The main class on which to base the built class
* @param {Function[]} extensions The set of extension classes which will be
* augmented/aggregated to the built class.
* @param {Object} cfg Optional. Build configuration for the class (see description).
* @return {Function} A custom class, created from the provided main and extension classes
*/
Base.build = function(name, main, extensions, cfg) {
return build(name, main, extensions, null, null, cfg);
};
/**
* <p>Creates a new class (constructor function) which extends the base class passed in as the second argument,
* and mixes in the array of extensions provided.</p>
* <p>Prototype properties or methods can be added to the new class, using the px argument (similar to Y.extend).</p>
* <p>Static properties or methods can be added to the new class, using the sx argument (similar to Y.extend).</p>
* <p>
*
* </p>
* @method Base.create
* @static
* @param {Function} name The name of the newly created class. Used to defined the NAME property for the new class.
* @param {Function} main The base class which the new class should extend. This class needs to be Base or a class derived from base (e.g. Widget).
* @param {Function[]} extensions The list of extensions which will be mixed into the built class.
* @return {Function} The newly created class.
*/
Base.create = function(name, base, extensions, px, sx) {
return build(name, base, extensions, px, sx);
};
/**
* <p>Mixes in a list of extensions to an existing class.</p>
* @method Base.mix
* @static
* @param {Function} main The existing class into which the extensions should be mixed. The class needs to be Base or class derived from base (e.g. Widget)
* @param {Function[]} extensions The set of extension classes which will mixed into the existing main class.
* @return {Function} The modified main class, with extensions mixed in.
*/
Base.mix = function(main, extensions) {
return build(null, main, extensions, null, null, {dynamic:false});
};
/**
* The build configuration for the Base class.
*
* Defines the static fields which need to be aggregated
* when the Base class is used as the main class passed to
* the <a href="#method_Base.build">Base.build</a> method.
*
* @property Base._buildCfg
* @type Object
* @static
* @final
* @private
*/
Base._buildCfg = {
custom : {
ATTRS : function(prop, r, s) {
r[prop] = r[prop] || {};
if (s[prop]) {
Y.aggregate(r[prop], s[prop], true);
}
}
},
aggregates : ["_PLUG", "_UNPLUG"]
};
}, '3.1.1' ,{requires:['base-base']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("base-build",function(D){var B=D.Base,A=D.Lang,C;B._build=function(F,L,P,T,S,O){var U=B._build,G=U._ctor(L,O),J=U._cfg(L,O),R=U._mixCust,N=J.aggregates,E=J.custom,I=G._yuibuild.dynamic,M,K,H,Q;if(I&&N){for(M=0,K=N.length;M<K;++M){H=N[M];if(L.hasOwnProperty(H)){G[H]=A.isArray(L[H])?[]:{};}}}for(M=0,K=P.length;M<K;M++){Q=P[M];D.mix(G,Q,true,null,1);R(G,Q,N,E);G._yuibuild.exts.push(Q);}if(T){D.mix(G.prototype,T,true);}if(S){D.mix(G,U._clean(S,N,E),true);R(G,S,N,E);}G.prototype.hasImpl=U._impl;if(I){G.NAME=F;G.prototype.constructor=G;}return G;};C=B._build;D.mix(C,{_mixCust:function(G,F,I,H){if(I){D.aggregate(G,F,true,I);}if(H){for(var E in H){if(H.hasOwnProperty(E)){H[E](E,G,F);}}}},_tmpl:function(E){function F(){F.superclass.constructor.apply(this,arguments);}D.extend(F,E);return F;},_impl:function(H){var K=this._getClasses(),J,F,E,I,L,G;for(J=0,F=K.length;J<F;J++){E=K[J];if(E._yuibuild){I=E._yuibuild.exts;L=I.length;for(G=0;G<L;G++){if(I[G]===H){return true;}}}}return false;},_ctor:function(E,F){var G=(F&&false===F.dynamic)?false:true,H=(G)?C._tmpl(E):E;H._yuibuild={id:null,exts:[],dynamic:G};return H;},_cfg:function(E,F){var G=[],J={},I,H=(F&&F.aggregates),L=(F&&F.custom),K=E;while(K&&K.prototype){I=K._buildCfg;if(I){if(I.aggregates){G=G.concat(I.aggregates);}if(I.custom){D.mix(J,I.custom,true);}}K=K.superclass?K.superclass.constructor:null;}if(H){G=G.concat(H);}if(L){D.mix(J,F.cfgBuild,true);}return{aggregates:G,custom:J};},_clean:function(K,J,G){var I,F,E,H=D.merge(K);for(I in G){if(H.hasOwnProperty(I)){delete H[I];}}for(F=0,E=J.length;F<E;F++){I=J[F];if(H.hasOwnProperty(I)){delete H[I];}}return H;}});B.build=function(G,E,H,F){return C(G,E,H,null,null,F);};B.create=function(E,H,G,F,I){return C(E,H,G,F,I);};B.mix=function(E,F){return C(null,E,F,null,null,{dynamic:false});};B._buildCfg={custom:{ATTRS:function(G,F,E){F[G]=F[G]||{};if(E[G]){D.aggregate(F[G],E[G],true);}}},aggregates:["_PLUG","_UNPLUG"]};},"3.1.1",{requires:["base-base"]});

View file

@ -0,0 +1,291 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('base-build', function(Y) {
/**
* The base-build submodule provides Base.build functionality, which
* can be used to create custom classes, by aggregating extensions onto
* a main class.
*
* @module base
* @submodule base-build
* @for Base
*/
var Base = Y.Base,
L = Y.Lang,
build;
Base._build = function(name, main, extensions, px, sx, cfg) {
var build = Base._build,
builtClass = build._ctor(main, cfg),
buildCfg = build._cfg(main, cfg),
_mixCust = build._mixCust,
aggregates = buildCfg.aggregates,
custom = buildCfg.custom,
dynamic = builtClass._yuibuild.dynamic,
i, l, val, extClass;
if (dynamic && aggregates) {
for (i = 0, l = aggregates.length; i < l; ++i) {
val = aggregates[i];
if (main.hasOwnProperty(val)) {
builtClass[val] = L.isArray(main[val]) ? [] : {};
}
}
}
// Augment/Aggregate
for (i = 0, l = extensions.length; i < l; i++) {
extClass = extensions[i];
// Prototype, old non-displacing augment
Y.mix(builtClass, extClass, true, null, 1);
// Custom Statics
_mixCust(builtClass, extClass, aggregates, custom);
builtClass._yuibuild.exts.push(extClass);
}
if (px) {
Y.mix(builtClass.prototype, px, true);
}
if (sx) {
Y.mix(builtClass, build._clean(sx, aggregates, custom), true);
_mixCust(builtClass, sx, aggregates, custom);
}
builtClass.prototype.hasImpl = build._impl;
if (dynamic) {
builtClass.NAME = name;
builtClass.prototype.constructor = builtClass;
}
return builtClass;
};
build = Base._build;
Y.mix(build, {
_mixCust: function(r, s, aggregates, custom) {
if (aggregates) {
Y.aggregate(r, s, true, aggregates);
}
if (custom) {
for (var j in custom) {
if (custom.hasOwnProperty(j)) {
custom[j](j, r, s);
}
}
}
},
_tmpl: function(main) {
function BuiltClass() {
BuiltClass.superclass.constructor.apply(this, arguments);
}
Y.extend(BuiltClass, main);
return BuiltClass;
},
_impl : function(extClass) {
var classes = this._getClasses(), i, l, cls, exts, ll, j;
for (i = 0, l = classes.length; i < l; i++) {
cls = classes[i];
if (cls._yuibuild) {
exts = cls._yuibuild.exts;
ll = exts.length;
for (j = 0; j < ll; j++) {
if (exts[j] === extClass) {
return true;
}
}
}
}
return false;
},
_ctor : function(main, cfg) {
var dynamic = (cfg && false === cfg.dynamic) ? false : true,
builtClass = (dynamic) ? build._tmpl(main) : main;
builtClass._yuibuild = {
id: null,
exts : [],
dynamic: dynamic
};
return builtClass;
},
_cfg : function(main, cfg) {
var aggr = [],
cust = {},
buildCfg,
cfgAggr = (cfg && cfg.aggregates),
cfgCustBuild = (cfg && cfg.custom),
c = main;
while (c && c.prototype) {
buildCfg = c._buildCfg;
if (buildCfg) {
if (buildCfg.aggregates) {
aggr = aggr.concat(buildCfg.aggregates);
}
if (buildCfg.custom) {
Y.mix(cust, buildCfg.custom, true);
}
}
c = c.superclass ? c.superclass.constructor : null;
}
if (cfgAggr) {
aggr = aggr.concat(cfgAggr);
}
if (cfgCustBuild) {
Y.mix(cust, cfg.cfgBuild, true);
}
return {
aggregates: aggr,
custom: cust
};
},
_clean : function(sx, aggregates, custom) {
var prop, i, l, sxclone = Y.merge(sx);
for (prop in custom) {
if (sxclone.hasOwnProperty(prop)) {
delete sxclone[prop];
}
}
for (i = 0, l = aggregates.length; i < l; i++) {
prop = aggregates[i];
if (sxclone.hasOwnProperty(prop)) {
delete sxclone[prop];
}
}
return sxclone;
}
});
/**
* <p>
* Builds a custom constructor function (class) from the
* main function, and array of extension functions (classes)
* provided. The NAME field for the constructor function is
* defined by the first argument passed in.
* </p>
* <p>
* The cfg object supports the following properties
* </p>
* <dl>
* <dt>dynamic &#60;boolean&#62;</dt>
* <dd>
* <p>If true (default), a completely new class
* is created which extends the main class, and acts as the
* host on which the extension classes are augmented.</p>
* <p>If false, the extensions classes are augmented directly to
* the main class, modifying the main class' prototype.</p>
* </dd>
* <dt>aggregates &#60;String[]&#62;</dt>
* <dd>An array of static property names, which will get aggregated
* on to the built class, in addition to the default properties build
* will always aggregate as defined by the main class' static _buildCfg
* property.
* </dd>
* </dl>
*
* @method Base.build
* @static
* @param {Function} name The name of the new class. Used to defined the NAME property for the new class.
* @param {Function} main The main class on which to base the built class
* @param {Function[]} extensions The set of extension classes which will be
* augmented/aggregated to the built class.
* @param {Object} cfg Optional. Build configuration for the class (see description).
* @return {Function} A custom class, created from the provided main and extension classes
*/
Base.build = function(name, main, extensions, cfg) {
return build(name, main, extensions, null, null, cfg);
};
/**
* <p>Creates a new class (constructor function) which extends the base class passed in as the second argument,
* and mixes in the array of extensions provided.</p>
* <p>Prototype properties or methods can be added to the new class, using the px argument (similar to Y.extend).</p>
* <p>Static properties or methods can be added to the new class, using the sx argument (similar to Y.extend).</p>
* <p>
*
* </p>
* @method Base.create
* @static
* @param {Function} name The name of the newly created class. Used to defined the NAME property for the new class.
* @param {Function} main The base class which the new class should extend. This class needs to be Base or a class derived from base (e.g. Widget).
* @param {Function[]} extensions The list of extensions which will be mixed into the built class.
* @return {Function} The newly created class.
*/
Base.create = function(name, base, extensions, px, sx) {
return build(name, base, extensions, px, sx);
};
/**
* <p>Mixes in a list of extensions to an existing class.</p>
* @method Base.mix
* @static
* @param {Function} main The existing class into which the extensions should be mixed. The class needs to be Base or class derived from base (e.g. Widget)
* @param {Function[]} extensions The set of extension classes which will mixed into the existing main class.
* @return {Function} The modified main class, with extensions mixed in.
*/
Base.mix = function(main, extensions) {
return build(null, main, extensions, null, null, {dynamic:false});
};
/**
* The build configuration for the Base class.
*
* Defines the static fields which need to be aggregated
* when the Base class is used as the main class passed to
* the <a href="#method_Base.build">Base.build</a> method.
*
* @property Base._buildCfg
* @type Object
* @static
* @final
* @private
*/
Base._buildCfg = {
custom : {
ATTRS : function(prop, r, s) {
r[prop] = r[prop] || {};
if (s[prop]) {
Y.aggregate(r[prop], s[prop], true);
}
}
},
aggregates : ["_PLUG", "_UNPLUG"]
};
}, '3.1.1' ,{requires:['base-base']});

View file

@ -0,0 +1,914 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('base-base', function(Y) {
/**
* The base module provides the Base class, which objects requiring attribute and custom event support can extend.
* The module also provides two ways to reuse code - It augments Base with the Plugin.Host interface which provides
* plugin support and also provides the Base.build method which provides a way to build custom classes using extensions.
*
* @module base
*/
/**
* The base-base submodule provides the Base class without the Plugin support, provided by Plugin.Host,
* and without the extension support provided by Base.build.
*
* @module base
* @submodule base-base
*/
var O = Y.Object,
L = Y.Lang,
DOT = ".",
DESTROY = "destroy",
INIT = "init",
INITIALIZED = "initialized",
DESTROYED = "destroyed",
INITIALIZER = "initializer",
BUBBLETARGETS = "bubbleTargets",
_BUBBLETARGETS = "_bubbleTargets",
OBJECT_CONSTRUCTOR = Object.prototype.constructor,
DEEP = "deep",
SHALLOW = "shallow",
DESTRUCTOR = "destructor",
Attribute = Y.Attribute;
/**
* <p>
* A base class which objects requiring attributes and custom event support can
* extend. Base also handles the chaining of initializer and destructor methods across
* the hierarchy as part of object construction and destruction. Additionally, attributes configured
* through the static <a href="#property_Base.ATTRS">ATTRS</a> property for each class
* in the hierarchy will be initialized by Base.
* </p>
*
* <p>
* The static <a href="#property_Base.NAME">NAME</a> property of each class extending
* from Base will be used as the identifier for the class, and is used by Base to prefix
* all events fired by instances of that class.
* </p>
*
* @class Base
* @constructor
* @uses Attribute
* @uses Plugin.Host
*
* @param {Object} config Object with configuration property name/value pairs. The object can be
* used to provide default values for the objects published attributes.
*
* <p>
* The config object can also contain the following non-attribute properties, providing a convenient
* way to configure events listeners and plugins for the instance, as part of the constructor call:
* </p>
*
* <dl>
* <dt>on</dt>
* <dd>An event name to listener function map, to register event listeners for the "on" moment of the event. A constructor convenience property for the <a href="Base.html#method_on">on</a> method.</dd>
* <dt>after</dt>
* <dd>An event name to listener function map, to register event listeners for the "after" moment of the event. A constructor convenience property for the <a href="Base.html#method_after">after</a> method.</dd>
* <dt>bubbleTargets</dt>
* <dd>An object, or array of objects, to register as bubble targets for bubbled events fired by this instance. A constructor convenience property for the <a href="EventTarget.html#method_addTarget">addTarget</a> method.</dd>
* <dt>plugins</dt>
* <dd>A plugin, or array of plugins to be plugged into the instance (see PluginHost's plug method for signature details). A constructor convenience property for the <a href="Plugin.Host.html#method_plug">plug</a> method.</dd>
* </dl>
*/
function Base() {
Y.log('constructor called', 'life', 'base');
Attribute.call(this);
// If Plugin.Host has been augmented [ through base-pluginhost ], setup it's
// initial state, but don't initialize Plugins yet. That's done after initialization.
var PluginHost = Y.Plugin && Y.Plugin.Host;
if (this._initPlugins && PluginHost) {
PluginHost.call(this);
}
if (this._lazyAddAttrs !== false) { this._lazyAddAttrs = true; }
/**
* The string used to identify the class of this object.
*
* @deprecated Use this.constructor.NAME
* @property name
* @type String
*/
this.name = this.constructor.NAME;
this._eventPrefix = this.constructor.EVENT_PREFIX || this.constructor.NAME;
this.init.apply(this, arguments);
}
/**
* The list of properties which can be configured for
* each attribute (e.g. setter, getter, writeOnce, readOnly etc.)
*
* @property Base._ATTR_CFG
* @type Array
* @static
* @private
*/
Base._ATTR_CFG = Attribute._ATTR_CFG.concat("cloneDefaultValue");
/**
* <p>
* The string to be used to identify instances of
* this class, for example in prefixing events.
* </p>
* <p>
* Classes extending Base, should define their own
* static NAME property, which should be camelCase by
* convention (e.g. MyClass.NAME = "myClass";).
* </p>
* @property Base.NAME
* @type String
* @static
*/
Base.NAME = "base";
/**
* The default set of attributes which will be available for instances of this class, and
* their configuration. In addition to the configuration properties listed by
* Attribute's <a href="Attribute.html#method_addAttr">addAttr</a> method, the attribute
* can also be configured with a "cloneDefaultValue" property, which defines how the statically
* defined value field should be protected ("shallow", "deep" and false are supported values).
*
* By default if the value is an object literal or an array it will be "shallow" cloned, to
* protect the default value.
*
* @property Base.ATTRS
* @type Object
* @static
*/
Base.ATTRS = {
/**
* Flag indicating whether or not this object
* has been through the init lifecycle phase.
*
* @attribute initialized
* @readonly
* @default false
* @type boolean
*/
initialized: {
readOnly:true,
value:false
},
/**
* Flag indicating whether or not this object
* has been through the destroy lifecycle phase.
*
* @attribute destroyed
* @readonly
* @default false
* @type boolean
*/
destroyed: {
readOnly:true,
value:false
}
};
Base.prototype = {
/**
* Init lifecycle method, invoked during construction.
* Fires the init event prior to setting up attributes and
* invoking initializers for the class hierarchy.
*
* @method init
* @final
* @chainable
* @param {Object} config Object with configuration property name/value pairs
* @return {Base} A reference to this object
*/
init: function(config) {
Y.log('init called', 'life', 'base');
this._yuievt.config.prefix = this._eventPrefix;
/**
* <p>
* Lifecycle event for the init phase, fired prior to initialization.
* Invoking the preventDefault() method on the event object provided
* to subscribers will prevent initialization from occuring.
* </p>
* <p>
* Subscribers to the "after" momemt of this event, will be notified
* after initialization of the object is complete (and therefore
* cannot prevent initialization).
* </p>
*
* @event init
* @preventable _defInitFn
* @param {EventFacade} e Event object, with a cfg property which
* refers to the configuration object passed to the constructor.
*/
this.publish(INIT, {
queuable:false,
fireOnce:true,
defaultTargetOnly:true,
defaultFn:this._defInitFn
});
this._preInitEventCfg(config);
this.fire(INIT, {cfg: config});
return this;
},
/**
* Handles the special on, after and target properties which allow the user to
* easily configure on and after listeners as well as bubble targets during
* construction, prior to init.
*
* @method _preInitEventCfg
* @param {Object} config The user configuration object
*/
_preInitEventCfg : function(config) {
if (config) {
if (config.on) {
this.on(config.on);
}
if (config.after) {
this.after(config.after);
}
}
var i, l, target,
userTargets = (config && BUBBLETARGETS in config);
if (userTargets || _BUBBLETARGETS in this) {
target = userTargets ? (config && config.bubbleTargets) : this._bubbleTargets;
if (L.isArray(target)) {
for (i = 0, l = target.length; i < l; i++) {
this.addTarget(target[i]);
}
} else if (target) {
this.addTarget(target);
}
}
},
/**
* <p>
* Destroy lifecycle method. Fires the destroy
* event, prior to invoking destructors for the
* class hierarchy.
* </p>
* <p>
* Subscribers to the destroy
* event can invoke preventDefault on the event object, to prevent destruction
* from proceeding.
* </p>
* @method destroy
* @return {Base} A reference to this object
* @final
* @chainable
*/
destroy: function() {
Y.log('destroy called', 'life', 'base');
/**
* <p>
* Lifecycle event for the destroy phase,
* fired prior to destruction. Invoking the preventDefault
* method on the event object provided to subscribers will
* prevent destruction from proceeding.
* </p>
* <p>
* Subscribers to the "after" moment of this event, will be notified
* after destruction is complete (and as a result cannot prevent
* destruction).
* </p>
* @event destroy
* @preventable _defDestroyFn
* @param {EventFacade} e Event object
*/
this.publish(DESTROY, {
queuable:false,
fireOnce:true,
defaultTargetOnly:true,
defaultFn: this._defDestroyFn
});
this.fire(DESTROY);
this.detachAll();
return this;
},
/**
* Default init event handler
*
* @method _defInitFn
* @param {EventFacade} e Event object, with a cfg property which
* refers to the configuration object passed to the constructor.
* @protected
*/
_defInitFn : function(e) {
this._initHierarchy(e.cfg);
if (this._initPlugins) {
// Need to initPlugins manually, to handle constructor parsing, static Plug parsing
this._initPlugins(e.cfg);
}
this._set(INITIALIZED, true);
},
/**
* Default destroy event handler
*
* @method _defDestroyFn
* @param {EventFacade} e Event object
* @protected
*/
_defDestroyFn : function(e) {
this._destroyHierarchy();
if (this._destroyPlugins) {
this._destroyPlugins();
}
this._set(DESTROYED, true);
},
/**
* Returns the class hierarchy for this object, with Base being the last class in the array.
*
* @method _getClasses
* @protected
* @return {Function[]} An array of classes (constructor functions), making up the class hierarchy for this object.
* This value is cached the first time the method, or _getAttrCfgs, is invoked. Subsequent invocations return the
* cached value.
*/
_getClasses : function() {
if (!this._classes) {
this._initHierarchyData();
}
return this._classes;
},
/**
* Returns an aggregated set of attribute configurations, by traversing the class hierarchy.
*
* @method _getAttrCfgs
* @protected
* @return {Object} The hash of attribute configurations, aggregated across classes in the hierarchy
* This value is cached the first time the method, or _getClasses, is invoked. Subsequent invocations return
* the cached value.
*/
_getAttrCfgs : function() {
if (!this._attrs) {
this._initHierarchyData();
}
return this._attrs;
},
/**
* A helper method used when processing ATTRS across the class hierarchy during
* initialization. Returns a disposable object with the attributes defined for
* the provided class, extracted from the set of all attributes passed in .
*
* @method _filterAttrCfs
* @private
*
* @param {Function} clazz The class for which the desired attributes are required.
* @param {Object} allCfgs The set of all attribute configurations for this instance.
* Attributes will be removed from this set, if they belong to the filtered class, so
* that by the time all classes are processed, allCfgs will be empty.
*
* @return {Object} The set of attributes belonging to the class passed in, in the form
* of an object with attribute name/configuration pairs.
*/
_filterAttrCfgs : function(clazz, allCfgs) {
var cfgs = null, attr, attrs = clazz.ATTRS;
if (attrs) {
for (attr in attrs) {
if (attrs.hasOwnProperty(attr) && allCfgs[attr]) {
cfgs = cfgs || {};
cfgs[attr] = allCfgs[attr];
delete allCfgs[attr];
}
}
}
return cfgs;
},
/**
* A helper method used by _getClasses and _getAttrCfgs, which determines both
* the array of classes and aggregate set of attribute configurations
* across the class hierarchy for the instance.
*
* @method _initHierarchyData
* @private
*/
_initHierarchyData : function() {
var c = this.constructor,
classes = [],
attrs = [];
while (c) {
// Add to classes
classes[classes.length] = c;
// Add to attributes
if (c.ATTRS) {
attrs[attrs.length] = c.ATTRS;
}
c = c.superclass ? c.superclass.constructor : null;
}
this._classes = classes;
this._attrs = this._aggregateAttrs(attrs);
},
/**
* A helper method, used by _initHierarchyData to aggregate
* attribute configuration across the instances class hierarchy.
*
* The method will potect the attribute configuration value to protect the statically defined
* default value in ATTRS if required (if the value is an object literal, array or the
* attribute configuration has cloneDefaultValue set to shallow or deep).
*
* @method _aggregateAttrs
* @private
* @param {Array} allAttrs An array of ATTRS definitions across classes in the hierarchy
* (subclass first, Base last)
* @return {Object} The aggregate set of ATTRS definitions for the instance
*/
_aggregateAttrs : function(allAttrs) {
var attr,
attrs,
cfg,
val,
path,
i,
clone,
cfgProps = Base._ATTR_CFG,
aggAttrs = {};
if (allAttrs) {
for (i = allAttrs.length-1; i >= 0; --i) {
attrs = allAttrs[i];
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
// Protect config passed in
cfg = Y.mix({}, attrs[attr], true, cfgProps);
val = cfg.value;
clone = cfg.cloneDefaultValue;
if (val) {
if ( (clone === undefined && (OBJECT_CONSTRUCTOR === val.constructor || L.isArray(val))) || clone === DEEP || clone === true) {
Y.log('Cloning default value for attribute:' + attr, 'info', 'base');
cfg.value = Y.clone(val);
} else if (clone === SHALLOW) {
Y.log('Merging default value for attribute:' + attr, 'info', 'base');
cfg.value = Y.merge(val);
}
// else if (clone === false), don't clone the static default value.
// It's intended to be used by reference.
}
path = null;
if (attr.indexOf(DOT) !== -1) {
path = attr.split(DOT);
attr = path.shift();
}
if (path && aggAttrs[attr] && aggAttrs[attr].value) {
O.setValue(aggAttrs[attr].value, path, val);
} else if (!path){
if (!aggAttrs[attr]) {
aggAttrs[attr] = cfg;
} else {
Y.mix(aggAttrs[attr], cfg, true, cfgProps);
}
}
}
}
}
}
return aggAttrs;
},
/**
* Initializes the class hierarchy for the instance, which includes
* initializing attributes for each class defined in the class's
* static <a href="#property_Base.ATTRS">ATTRS</a> property and
* invoking the initializer method on the prototype of each class in the hierarchy.
*
* @method _initHierarchy
* @param {Object} userVals Object with configuration property name/value pairs
* @private
*/
_initHierarchy : function(userVals) {
var lazy = this._lazyAddAttrs,
constr,
constrProto,
ci,
ei,
el,
classes = this._getClasses(),
attrCfgs = this._getAttrCfgs();
for (ci = classes.length-1; ci >= 0; ci--) {
constr = classes[ci];
constrProto = constr.prototype;
if (constr._yuibuild && constr._yuibuild.exts) {
for (ei = 0, el = constr._yuibuild.exts.length; ei < el; ei++) {
constr._yuibuild.exts[ei].apply(this, arguments);
}
}
this.addAttrs(this._filterAttrCfgs(constr, attrCfgs), userVals, lazy);
// Using INITIALIZER in hasOwnProperty check, for performance reasons (helps IE6 avoid GC thresholds when
// referencing string literals). Not using it in apply, again, for performance "." is faster.
if (constrProto.hasOwnProperty(INITIALIZER)) {
constrProto.initializer.apply(this, arguments);
}
}
},
/**
* Destroys the class hierarchy for this instance by invoking
* the descructor method on the prototype of each class in the hierarchy.
*
* @method _destroyHierarchy
* @private
*/
_destroyHierarchy : function() {
var constr,
constrProto,
ci, cl,
classes = this._getClasses();
for (ci = 0, cl = classes.length; ci < cl; ci++) {
constr = classes[ci];
constrProto = constr.prototype;
if (constrProto.hasOwnProperty(DESTRUCTOR)) {
constrProto.destructor.apply(this, arguments);
}
}
},
/**
* Default toString implementation. Provides the constructor NAME
* and the instance ID.
*
* @method toString
* @return {String} String representation for this object
*/
toString: function() {
return this.constructor.NAME + "[" + Y.stamp(this) + "]";
}
};
// Straightup augment, no wrapper functions
Y.mix(Base, Attribute, false, null, 1);
// Fix constructor
Base.prototype.constructor = Base;
Y.Base = Base;
}, '3.1.1' ,{requires:['attribute-base']});
YUI.add('base-pluginhost', function(Y) {
/**
* The base-pluginhost submodule adds Plugin support to Base, by augmenting Base with
* Plugin.Host and setting up static (class level) Base.plug and Base.unplug methods.
*
* @module base
* @submodule base-pluginhost
* @for Base
*/
var Base = Y.Base,
PluginHost = Y.Plugin.Host;
Y.mix(Base, PluginHost, false, null, 1);
/**
* Alias for <a href="Plugin.Host.html#method_Plugin.Host.plug">Plugin.Host.plug</a>. See aliased
* method for argument and return value details.
*
* @method Base.plug
* @static
*/
Base.plug = PluginHost.plug;
/**
* Alias for <a href="Plugin.Host.html#method_Plugin.Host.unplug">Plugin.Host.unplug</a>. See the
* aliased method for argument and return value details.
*
* @method Base.unplug
* @static
*/
Base.unplug = PluginHost.unplug;
}, '3.1.1' ,{requires:['base-base', 'pluginhost']});
YUI.add('base-build', function(Y) {
/**
* The base-build submodule provides Base.build functionality, which
* can be used to create custom classes, by aggregating extensions onto
* a main class.
*
* @module base
* @submodule base-build
* @for Base
*/
var Base = Y.Base,
L = Y.Lang,
build;
Base._build = function(name, main, extensions, px, sx, cfg) {
var build = Base._build,
builtClass = build._ctor(main, cfg),
buildCfg = build._cfg(main, cfg),
_mixCust = build._mixCust,
aggregates = buildCfg.aggregates,
custom = buildCfg.custom,
dynamic = builtClass._yuibuild.dynamic,
i, l, val, extClass;
if (dynamic && aggregates) {
for (i = 0, l = aggregates.length; i < l; ++i) {
val = aggregates[i];
if (main.hasOwnProperty(val)) {
builtClass[val] = L.isArray(main[val]) ? [] : {};
}
}
}
// Augment/Aggregate
for (i = 0, l = extensions.length; i < l; i++) {
extClass = extensions[i];
// Prototype, old non-displacing augment
Y.mix(builtClass, extClass, true, null, 1);
// Custom Statics
_mixCust(builtClass, extClass, aggregates, custom);
builtClass._yuibuild.exts.push(extClass);
}
if (px) {
Y.mix(builtClass.prototype, px, true);
}
if (sx) {
Y.mix(builtClass, build._clean(sx, aggregates, custom), true);
_mixCust(builtClass, sx, aggregates, custom);
}
builtClass.prototype.hasImpl = build._impl;
if (dynamic) {
builtClass.NAME = name;
builtClass.prototype.constructor = builtClass;
}
return builtClass;
};
build = Base._build;
Y.mix(build, {
_mixCust: function(r, s, aggregates, custom) {
if (aggregates) {
Y.aggregate(r, s, true, aggregates);
}
if (custom) {
for (var j in custom) {
if (custom.hasOwnProperty(j)) {
custom[j](j, r, s);
}
}
}
},
_tmpl: function(main) {
function BuiltClass() {
BuiltClass.superclass.constructor.apply(this, arguments);
}
Y.extend(BuiltClass, main);
return BuiltClass;
},
_impl : function(extClass) {
var classes = this._getClasses(), i, l, cls, exts, ll, j;
for (i = 0, l = classes.length; i < l; i++) {
cls = classes[i];
if (cls._yuibuild) {
exts = cls._yuibuild.exts;
ll = exts.length;
for (j = 0; j < ll; j++) {
if (exts[j] === extClass) {
return true;
}
}
}
}
return false;
},
_ctor : function(main, cfg) {
var dynamic = (cfg && false === cfg.dynamic) ? false : true,
builtClass = (dynamic) ? build._tmpl(main) : main;
builtClass._yuibuild = {
id: null,
exts : [],
dynamic: dynamic
};
return builtClass;
},
_cfg : function(main, cfg) {
var aggr = [],
cust = {},
buildCfg,
cfgAggr = (cfg && cfg.aggregates),
cfgCustBuild = (cfg && cfg.custom),
c = main;
while (c && c.prototype) {
buildCfg = c._buildCfg;
if (buildCfg) {
if (buildCfg.aggregates) {
aggr = aggr.concat(buildCfg.aggregates);
}
if (buildCfg.custom) {
Y.mix(cust, buildCfg.custom, true);
}
}
c = c.superclass ? c.superclass.constructor : null;
}
if (cfgAggr) {
aggr = aggr.concat(cfgAggr);
}
if (cfgCustBuild) {
Y.mix(cust, cfg.cfgBuild, true);
}
return {
aggregates: aggr,
custom: cust
};
},
_clean : function(sx, aggregates, custom) {
var prop, i, l, sxclone = Y.merge(sx);
for (prop in custom) {
if (sxclone.hasOwnProperty(prop)) {
delete sxclone[prop];
}
}
for (i = 0, l = aggregates.length; i < l; i++) {
prop = aggregates[i];
if (sxclone.hasOwnProperty(prop)) {
delete sxclone[prop];
}
}
return sxclone;
}
});
/**
* <p>
* Builds a custom constructor function (class) from the
* main function, and array of extension functions (classes)
* provided. The NAME field for the constructor function is
* defined by the first argument passed in.
* </p>
* <p>
* The cfg object supports the following properties
* </p>
* <dl>
* <dt>dynamic &#60;boolean&#62;</dt>
* <dd>
* <p>If true (default), a completely new class
* is created which extends the main class, and acts as the
* host on which the extension classes are augmented.</p>
* <p>If false, the extensions classes are augmented directly to
* the main class, modifying the main class' prototype.</p>
* </dd>
* <dt>aggregates &#60;String[]&#62;</dt>
* <dd>An array of static property names, which will get aggregated
* on to the built class, in addition to the default properties build
* will always aggregate as defined by the main class' static _buildCfg
* property.
* </dd>
* </dl>
*
* @method Base.build
* @static
* @param {Function} name The name of the new class. Used to defined the NAME property for the new class.
* @param {Function} main The main class on which to base the built class
* @param {Function[]} extensions The set of extension classes which will be
* augmented/aggregated to the built class.
* @param {Object} cfg Optional. Build configuration for the class (see description).
* @return {Function} A custom class, created from the provided main and extension classes
*/
Base.build = function(name, main, extensions, cfg) {
return build(name, main, extensions, null, null, cfg);
};
/**
* <p>Creates a new class (constructor function) which extends the base class passed in as the second argument,
* and mixes in the array of extensions provided.</p>
* <p>Prototype properties or methods can be added to the new class, using the px argument (similar to Y.extend).</p>
* <p>Static properties or methods can be added to the new class, using the sx argument (similar to Y.extend).</p>
* <p>
*
* </p>
* @method Base.create
* @static
* @param {Function} name The name of the newly created class. Used to defined the NAME property for the new class.
* @param {Function} main The base class which the new class should extend. This class needs to be Base or a class derived from base (e.g. Widget).
* @param {Function[]} extensions The list of extensions which will be mixed into the built class.
* @return {Function} The newly created class.
*/
Base.create = function(name, base, extensions, px, sx) {
return build(name, base, extensions, px, sx);
};
/**
* <p>Mixes in a list of extensions to an existing class.</p>
* @method Base.mix
* @static
* @param {Function} main The existing class into which the extensions should be mixed. The class needs to be Base or class derived from base (e.g. Widget)
* @param {Function[]} extensions The set of extension classes which will mixed into the existing main class.
* @return {Function} The modified main class, with extensions mixed in.
*/
Base.mix = function(main, extensions) {
return build(null, main, extensions, null, null, {dynamic:false});
};
/**
* The build configuration for the Base class.
*
* Defines the static fields which need to be aggregated
* when the Base class is used as the main class passed to
* the <a href="#method_Base.build">Base.build</a> method.
*
* @property Base._buildCfg
* @type Object
* @static
* @final
* @private
*/
Base._buildCfg = {
custom : {
ATTRS : function(prop, r, s) {
r[prop] = r[prop] || {};
if (s[prop]) {
Y.aggregate(r[prop], s[prop], true);
}
}
},
aggregates : ["_PLUG", "_UNPLUG"]
};
}, '3.1.1' ,{requires:['base-base']});
YUI.add('base', function(Y){}, '3.1.1' ,{use:['base-base', 'base-pluginhost', 'base-build']});

8
lib/yui/3.1.1/build/base/base-min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,43 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('base-pluginhost', function(Y) {
/**
* The base-pluginhost submodule adds Plugin support to Base, by augmenting Base with
* Plugin.Host and setting up static (class level) Base.plug and Base.unplug methods.
*
* @module base
* @submodule base-pluginhost
* @for Base
*/
var Base = Y.Base,
PluginHost = Y.Plugin.Host;
Y.mix(Base, PluginHost, false, null, 1);
/**
* Alias for <a href="Plugin.Host.html#method_Plugin.Host.plug">Plugin.Host.plug</a>. See aliased
* method for argument and return value details.
*
* @method Base.plug
* @static
*/
Base.plug = PluginHost.plug;
/**
* Alias for <a href="Plugin.Host.html#method_Plugin.Host.unplug">Plugin.Host.unplug</a>. See the
* aliased method for argument and return value details.
*
* @method Base.unplug
* @static
*/
Base.unplug = PluginHost.unplug;
}, '3.1.1' ,{requires:['base-base', 'pluginhost']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("base-pluginhost",function(C){var A=C.Base,B=C.Plugin.Host;C.mix(A,B,false,null,1);A.plug=B.plug;A.unplug=B.unplug;},"3.1.1",{requires:["base-base","pluginhost"]});

View file

@ -0,0 +1,43 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('base-pluginhost', function(Y) {
/**
* The base-pluginhost submodule adds Plugin support to Base, by augmenting Base with
* Plugin.Host and setting up static (class level) Base.plug and Base.unplug methods.
*
* @module base
* @submodule base-pluginhost
* @for Base
*/
var Base = Y.Base,
PluginHost = Y.Plugin.Host;
Y.mix(Base, PluginHost, false, null, 1);
/**
* Alias for <a href="Plugin.Host.html#method_Plugin.Host.plug">Plugin.Host.plug</a>. See aliased
* method for argument and return value details.
*
* @method Base.plug
* @static
*/
Base.plug = PluginHost.plug;
/**
* Alias for <a href="Plugin.Host.html#method_Plugin.Host.unplug">Plugin.Host.unplug</a>. See the
* aliased method for argument and return value details.
*
* @method Base.unplug
* @static
*/
Base.unplug = PluginHost.unplug;
}, '3.1.1' ,{requires:['base-base', 'pluginhost']});

View file

@ -0,0 +1,909 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('base-base', function(Y) {
/**
* The base module provides the Base class, which objects requiring attribute and custom event support can extend.
* The module also provides two ways to reuse code - It augments Base with the Plugin.Host interface which provides
* plugin support and also provides the Base.build method which provides a way to build custom classes using extensions.
*
* @module base
*/
/**
* The base-base submodule provides the Base class without the Plugin support, provided by Plugin.Host,
* and without the extension support provided by Base.build.
*
* @module base
* @submodule base-base
*/
var O = Y.Object,
L = Y.Lang,
DOT = ".",
DESTROY = "destroy",
INIT = "init",
INITIALIZED = "initialized",
DESTROYED = "destroyed",
INITIALIZER = "initializer",
BUBBLETARGETS = "bubbleTargets",
_BUBBLETARGETS = "_bubbleTargets",
OBJECT_CONSTRUCTOR = Object.prototype.constructor,
DEEP = "deep",
SHALLOW = "shallow",
DESTRUCTOR = "destructor",
Attribute = Y.Attribute;
/**
* <p>
* A base class which objects requiring attributes and custom event support can
* extend. Base also handles the chaining of initializer and destructor methods across
* the hierarchy as part of object construction and destruction. Additionally, attributes configured
* through the static <a href="#property_Base.ATTRS">ATTRS</a> property for each class
* in the hierarchy will be initialized by Base.
* </p>
*
* <p>
* The static <a href="#property_Base.NAME">NAME</a> property of each class extending
* from Base will be used as the identifier for the class, and is used by Base to prefix
* all events fired by instances of that class.
* </p>
*
* @class Base
* @constructor
* @uses Attribute
* @uses Plugin.Host
*
* @param {Object} config Object with configuration property name/value pairs. The object can be
* used to provide default values for the objects published attributes.
*
* <p>
* The config object can also contain the following non-attribute properties, providing a convenient
* way to configure events listeners and plugins for the instance, as part of the constructor call:
* </p>
*
* <dl>
* <dt>on</dt>
* <dd>An event name to listener function map, to register event listeners for the "on" moment of the event. A constructor convenience property for the <a href="Base.html#method_on">on</a> method.</dd>
* <dt>after</dt>
* <dd>An event name to listener function map, to register event listeners for the "after" moment of the event. A constructor convenience property for the <a href="Base.html#method_after">after</a> method.</dd>
* <dt>bubbleTargets</dt>
* <dd>An object, or array of objects, to register as bubble targets for bubbled events fired by this instance. A constructor convenience property for the <a href="EventTarget.html#method_addTarget">addTarget</a> method.</dd>
* <dt>plugins</dt>
* <dd>A plugin, or array of plugins to be plugged into the instance (see PluginHost's plug method for signature details). A constructor convenience property for the <a href="Plugin.Host.html#method_plug">plug</a> method.</dd>
* </dl>
*/
function Base() {
Attribute.call(this);
// If Plugin.Host has been augmented [ through base-pluginhost ], setup it's
// initial state, but don't initialize Plugins yet. That's done after initialization.
var PluginHost = Y.Plugin && Y.Plugin.Host;
if (this._initPlugins && PluginHost) {
PluginHost.call(this);
}
if (this._lazyAddAttrs !== false) { this._lazyAddAttrs = true; }
/**
* The string used to identify the class of this object.
*
* @deprecated Use this.constructor.NAME
* @property name
* @type String
*/
this.name = this.constructor.NAME;
this._eventPrefix = this.constructor.EVENT_PREFIX || this.constructor.NAME;
this.init.apply(this, arguments);
}
/**
* The list of properties which can be configured for
* each attribute (e.g. setter, getter, writeOnce, readOnly etc.)
*
* @property Base._ATTR_CFG
* @type Array
* @static
* @private
*/
Base._ATTR_CFG = Attribute._ATTR_CFG.concat("cloneDefaultValue");
/**
* <p>
* The string to be used to identify instances of
* this class, for example in prefixing events.
* </p>
* <p>
* Classes extending Base, should define their own
* static NAME property, which should be camelCase by
* convention (e.g. MyClass.NAME = "myClass";).
* </p>
* @property Base.NAME
* @type String
* @static
*/
Base.NAME = "base";
/**
* The default set of attributes which will be available for instances of this class, and
* their configuration. In addition to the configuration properties listed by
* Attribute's <a href="Attribute.html#method_addAttr">addAttr</a> method, the attribute
* can also be configured with a "cloneDefaultValue" property, which defines how the statically
* defined value field should be protected ("shallow", "deep" and false are supported values).
*
* By default if the value is an object literal or an array it will be "shallow" cloned, to
* protect the default value.
*
* @property Base.ATTRS
* @type Object
* @static
*/
Base.ATTRS = {
/**
* Flag indicating whether or not this object
* has been through the init lifecycle phase.
*
* @attribute initialized
* @readonly
* @default false
* @type boolean
*/
initialized: {
readOnly:true,
value:false
},
/**
* Flag indicating whether or not this object
* has been through the destroy lifecycle phase.
*
* @attribute destroyed
* @readonly
* @default false
* @type boolean
*/
destroyed: {
readOnly:true,
value:false
}
};
Base.prototype = {
/**
* Init lifecycle method, invoked during construction.
* Fires the init event prior to setting up attributes and
* invoking initializers for the class hierarchy.
*
* @method init
* @final
* @chainable
* @param {Object} config Object with configuration property name/value pairs
* @return {Base} A reference to this object
*/
init: function(config) {
this._yuievt.config.prefix = this._eventPrefix;
/**
* <p>
* Lifecycle event for the init phase, fired prior to initialization.
* Invoking the preventDefault() method on the event object provided
* to subscribers will prevent initialization from occuring.
* </p>
* <p>
* Subscribers to the "after" momemt of this event, will be notified
* after initialization of the object is complete (and therefore
* cannot prevent initialization).
* </p>
*
* @event init
* @preventable _defInitFn
* @param {EventFacade} e Event object, with a cfg property which
* refers to the configuration object passed to the constructor.
*/
this.publish(INIT, {
queuable:false,
fireOnce:true,
defaultTargetOnly:true,
defaultFn:this._defInitFn
});
this._preInitEventCfg(config);
this.fire(INIT, {cfg: config});
return this;
},
/**
* Handles the special on, after and target properties which allow the user to
* easily configure on and after listeners as well as bubble targets during
* construction, prior to init.
*
* @method _preInitEventCfg
* @param {Object} config The user configuration object
*/
_preInitEventCfg : function(config) {
if (config) {
if (config.on) {
this.on(config.on);
}
if (config.after) {
this.after(config.after);
}
}
var i, l, target,
userTargets = (config && BUBBLETARGETS in config);
if (userTargets || _BUBBLETARGETS in this) {
target = userTargets ? (config && config.bubbleTargets) : this._bubbleTargets;
if (L.isArray(target)) {
for (i = 0, l = target.length; i < l; i++) {
this.addTarget(target[i]);
}
} else if (target) {
this.addTarget(target);
}
}
},
/**
* <p>
* Destroy lifecycle method. Fires the destroy
* event, prior to invoking destructors for the
* class hierarchy.
* </p>
* <p>
* Subscribers to the destroy
* event can invoke preventDefault on the event object, to prevent destruction
* from proceeding.
* </p>
* @method destroy
* @return {Base} A reference to this object
* @final
* @chainable
*/
destroy: function() {
/**
* <p>
* Lifecycle event for the destroy phase,
* fired prior to destruction. Invoking the preventDefault
* method on the event object provided to subscribers will
* prevent destruction from proceeding.
* </p>
* <p>
* Subscribers to the "after" moment of this event, will be notified
* after destruction is complete (and as a result cannot prevent
* destruction).
* </p>
* @event destroy
* @preventable _defDestroyFn
* @param {EventFacade} e Event object
*/
this.publish(DESTROY, {
queuable:false,
fireOnce:true,
defaultTargetOnly:true,
defaultFn: this._defDestroyFn
});
this.fire(DESTROY);
this.detachAll();
return this;
},
/**
* Default init event handler
*
* @method _defInitFn
* @param {EventFacade} e Event object, with a cfg property which
* refers to the configuration object passed to the constructor.
* @protected
*/
_defInitFn : function(e) {
this._initHierarchy(e.cfg);
if (this._initPlugins) {
// Need to initPlugins manually, to handle constructor parsing, static Plug parsing
this._initPlugins(e.cfg);
}
this._set(INITIALIZED, true);
},
/**
* Default destroy event handler
*
* @method _defDestroyFn
* @param {EventFacade} e Event object
* @protected
*/
_defDestroyFn : function(e) {
this._destroyHierarchy();
if (this._destroyPlugins) {
this._destroyPlugins();
}
this._set(DESTROYED, true);
},
/**
* Returns the class hierarchy for this object, with Base being the last class in the array.
*
* @method _getClasses
* @protected
* @return {Function[]} An array of classes (constructor functions), making up the class hierarchy for this object.
* This value is cached the first time the method, or _getAttrCfgs, is invoked. Subsequent invocations return the
* cached value.
*/
_getClasses : function() {
if (!this._classes) {
this._initHierarchyData();
}
return this._classes;
},
/**
* Returns an aggregated set of attribute configurations, by traversing the class hierarchy.
*
* @method _getAttrCfgs
* @protected
* @return {Object} The hash of attribute configurations, aggregated across classes in the hierarchy
* This value is cached the first time the method, or _getClasses, is invoked. Subsequent invocations return
* the cached value.
*/
_getAttrCfgs : function() {
if (!this._attrs) {
this._initHierarchyData();
}
return this._attrs;
},
/**
* A helper method used when processing ATTRS across the class hierarchy during
* initialization. Returns a disposable object with the attributes defined for
* the provided class, extracted from the set of all attributes passed in .
*
* @method _filterAttrCfs
* @private
*
* @param {Function} clazz The class for which the desired attributes are required.
* @param {Object} allCfgs The set of all attribute configurations for this instance.
* Attributes will be removed from this set, if they belong to the filtered class, so
* that by the time all classes are processed, allCfgs will be empty.
*
* @return {Object} The set of attributes belonging to the class passed in, in the form
* of an object with attribute name/configuration pairs.
*/
_filterAttrCfgs : function(clazz, allCfgs) {
var cfgs = null, attr, attrs = clazz.ATTRS;
if (attrs) {
for (attr in attrs) {
if (attrs.hasOwnProperty(attr) && allCfgs[attr]) {
cfgs = cfgs || {};
cfgs[attr] = allCfgs[attr];
delete allCfgs[attr];
}
}
}
return cfgs;
},
/**
* A helper method used by _getClasses and _getAttrCfgs, which determines both
* the array of classes and aggregate set of attribute configurations
* across the class hierarchy for the instance.
*
* @method _initHierarchyData
* @private
*/
_initHierarchyData : function() {
var c = this.constructor,
classes = [],
attrs = [];
while (c) {
// Add to classes
classes[classes.length] = c;
// Add to attributes
if (c.ATTRS) {
attrs[attrs.length] = c.ATTRS;
}
c = c.superclass ? c.superclass.constructor : null;
}
this._classes = classes;
this._attrs = this._aggregateAttrs(attrs);
},
/**
* A helper method, used by _initHierarchyData to aggregate
* attribute configuration across the instances class hierarchy.
*
* The method will potect the attribute configuration value to protect the statically defined
* default value in ATTRS if required (if the value is an object literal, array or the
* attribute configuration has cloneDefaultValue set to shallow or deep).
*
* @method _aggregateAttrs
* @private
* @param {Array} allAttrs An array of ATTRS definitions across classes in the hierarchy
* (subclass first, Base last)
* @return {Object} The aggregate set of ATTRS definitions for the instance
*/
_aggregateAttrs : function(allAttrs) {
var attr,
attrs,
cfg,
val,
path,
i,
clone,
cfgProps = Base._ATTR_CFG,
aggAttrs = {};
if (allAttrs) {
for (i = allAttrs.length-1; i >= 0; --i) {
attrs = allAttrs[i];
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
// Protect config passed in
cfg = Y.mix({}, attrs[attr], true, cfgProps);
val = cfg.value;
clone = cfg.cloneDefaultValue;
if (val) {
if ( (clone === undefined && (OBJECT_CONSTRUCTOR === val.constructor || L.isArray(val))) || clone === DEEP || clone === true) {
cfg.value = Y.clone(val);
} else if (clone === SHALLOW) {
cfg.value = Y.merge(val);
}
// else if (clone === false), don't clone the static default value.
// It's intended to be used by reference.
}
path = null;
if (attr.indexOf(DOT) !== -1) {
path = attr.split(DOT);
attr = path.shift();
}
if (path && aggAttrs[attr] && aggAttrs[attr].value) {
O.setValue(aggAttrs[attr].value, path, val);
} else if (!path){
if (!aggAttrs[attr]) {
aggAttrs[attr] = cfg;
} else {
Y.mix(aggAttrs[attr], cfg, true, cfgProps);
}
}
}
}
}
}
return aggAttrs;
},
/**
* Initializes the class hierarchy for the instance, which includes
* initializing attributes for each class defined in the class's
* static <a href="#property_Base.ATTRS">ATTRS</a> property and
* invoking the initializer method on the prototype of each class in the hierarchy.
*
* @method _initHierarchy
* @param {Object} userVals Object with configuration property name/value pairs
* @private
*/
_initHierarchy : function(userVals) {
var lazy = this._lazyAddAttrs,
constr,
constrProto,
ci,
ei,
el,
classes = this._getClasses(),
attrCfgs = this._getAttrCfgs();
for (ci = classes.length-1; ci >= 0; ci--) {
constr = classes[ci];
constrProto = constr.prototype;
if (constr._yuibuild && constr._yuibuild.exts) {
for (ei = 0, el = constr._yuibuild.exts.length; ei < el; ei++) {
constr._yuibuild.exts[ei].apply(this, arguments);
}
}
this.addAttrs(this._filterAttrCfgs(constr, attrCfgs), userVals, lazy);
// Using INITIALIZER in hasOwnProperty check, for performance reasons (helps IE6 avoid GC thresholds when
// referencing string literals). Not using it in apply, again, for performance "." is faster.
if (constrProto.hasOwnProperty(INITIALIZER)) {
constrProto.initializer.apply(this, arguments);
}
}
},
/**
* Destroys the class hierarchy for this instance by invoking
* the descructor method on the prototype of each class in the hierarchy.
*
* @method _destroyHierarchy
* @private
*/
_destroyHierarchy : function() {
var constr,
constrProto,
ci, cl,
classes = this._getClasses();
for (ci = 0, cl = classes.length; ci < cl; ci++) {
constr = classes[ci];
constrProto = constr.prototype;
if (constrProto.hasOwnProperty(DESTRUCTOR)) {
constrProto.destructor.apply(this, arguments);
}
}
},
/**
* Default toString implementation. Provides the constructor NAME
* and the instance ID.
*
* @method toString
* @return {String} String representation for this object
*/
toString: function() {
return this.constructor.NAME + "[" + Y.stamp(this) + "]";
}
};
// Straightup augment, no wrapper functions
Y.mix(Base, Attribute, false, null, 1);
// Fix constructor
Base.prototype.constructor = Base;
Y.Base = Base;
}, '3.1.1' ,{requires:['attribute-base']});
YUI.add('base-pluginhost', function(Y) {
/**
* The base-pluginhost submodule adds Plugin support to Base, by augmenting Base with
* Plugin.Host and setting up static (class level) Base.plug and Base.unplug methods.
*
* @module base
* @submodule base-pluginhost
* @for Base
*/
var Base = Y.Base,
PluginHost = Y.Plugin.Host;
Y.mix(Base, PluginHost, false, null, 1);
/**
* Alias for <a href="Plugin.Host.html#method_Plugin.Host.plug">Plugin.Host.plug</a>. See aliased
* method for argument and return value details.
*
* @method Base.plug
* @static
*/
Base.plug = PluginHost.plug;
/**
* Alias for <a href="Plugin.Host.html#method_Plugin.Host.unplug">Plugin.Host.unplug</a>. See the
* aliased method for argument and return value details.
*
* @method Base.unplug
* @static
*/
Base.unplug = PluginHost.unplug;
}, '3.1.1' ,{requires:['base-base', 'pluginhost']});
YUI.add('base-build', function(Y) {
/**
* The base-build submodule provides Base.build functionality, which
* can be used to create custom classes, by aggregating extensions onto
* a main class.
*
* @module base
* @submodule base-build
* @for Base
*/
var Base = Y.Base,
L = Y.Lang,
build;
Base._build = function(name, main, extensions, px, sx, cfg) {
var build = Base._build,
builtClass = build._ctor(main, cfg),
buildCfg = build._cfg(main, cfg),
_mixCust = build._mixCust,
aggregates = buildCfg.aggregates,
custom = buildCfg.custom,
dynamic = builtClass._yuibuild.dynamic,
i, l, val, extClass;
if (dynamic && aggregates) {
for (i = 0, l = aggregates.length; i < l; ++i) {
val = aggregates[i];
if (main.hasOwnProperty(val)) {
builtClass[val] = L.isArray(main[val]) ? [] : {};
}
}
}
// Augment/Aggregate
for (i = 0, l = extensions.length; i < l; i++) {
extClass = extensions[i];
// Prototype, old non-displacing augment
Y.mix(builtClass, extClass, true, null, 1);
// Custom Statics
_mixCust(builtClass, extClass, aggregates, custom);
builtClass._yuibuild.exts.push(extClass);
}
if (px) {
Y.mix(builtClass.prototype, px, true);
}
if (sx) {
Y.mix(builtClass, build._clean(sx, aggregates, custom), true);
_mixCust(builtClass, sx, aggregates, custom);
}
builtClass.prototype.hasImpl = build._impl;
if (dynamic) {
builtClass.NAME = name;
builtClass.prototype.constructor = builtClass;
}
return builtClass;
};
build = Base._build;
Y.mix(build, {
_mixCust: function(r, s, aggregates, custom) {
if (aggregates) {
Y.aggregate(r, s, true, aggregates);
}
if (custom) {
for (var j in custom) {
if (custom.hasOwnProperty(j)) {
custom[j](j, r, s);
}
}
}
},
_tmpl: function(main) {
function BuiltClass() {
BuiltClass.superclass.constructor.apply(this, arguments);
}
Y.extend(BuiltClass, main);
return BuiltClass;
},
_impl : function(extClass) {
var classes = this._getClasses(), i, l, cls, exts, ll, j;
for (i = 0, l = classes.length; i < l; i++) {
cls = classes[i];
if (cls._yuibuild) {
exts = cls._yuibuild.exts;
ll = exts.length;
for (j = 0; j < ll; j++) {
if (exts[j] === extClass) {
return true;
}
}
}
}
return false;
},
_ctor : function(main, cfg) {
var dynamic = (cfg && false === cfg.dynamic) ? false : true,
builtClass = (dynamic) ? build._tmpl(main) : main;
builtClass._yuibuild = {
id: null,
exts : [],
dynamic: dynamic
};
return builtClass;
},
_cfg : function(main, cfg) {
var aggr = [],
cust = {},
buildCfg,
cfgAggr = (cfg && cfg.aggregates),
cfgCustBuild = (cfg && cfg.custom),
c = main;
while (c && c.prototype) {
buildCfg = c._buildCfg;
if (buildCfg) {
if (buildCfg.aggregates) {
aggr = aggr.concat(buildCfg.aggregates);
}
if (buildCfg.custom) {
Y.mix(cust, buildCfg.custom, true);
}
}
c = c.superclass ? c.superclass.constructor : null;
}
if (cfgAggr) {
aggr = aggr.concat(cfgAggr);
}
if (cfgCustBuild) {
Y.mix(cust, cfg.cfgBuild, true);
}
return {
aggregates: aggr,
custom: cust
};
},
_clean : function(sx, aggregates, custom) {
var prop, i, l, sxclone = Y.merge(sx);
for (prop in custom) {
if (sxclone.hasOwnProperty(prop)) {
delete sxclone[prop];
}
}
for (i = 0, l = aggregates.length; i < l; i++) {
prop = aggregates[i];
if (sxclone.hasOwnProperty(prop)) {
delete sxclone[prop];
}
}
return sxclone;
}
});
/**
* <p>
* Builds a custom constructor function (class) from the
* main function, and array of extension functions (classes)
* provided. The NAME field for the constructor function is
* defined by the first argument passed in.
* </p>
* <p>
* The cfg object supports the following properties
* </p>
* <dl>
* <dt>dynamic &#60;boolean&#62;</dt>
* <dd>
* <p>If true (default), a completely new class
* is created which extends the main class, and acts as the
* host on which the extension classes are augmented.</p>
* <p>If false, the extensions classes are augmented directly to
* the main class, modifying the main class' prototype.</p>
* </dd>
* <dt>aggregates &#60;String[]&#62;</dt>
* <dd>An array of static property names, which will get aggregated
* on to the built class, in addition to the default properties build
* will always aggregate as defined by the main class' static _buildCfg
* property.
* </dd>
* </dl>
*
* @method Base.build
* @static
* @param {Function} name The name of the new class. Used to defined the NAME property for the new class.
* @param {Function} main The main class on which to base the built class
* @param {Function[]} extensions The set of extension classes which will be
* augmented/aggregated to the built class.
* @param {Object} cfg Optional. Build configuration for the class (see description).
* @return {Function} A custom class, created from the provided main and extension classes
*/
Base.build = function(name, main, extensions, cfg) {
return build(name, main, extensions, null, null, cfg);
};
/**
* <p>Creates a new class (constructor function) which extends the base class passed in as the second argument,
* and mixes in the array of extensions provided.</p>
* <p>Prototype properties or methods can be added to the new class, using the px argument (similar to Y.extend).</p>
* <p>Static properties or methods can be added to the new class, using the sx argument (similar to Y.extend).</p>
* <p>
*
* </p>
* @method Base.create
* @static
* @param {Function} name The name of the newly created class. Used to defined the NAME property for the new class.
* @param {Function} main The base class which the new class should extend. This class needs to be Base or a class derived from base (e.g. Widget).
* @param {Function[]} extensions The list of extensions which will be mixed into the built class.
* @return {Function} The newly created class.
*/
Base.create = function(name, base, extensions, px, sx) {
return build(name, base, extensions, px, sx);
};
/**
* <p>Mixes in a list of extensions to an existing class.</p>
* @method Base.mix
* @static
* @param {Function} main The existing class into which the extensions should be mixed. The class needs to be Base or class derived from base (e.g. Widget)
* @param {Function[]} extensions The set of extension classes which will mixed into the existing main class.
* @return {Function} The modified main class, with extensions mixed in.
*/
Base.mix = function(main, extensions) {
return build(null, main, extensions, null, null, {dynamic:false});
};
/**
* The build configuration for the Base class.
*
* Defines the static fields which need to be aggregated
* when the Base class is used as the main class passed to
* the <a href="#method_Base.build">Base.build</a> method.
*
* @property Base._buildCfg
* @type Object
* @static
* @final
* @private
*/
Base._buildCfg = {
custom : {
ATTRS : function(prop, r, s) {
r[prop] = r[prop] || {};
if (s[prop]) {
Y.aggregate(r[prop], s[prop], true);
}
}
},
aggregates : ["_PLUG", "_UNPLUG"]
};
}, '3.1.1' ,{requires:['base-base']});
YUI.add('base', function(Y){}, '3.1.1' ,{use:['base-base', 'base-pluginhost', 'base-build']});

366
lib/yui/3.1.1/build/cache/cache-debug.js vendored Normal file
View file

@ -0,0 +1,366 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('cache', function(Y) {
/**
* The Cache utility provides a common configurable interface for components to
* cache and retrieve data from a local JavaScript struct.
*
* @module cache
*/
var LANG = Y.Lang,
/**
* Base class for the YUI Cache utility.
* @class Cache
* @extends Plugin.Base
* @constructor
*/
Cache = function() {
Cache.superclass.constructor.apply(this, arguments);
};
/////////////////////////////////////////////////////////////////////////////
//
// Cache static properties
//
/////////////////////////////////////////////////////////////////////////////
Y.mix(Cache, {
/**
* The namespace for the plugin. This will be the property on the host which
* references the plugin instance.
*
* @property NS
* @type String
* @static
* @final
* @value "cache"
*/
NS: "cache",
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "cache"
*/
NAME: "cache",
ATTRS: {
/////////////////////////////////////////////////////////////////////////////
//
// Cache Attributes
//
/////////////////////////////////////////////////////////////////////////////
/**
* @attribute max
* @description Maximum number of entries the Cache can hold.
* Set to 0 to turn off caching.
* @type Number
* @default 0
*/
max: {
value: 0,
validator: function(value) {
return (LANG.isNumber(value));
},
setter: function(value) {
// If the cache is full, make room by removing stalest element (index=0)
var entries = this._entries;
if(value > 0) {
if(entries) {
while(entries.length > value) {
entries.shift();
}
}
}
else {
this._entries = [];
}
return value;
}
},
/**
* @attribute size
* @description Number of entries currently cached.
* @type Number
*/
size: {
readOnly: true,
getter: function() {
return this._entries.length;
}
},
/**
* @attribute uniqueKeys
* @description Validate uniqueness of stored keys. Default is false and
* is more performant.
* @type Number
*/
uniqueKeys: {
value: false,
validator: function(value) {
return (LANG.isBoolean(value));
}
},
/**
* @attribute entries
* @description Cached entries.
* @type Array
*/
entries: {
readOnly: true,
getter: function() {
return this._entries;
}
}
}
});
Y.extend(Cache, Y.Plugin.Base, {
/////////////////////////////////////////////////////////////////////////////
//
// Cache private properties
//
/////////////////////////////////////////////////////////////////////////////
/**
* Array of request/response objects indexed chronologically.
*
* @property _entries
* @type Object[]
* @private
*/
_entries: null,
/////////////////////////////////////////////////////////////////////////////
//
// Cache private methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* @method initializer
* @description Internal init() handler.
* @param config {Object} Config object.
* @private
*/
initializer: function(config) {
/**
* @event add
* @description Fired when an entry is added.
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>entry (Object)</dt> <dd>The cached entry.</dd>
* </dl>
* @preventable _defAddFn
*/
this.publish("add", {defaultFn: this._defAddFn});
/**
* @event flush
* @description Fired when the cache is flushed.
* @param e {Event.Facade} Event Facade object.
* @preventable _defFlushFn
*/
this.publish("flush", {defaultFn: this._defFlushFn});
/**
* @event request
* @description Fired when an entry is requested from the cache.
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>request (Object)</dt> <dd>The request object.</dd>
* </dl>
*/
/**
* @event retrieve
* @description Fired when an entry is retrieved from the cache.
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>entry (Object)</dt> <dd>The retrieved entry.</dd>
* </dl>
*/
// Initialize internal values
this._entries = [];
Y.log("Cache initialized", "info", "cache");
},
/**
* @method destructor
* @description Internal destroy() handler.
* @private
*/
destructor: function() {
this._entries = null;
Y.log("Cache destroyed", "info", "cache");
},
/////////////////////////////////////////////////////////////////////////////
//
// Cache protected methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Adds entry to cache.
*
* @method _defAddFn
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>entry (Object)</dt> <dd>The cached entry.</dd>
* </dl>
* @protected
*/
_defAddFn: function(e) {
var entries = this._entries,
max = this.get("max"),
entry = e.entry;
if(this.get("uniqueKeys") && (this.retrieve(e.entry.request))) {
entries.shift();
}
// If the cache at or over capacity, make room by removing stalest element (index=0)
while(entries.length>=max) {
entries.shift();
}
// Add entry to cache in the newest position, at the end of the array
entries[entries.length] = entry;
Y.log("Cached entry: " + Y.dump(entry), "info", "cache");
},
/**
* Flushes cache.
*
* @method _defFlushFn
* @param e {Event.Facade} Event Facade object.
* @protected
*/
_defFlushFn: function(e) {
this._entries = [];
Y.log("Cache flushed", "info", "cache");
},
/**
* Default overridable method compares current request with given cache entry.
* Returns true if current request matches the cached request, otherwise
* false. Implementers should override this method to customize the
* cache-matching algorithm.
*
* @method _isMatch
* @param request {Object} Request object.
* @param entry {Object} Cached entry.
* @return {Boolean} True if current request matches given cached request, false otherwise.
* @protected
*/
_isMatch: function(request, entry) {
return (request === entry.request);
},
/////////////////////////////////////////////////////////////////////////////
//
// Cache public methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Adds a new entry to the cache of the format
* {request:request, response:response, payload:payload}.
* If cache is full, evicts the stalest entry before adding the new one.
*
* @method add
* @param request {Object} Request value.
* @param response {Object} Response value.
* @param payload {Object} (optional) Arbitrary data payload.
*/
add: function(request, response, payload) {
if(this.get("entries") && (this.get("max")>0) &&
(LANG.isValue(request) || LANG.isNull(request) || LANG.isUndefined(request))) {
this.fire("add", {entry: {request:request, response:response, payload:payload}});
}
else {
Y.log("Could not add " + Y.dump(response) + " to cache for " + Y.dump(request), "info", "cache");
}
},
/**
* Flushes cache.
*
* @method flush
*/
flush: function() {
this.fire("flush");
},
/**
* Retrieves cached entry for given request, if available, and refreshes
* entry in the cache. Returns null if there is no cache match.
*
* @method retrieve
* @param request {Object} Request object.
* @return {Object} Cached entry object with the properties request, response, and payload, or null.
*/
retrieve: function(request) {
// If cache is enabled...
var entries = this._entries,
length = entries.length,
entry = null,
i = length-1;
if((this.get("max") > 0) && (length > 0)) {
this.fire("request", {request: request});
// Loop through each cached entry starting from the newest
for(; i >= 0; i--) {
entry = entries[i];
// Execute matching function
if(this._isMatch(request, entry)) {
this.fire("retrieve", {entry: entry});
// Refresh the position of the cache hit
if(i < length-1) {
// Remove element from its original location
entries.splice(i,1);
// Add as newest
entries[entries.length] = entry;
Y.log("Refreshed cache entry: " + Y.dump(entry) +
" for request: " + Y.dump(request), "info", "cache");
}
Y.log("Retrieved cached response: " + Y.dump(entry) +
" for request: " + Y.dump(request), "info", "cache");
return entry;
}
}
}
return null;
}
});
Y.Cache = Cache;
}, '3.1.1' ,{requires:['plugin']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("cache",function(C){var A=C.Lang,B=function(){B.superclass.constructor.apply(this,arguments);};C.mix(B,{NS:"cache",NAME:"cache",ATTRS:{max:{value:0,validator:function(D){return(A.isNumber(D));},setter:function(E){var D=this._entries;if(E>0){if(D){while(D.length>E){D.shift();}}}else{this._entries=[];}return E;}},size:{readOnly:true,getter:function(){return this._entries.length;}},uniqueKeys:{value:false,validator:function(D){return(A.isBoolean(D));}},entries:{readOnly:true,getter:function(){return this._entries;}}}});C.extend(B,C.Plugin.Base,{_entries:null,initializer:function(D){this.publish("add",{defaultFn:this._defAddFn});this.publish("flush",{defaultFn:this._defFlushFn});this._entries=[];},destructor:function(){this._entries=null;},_defAddFn:function(G){var E=this._entries,D=this.get("max"),F=G.entry;if(this.get("uniqueKeys")&&(this.retrieve(G.entry.request))){E.shift();}while(E.length>=D){E.shift();}E[E.length]=F;},_defFlushFn:function(D){this._entries=[];},_isMatch:function(E,D){return(E===D.request);},add:function(E,D,F){if(this.get("entries")&&(this.get("max")>0)&&(A.isValue(E)||A.isNull(E)||A.isUndefined(E))){this.fire("add",{entry:{request:E,response:D,payload:F}});}else{}},flush:function(){this.fire("flush");},retrieve:function(H){var D=this._entries,G=D.length,F=null,E=G-1;if((this.get("max")>0)&&(G>0)){this.fire("request",{request:H});for(;E>=0;E--){F=D[E];if(this._isMatch(H,F)){this.fire("retrieve",{entry:F});if(E<G-1){D.splice(E,1);D[D.length]=F;}return F;}}}return null;}});C.Cache=B;},"3.1.1",{requires:["plugin"]});

357
lib/yui/3.1.1/build/cache/cache.js vendored Normal file
View file

@ -0,0 +1,357 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('cache', function(Y) {
/**
* The Cache utility provides a common configurable interface for components to
* cache and retrieve data from a local JavaScript struct.
*
* @module cache
*/
var LANG = Y.Lang,
/**
* Base class for the YUI Cache utility.
* @class Cache
* @extends Plugin.Base
* @constructor
*/
Cache = function() {
Cache.superclass.constructor.apply(this, arguments);
};
/////////////////////////////////////////////////////////////////////////////
//
// Cache static properties
//
/////////////////////////////////////////////////////////////////////////////
Y.mix(Cache, {
/**
* The namespace for the plugin. This will be the property on the host which
* references the plugin instance.
*
* @property NS
* @type String
* @static
* @final
* @value "cache"
*/
NS: "cache",
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "cache"
*/
NAME: "cache",
ATTRS: {
/////////////////////////////////////////////////////////////////////////////
//
// Cache Attributes
//
/////////////////////////////////////////////////////////////////////////////
/**
* @attribute max
* @description Maximum number of entries the Cache can hold.
* Set to 0 to turn off caching.
* @type Number
* @default 0
*/
max: {
value: 0,
validator: function(value) {
return (LANG.isNumber(value));
},
setter: function(value) {
// If the cache is full, make room by removing stalest element (index=0)
var entries = this._entries;
if(value > 0) {
if(entries) {
while(entries.length > value) {
entries.shift();
}
}
}
else {
this._entries = [];
}
return value;
}
},
/**
* @attribute size
* @description Number of entries currently cached.
* @type Number
*/
size: {
readOnly: true,
getter: function() {
return this._entries.length;
}
},
/**
* @attribute uniqueKeys
* @description Validate uniqueness of stored keys. Default is false and
* is more performant.
* @type Number
*/
uniqueKeys: {
value: false,
validator: function(value) {
return (LANG.isBoolean(value));
}
},
/**
* @attribute entries
* @description Cached entries.
* @type Array
*/
entries: {
readOnly: true,
getter: function() {
return this._entries;
}
}
}
});
Y.extend(Cache, Y.Plugin.Base, {
/////////////////////////////////////////////////////////////////////////////
//
// Cache private properties
//
/////////////////////////////////////////////////////////////////////////////
/**
* Array of request/response objects indexed chronologically.
*
* @property _entries
* @type Object[]
* @private
*/
_entries: null,
/////////////////////////////////////////////////////////////////////////////
//
// Cache private methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* @method initializer
* @description Internal init() handler.
* @param config {Object} Config object.
* @private
*/
initializer: function(config) {
/**
* @event add
* @description Fired when an entry is added.
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>entry (Object)</dt> <dd>The cached entry.</dd>
* </dl>
* @preventable _defAddFn
*/
this.publish("add", {defaultFn: this._defAddFn});
/**
* @event flush
* @description Fired when the cache is flushed.
* @param e {Event.Facade} Event Facade object.
* @preventable _defFlushFn
*/
this.publish("flush", {defaultFn: this._defFlushFn});
/**
* @event request
* @description Fired when an entry is requested from the cache.
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>request (Object)</dt> <dd>The request object.</dd>
* </dl>
*/
/**
* @event retrieve
* @description Fired when an entry is retrieved from the cache.
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>entry (Object)</dt> <dd>The retrieved entry.</dd>
* </dl>
*/
// Initialize internal values
this._entries = [];
},
/**
* @method destructor
* @description Internal destroy() handler.
* @private
*/
destructor: function() {
this._entries = null;
},
/////////////////////////////////////////////////////////////////////////////
//
// Cache protected methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Adds entry to cache.
*
* @method _defAddFn
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>entry (Object)</dt> <dd>The cached entry.</dd>
* </dl>
* @protected
*/
_defAddFn: function(e) {
var entries = this._entries,
max = this.get("max"),
entry = e.entry;
if(this.get("uniqueKeys") && (this.retrieve(e.entry.request))) {
entries.shift();
}
// If the cache at or over capacity, make room by removing stalest element (index=0)
while(entries.length>=max) {
entries.shift();
}
// Add entry to cache in the newest position, at the end of the array
entries[entries.length] = entry;
},
/**
* Flushes cache.
*
* @method _defFlushFn
* @param e {Event.Facade} Event Facade object.
* @protected
*/
_defFlushFn: function(e) {
this._entries = [];
},
/**
* Default overridable method compares current request with given cache entry.
* Returns true if current request matches the cached request, otherwise
* false. Implementers should override this method to customize the
* cache-matching algorithm.
*
* @method _isMatch
* @param request {Object} Request object.
* @param entry {Object} Cached entry.
* @return {Boolean} True if current request matches given cached request, false otherwise.
* @protected
*/
_isMatch: function(request, entry) {
return (request === entry.request);
},
/////////////////////////////////////////////////////////////////////////////
//
// Cache public methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Adds a new entry to the cache of the format
* {request:request, response:response, payload:payload}.
* If cache is full, evicts the stalest entry before adding the new one.
*
* @method add
* @param request {Object} Request value.
* @param response {Object} Response value.
* @param payload {Object} (optional) Arbitrary data payload.
*/
add: function(request, response, payload) {
if(this.get("entries") && (this.get("max")>0) &&
(LANG.isValue(request) || LANG.isNull(request) || LANG.isUndefined(request))) {
this.fire("add", {entry: {request:request, response:response, payload:payload}});
}
else {
}
},
/**
* Flushes cache.
*
* @method flush
*/
flush: function() {
this.fire("flush");
},
/**
* Retrieves cached entry for given request, if available, and refreshes
* entry in the cache. Returns null if there is no cache match.
*
* @method retrieve
* @param request {Object} Request object.
* @return {Object} Cached entry object with the properties request, response, and payload, or null.
*/
retrieve: function(request) {
// If cache is enabled...
var entries = this._entries,
length = entries.length,
entry = null,
i = length-1;
if((this.get("max") > 0) && (length > 0)) {
this.fire("request", {request: request});
// Loop through each cached entry starting from the newest
for(; i >= 0; i--) {
entry = entries[i];
// Execute matching function
if(this._isMatch(request, entry)) {
this.fire("retrieve", {entry: entry});
// Refresh the position of the cache hit
if(i < length-1) {
// Remove element from its original location
entries.splice(i,1);
// Add as newest
entries[entries.length] = entry;
}
return entry;
}
}
}
return null;
}
});
Y.Cache = Cache;
}, '3.1.1' ,{requires:['plugin']});

View file

@ -0,0 +1,91 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('classnamemanager', function(Y) {
/**
* Contains a singleton (ClassNameManager) that enables easy creation and caching of
* prefixed class names.
* @module classnamemanager
*/
/**
* A singleton class providing:
*
* <ul>
* <li>Easy creation of prefixed class names</li>
* <li>Caching of previously created class names for improved performance.</li>
* </ul>
*
* @class ClassNameManager
* @static
*/
// String constants
var CLASS_NAME_PREFIX = 'classNamePrefix',
CLASS_NAME_DELIMITER = 'classNameDelimiter',
CONFIG = Y.config;
// Global config
/**
* Configuration property indicating the prefix for all CSS class names in this YUI instance.
*
* @property Y.config.classNamePrefix
* @type {String}
* @default "yui"
* @static
*/
CONFIG[CLASS_NAME_PREFIX] = CONFIG[CLASS_NAME_PREFIX] || 'yui3';
/**
* Configuration property indicating the delimiter used to compose all CSS class names in
* this YUI instance.
*
* @property Y.config.classNameDelimiter
* @type {String}
* @default "-"
* @static
*/
CONFIG[CLASS_NAME_DELIMITER] = CONFIG[CLASS_NAME_DELIMITER] || '-';
Y.ClassNameManager = function () {
var sPrefix = CONFIG[CLASS_NAME_PREFIX],
sDelimiter = CONFIG[CLASS_NAME_DELIMITER];
return {
/**
* Returns a class name prefixed with the the value of the
* <code>Y.config.classNamePrefix</code> attribute + the provided strings.
* Uses the <code>Y.config.classNameDelimiter</code> attribute to delimit the
* provided strings. E.g. Y.ClassNameManager.getClassName('foo','bar'); // yui-foo-bar
*
* @method getClassName
* @param {String}+ classnameSection one or more classname sections to be joined
* @param {Boolean} skipPrefix If set to true, the classname will not be prefixed with the default Y.config.classNameDelimiter value.
*/
getClassName: Y.cached(function () {
var args = Y.Array(arguments);
if (args[args.length-1] !== true) {
args.unshift(sPrefix);
} else {
args.pop();
}
return args.join(sDelimiter);
})
};
}();
}, '3.1.1' );

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("classnamemanager",function(C){var B="classNamePrefix",D="classNameDelimiter",A=C.config;A[B]=A[B]||"yui3";A[D]=A[D]||"-";C.ClassNameManager=function(){var E=A[B],F=A[D];return{getClassName:C.cached(function(){var G=C.Array(arguments);if(G[G.length-1]!==true){G.unshift(E);}else{G.pop();}return G.join(F);})};}();},"3.1.1");

View file

@ -0,0 +1,91 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('classnamemanager', function(Y) {
/**
* Contains a singleton (ClassNameManager) that enables easy creation and caching of
* prefixed class names.
* @module classnamemanager
*/
/**
* A singleton class providing:
*
* <ul>
* <li>Easy creation of prefixed class names</li>
* <li>Caching of previously created class names for improved performance.</li>
* </ul>
*
* @class ClassNameManager
* @static
*/
// String constants
var CLASS_NAME_PREFIX = 'classNamePrefix',
CLASS_NAME_DELIMITER = 'classNameDelimiter',
CONFIG = Y.config;
// Global config
/**
* Configuration property indicating the prefix for all CSS class names in this YUI instance.
*
* @property Y.config.classNamePrefix
* @type {String}
* @default "yui"
* @static
*/
CONFIG[CLASS_NAME_PREFIX] = CONFIG[CLASS_NAME_PREFIX] || 'yui3';
/**
* Configuration property indicating the delimiter used to compose all CSS class names in
* this YUI instance.
*
* @property Y.config.classNameDelimiter
* @type {String}
* @default "-"
* @static
*/
CONFIG[CLASS_NAME_DELIMITER] = CONFIG[CLASS_NAME_DELIMITER] || '-';
Y.ClassNameManager = function () {
var sPrefix = CONFIG[CLASS_NAME_PREFIX],
sDelimiter = CONFIG[CLASS_NAME_DELIMITER];
return {
/**
* Returns a class name prefixed with the the value of the
* <code>Y.config.classNamePrefix</code> attribute + the provided strings.
* Uses the <code>Y.config.classNameDelimiter</code> attribute to delimit the
* provided strings. E.g. Y.ClassNameManager.getClassName('foo','bar'); // yui-foo-bar
*
* @method getClassName
* @param {String}+ classnameSection one or more classname sections to be joined
* @param {Boolean} skipPrefix If set to true, the classname will not be prefixed with the default Y.config.classNameDelimiter value.
*/
getClassName: Y.cached(function () {
var args = Y.Array(arguments);
if (args[args.length-1] !== true) {
args.unshift(sPrefix);
} else {
args.pop();
}
return args.join(sDelimiter);
})
};
}();
}, '3.1.1' );

View file

@ -0,0 +1,300 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('array-extras', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule array-extras
*/
var L = Y.Lang, Native = Array.prototype, A = Y.Array;
/**
* Adds the following array utilities to the YUI instance
* (Y.Array). This is in addition to the methods provided
* in the core.
* @class YUI~array~extras
*/
/**
* Returns the index of the last item in the array
* that contains the specified value, -1 if the
* value isn't found.
* @method Array.lastIndexOf
* @static
* @param a {Array} the array to search
* @param val the value to search for
* @return {int} the index of hte item that contains the value or -1
*/
A.lastIndexOf = (Native.lastIndexOf) ?
function(a ,val) {
return a.lastIndexOf(val);
} :
function(a, val) {
for (var i=a.length-1; i>=0; i=i-1) {
if (a[i] === val) {
break;
}
}
return i;
};
/**
* Returns a copy of the array with the duplicate entries removed
* @method Array.unique
* @static
* @param a {Array} the array to find the subset of uniques for
* @param sort {bool} flag to denote if the array is sorted or not. Defaults to false, the more general operation
* @return {Array} a copy of the array with duplicate entries removed
*/
A.unique = function(a, sort) {
var b = a.slice(), i = 0, n = -1, item = null;
while (i < b.length) {
item = b[i];
while ((n = A.lastIndexOf(b, item)) !== i) {
b.splice(n, 1);
}
i += 1;
}
// Note: the sort option doesn't really belong here... I think it was added
// because there was a way to fast path the two operations together. That
// implementation was not working, so I replaced it with the following.
// Leaving it in so that the API doesn't get broken.
if (sort) {
if (L.isNumber(b[0])) {
b.sort(A.numericSort);
} else {
b.sort();
}
}
return b;
};
/**
* Executes the supplied function on each item in the array.
* Returns a new array containing the items that the supplied
* function returned true for.
* @method Array.filter
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} The items on which the supplied function
* returned true. If no items matched an empty array is
* returned.
*/
A.filter = (Native.filter) ?
function(a, f, o) {
return Native.filter.call(a, f, o);
} :
function(a, f, o) {
var results = [];
A.each(a, function(item, i, a) {
if (f.call(o, item, i, a)) {
results.push(item);
}
});
return results;
};
/**
* The inverse of filter. Executes the supplied function on each item.
* Returns a new array containing the items that the supplied
* function returned *false* for.
* @method Array.reject
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} The items on which the supplied function
* returned false.
*/
A.reject = function(a, f, o) {
return A.filter(a, function(item, i, a) {
return !f.call(o, item, i, a);
});
};
/**
* Executes the supplied function on each item in the array.
* @method Array.every
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {boolean} true if every item in the array returns true
* from the supplied function.
*/
A.every = (Native.every) ?
function(a, f, o) {
return Native.every.call(a,f,o);
} :
function(a, f, o) {
for (var i = 0, l = a.length; i < l; i=i+1) {
if (!f.call(o, a[i], i, a)) {
return false;
}
}
return true;
};
/**
* Executes the supplied function on each item in the array.
* @method Array.map
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} A new array containing the return value
* of the supplied function for each item in the original
* array.
*/
A.map = (Native.map) ?
function(a, f, o) {
return Native.map.call(a, f, o);
} :
function(a, f, o) {
var results = [];
A.each(a, function(item, i, a) {
results.push(f.call(o, item, i, a));
});
return results;
};
/**
* Executes the supplied function on each item in the array.
* Reduce "folds" the array into a single value.
* @method Array.reduce
* @param a {Array} the array to iterate
* @param init The initial value to start from
* @param f {Function} the function to execute on each item. It
* is responsible for returning the updated value of the
* computation.
* @param o Optional context object
* @static
* @return A value that results from iteratively applying the
* supplied function to each element in the array.
*/
A.reduce = (Native.reduce) ?
function(a, init, f, o) {
//Firefox's Array.reduce does not allow inclusion of a
// thisObject, so we need to implement it manually
return Native.reduce.call(a, function(init, item, i, a) {
return f.call(o, init, item, i, a);
}, init);
} :
function(a, init, f, o) {
var r = init;
A.each(a, function (item, i, a) {
r = f.call(o, r, item, i, a);
});
return r;
};
/**
* Executes the supplied function on each item in the array,
* searching for the first item that matches the supplied
* function.
* @method Array.find
* @param a {Array} the array to search
* @param f {Function} the function to execute on each item.
* Iteration is stopped as soon as this function returns true
* on an item.
* @param o Optional context object
* @static
* @return {object} the first item that the supplied function
* returns true for, or null if it never returns true
*/
A.find = function(a, f, o) {
for(var i=0, l = a.length; i < l; i++) {
if (f.call(o, a[i], i, a)) {
return a[i];
}
}
return null;
};
/**
* Iterates over an array, returning a new array of all the elements
* that match the supplied regular expression
* @method Array.grep
* @param a {Array} a collection to iterate over
* @param pattern {RegExp} The regular expression to test against
* each item
* @static
* @return {Array} All the items in the collection that
* produce a match against the supplied regular expression.
* If no items match, an empty array is returned.
*/
A.grep = function (a, pattern) {
return A.filter(a, function (item, index) {
return pattern.test(item);
});
};
/**
* Partitions an array into two new arrays, one with the items
* that match the supplied function, and one with the items that
* do not.
* @method Array.partition
* @param a {Array} a collection to iterate over
* @paran f {Function} a function that will receive each item
* in the collection and its index.
* @param o Optional execution context of f.
* @static
* @return An object with two members, 'matches' and 'rejects',
* that are arrays containing the items that were selected or
* rejected by the test function (or an empty array).
*/
A.partition = function (a, f, o) {
var results = {
matches: [],
rejects: []
};
A.each(a, function (item, index) {
var set = f.call(o, item, index, a) ? results.matches : results.rejects;
set.push(item);
});
return results;
};
/**
* Creates an array of arrays by pairing the corresponding
* elements of two arrays together into a new array.
* @method Array.zip
* @param a {Array} a collection to iterate over
* @param a2 {Array} another collection whose members will be
* paired with members of the first parameter
* @static
* @return An array of arrays formed by pairing each element
* of the first collection with an item in the second collection
* having the corresponding index.
*/
A.zip = function (a, a2) {
var results = [];
A.each(a, function (item, index) {
results.push([item, a2[index]]);
});
return results;
};
A.forEach = A.each;
}, '3.1.1' );

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("array-extras",function(E){var C=E.Lang,D=Array.prototype,B=E.Array;B.lastIndexOf=(D.lastIndexOf)?function(A,F){return A.lastIndexOf(F);}:function(A,G){for(var F=A.length-1;F>=0;F=F-1){if(A[F]===G){break;}}return F;};B.unique=function(F,H){var A=F.slice(),G=0,J=-1,I=null;while(G<A.length){I=A[G];while((J=B.lastIndexOf(A,I))!==G){A.splice(J,1);}G+=1;}if(H){if(C.isNumber(A[0])){A.sort(B.numericSort);}else{A.sort();}}return A;};B.filter=(D.filter)?function(A,F,G){return D.filter.call(A,F,G);}:function(A,G,H){var F=[];B.each(A,function(K,J,I){if(G.call(H,K,J,I)){F.push(K);}});return F;};B.reject=function(A,F,G){return B.filter(A,function(J,I,H){return !F.call(G,J,I,H);});};B.every=(D.every)?function(A,F,G){return D.every.call(A,F,G);}:function(F,H,I){for(var G=0,A=F.length;G<A;G=G+1){if(!H.call(I,F[G],G,F)){return false;}}return true;};B.map=(D.map)?function(A,F,G){return D.map.call(A,F,G);}:function(A,G,H){var F=[];B.each(A,function(K,J,I){F.push(G.call(H,K,J,I));});return F;};B.reduce=(D.reduce)?function(A,H,F,G){return D.reduce.call(A,function(L,K,J,I){return F.call(G,L,K,J,I);},H);}:function(A,I,G,H){var F=I;B.each(A,function(L,K,J){F=G.call(H,F,L,K,J);});return F;};B.find=function(F,H,I){for(var G=0,A=F.length;G<A;G++){if(H.call(I,F[G],G,F)){return F[G];}}return null;};B.grep=function(A,F){return B.filter(A,function(H,G){return F.test(H);});};B.partition=function(A,G,H){var F={matches:[],rejects:[]};B.each(A,function(J,I){var K=G.call(H,J,I,A)?F.matches:F.rejects;K.push(J);});return F;};B.zip=function(F,A){var G=[];B.each(F,function(I,H){G.push([I,A[H]]);});return G;};B.forEach=B.each;},"3.1.1");

View file

@ -0,0 +1,300 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('array-extras', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule array-extras
*/
var L = Y.Lang, Native = Array.prototype, A = Y.Array;
/**
* Adds the following array utilities to the YUI instance
* (Y.Array). This is in addition to the methods provided
* in the core.
* @class YUI~array~extras
*/
/**
* Returns the index of the last item in the array
* that contains the specified value, -1 if the
* value isn't found.
* @method Array.lastIndexOf
* @static
* @param a {Array} the array to search
* @param val the value to search for
* @return {int} the index of hte item that contains the value or -1
*/
A.lastIndexOf = (Native.lastIndexOf) ?
function(a ,val) {
return a.lastIndexOf(val);
} :
function(a, val) {
for (var i=a.length-1; i>=0; i=i-1) {
if (a[i] === val) {
break;
}
}
return i;
};
/**
* Returns a copy of the array with the duplicate entries removed
* @method Array.unique
* @static
* @param a {Array} the array to find the subset of uniques for
* @param sort {bool} flag to denote if the array is sorted or not. Defaults to false, the more general operation
* @return {Array} a copy of the array with duplicate entries removed
*/
A.unique = function(a, sort) {
var b = a.slice(), i = 0, n = -1, item = null;
while (i < b.length) {
item = b[i];
while ((n = A.lastIndexOf(b, item)) !== i) {
b.splice(n, 1);
}
i += 1;
}
// Note: the sort option doesn't really belong here... I think it was added
// because there was a way to fast path the two operations together. That
// implementation was not working, so I replaced it with the following.
// Leaving it in so that the API doesn't get broken.
if (sort) {
if (L.isNumber(b[0])) {
b.sort(A.numericSort);
} else {
b.sort();
}
}
return b;
};
/**
* Executes the supplied function on each item in the array.
* Returns a new array containing the items that the supplied
* function returned true for.
* @method Array.filter
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} The items on which the supplied function
* returned true. If no items matched an empty array is
* returned.
*/
A.filter = (Native.filter) ?
function(a, f, o) {
return Native.filter.call(a, f, o);
} :
function(a, f, o) {
var results = [];
A.each(a, function(item, i, a) {
if (f.call(o, item, i, a)) {
results.push(item);
}
});
return results;
};
/**
* The inverse of filter. Executes the supplied function on each item.
* Returns a new array containing the items that the supplied
* function returned *false* for.
* @method Array.reject
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} The items on which the supplied function
* returned false.
*/
A.reject = function(a, f, o) {
return A.filter(a, function(item, i, a) {
return !f.call(o, item, i, a);
});
};
/**
* Executes the supplied function on each item in the array.
* @method Array.every
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {boolean} true if every item in the array returns true
* from the supplied function.
*/
A.every = (Native.every) ?
function(a, f, o) {
return Native.every.call(a,f,o);
} :
function(a, f, o) {
for (var i = 0, l = a.length; i < l; i=i+1) {
if (!f.call(o, a[i], i, a)) {
return false;
}
}
return true;
};
/**
* Executes the supplied function on each item in the array.
* @method Array.map
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} A new array containing the return value
* of the supplied function for each item in the original
* array.
*/
A.map = (Native.map) ?
function(a, f, o) {
return Native.map.call(a, f, o);
} :
function(a, f, o) {
var results = [];
A.each(a, function(item, i, a) {
results.push(f.call(o, item, i, a));
});
return results;
};
/**
* Executes the supplied function on each item in the array.
* Reduce "folds" the array into a single value.
* @method Array.reduce
* @param a {Array} the array to iterate
* @param init The initial value to start from
* @param f {Function} the function to execute on each item. It
* is responsible for returning the updated value of the
* computation.
* @param o Optional context object
* @static
* @return A value that results from iteratively applying the
* supplied function to each element in the array.
*/
A.reduce = (Native.reduce) ?
function(a, init, f, o) {
//Firefox's Array.reduce does not allow inclusion of a
// thisObject, so we need to implement it manually
return Native.reduce.call(a, function(init, item, i, a) {
return f.call(o, init, item, i, a);
}, init);
} :
function(a, init, f, o) {
var r = init;
A.each(a, function (item, i, a) {
r = f.call(o, r, item, i, a);
});
return r;
};
/**
* Executes the supplied function on each item in the array,
* searching for the first item that matches the supplied
* function.
* @method Array.find
* @param a {Array} the array to search
* @param f {Function} the function to execute on each item.
* Iteration is stopped as soon as this function returns true
* on an item.
* @param o Optional context object
* @static
* @return {object} the first item that the supplied function
* returns true for, or null if it never returns true
*/
A.find = function(a, f, o) {
for(var i=0, l = a.length; i < l; i++) {
if (f.call(o, a[i], i, a)) {
return a[i];
}
}
return null;
};
/**
* Iterates over an array, returning a new array of all the elements
* that match the supplied regular expression
* @method Array.grep
* @param a {Array} a collection to iterate over
* @param pattern {RegExp} The regular expression to test against
* each item
* @static
* @return {Array} All the items in the collection that
* produce a match against the supplied regular expression.
* If no items match, an empty array is returned.
*/
A.grep = function (a, pattern) {
return A.filter(a, function (item, index) {
return pattern.test(item);
});
};
/**
* Partitions an array into two new arrays, one with the items
* that match the supplied function, and one with the items that
* do not.
* @method Array.partition
* @param a {Array} a collection to iterate over
* @paran f {Function} a function that will receive each item
* in the collection and its index.
* @param o Optional execution context of f.
* @static
* @return An object with two members, 'matches' and 'rejects',
* that are arrays containing the items that were selected or
* rejected by the test function (or an empty array).
*/
A.partition = function (a, f, o) {
var results = {
matches: [],
rejects: []
};
A.each(a, function (item, index) {
var set = f.call(o, item, index, a) ? results.matches : results.rejects;
set.push(item);
});
return results;
};
/**
* Creates an array of arrays by pairing the corresponding
* elements of two arrays together into a new array.
* @method Array.zip
* @param a {Array} a collection to iterate over
* @param a2 {Array} another collection whose members will be
* paired with members of the first parameter
* @static
* @return An array of arrays formed by pairing each element
* of the first collection with an item in the second collection
* having the corresponding index.
*/
A.zip = function (a, a2) {
var results = [];
A.each(a, function (item, index) {
results.push([item, a2[index]]);
});
return results;
};
A.forEach = A.each;
}, '3.1.1' );

View file

@ -0,0 +1,51 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('array-invoke', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule array-invoke
*/
/**
* Adds the <code>Y.Array.invoke( items, methodName )</code> utility method.
* @class YUI~array~invoke
*/
/**
* <p>Execute a named method on an array of objects. Items in the list that do
* not have a function by that name will be skipped. For example,
* <code>Y.Array.invoke( arrayOfDrags, 'plug', Y.Plugin.DDProxy );</code></p>
*
* <p>The return values from each call are returned in an array.</p>
*
* @method invoke
* @static
* @param items { Array } Array of objects supporting the named method
* @param name { String } the name of the method to execute on each item
* @param args* { mixed } Any number of additional args are passed as
* parameters to the execution of the named method.
* @return { Array } All return values, indexed according to item index.
*/
Y.Array.invoke = function ( items, name ) {
var args = Y.Array( arguments, 2, true ),
isFunction = Y.Lang.isFunction,
ret = [];
Y.Array.each( Y.Array( items ), function ( item, i ) {
if ( isFunction( item[ name ] ) ) {
ret[i] = item[ name ].apply( item, args );
}
});
return ret;
};
}, '3.1.1' );

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("array-invoke",function(A){A.Array.invoke=function(B,E){var D=A.Array(arguments,2,true),F=A.Lang.isFunction,C=[];A.Array.each(A.Array(B),function(H,G){if(F(H[E])){C[G]=H[E].apply(H,D);}});return C;};},"3.1.1");

View file

@ -0,0 +1,51 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('array-invoke', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule array-invoke
*/
/**
* Adds the <code>Y.Array.invoke( items, methodName )</code> utility method.
* @class YUI~array~invoke
*/
/**
* <p>Execute a named method on an array of objects. Items in the list that do
* not have a function by that name will be skipped. For example,
* <code>Y.Array.invoke( arrayOfDrags, 'plug', Y.Plugin.DDProxy );</code></p>
*
* <p>The return values from each call are returned in an array.</p>
*
* @method invoke
* @static
* @param items { Array } Array of objects supporting the named method
* @param name { String } the name of the method to execute on each item
* @param args* { mixed } Any number of additional args are passed as
* parameters to the execution of the named method.
* @return { Array } All return values, indexed according to item index.
*/
Y.Array.invoke = function ( items, name ) {
var args = Y.Array( arguments, 2, true ),
isFunction = Y.Lang.isFunction,
ret = [];
Y.Array.each( Y.Array( items ), function ( item, i ) {
if ( isFunction( item[ name ] ) ) {
ret[i] = item[ name ].apply( item, args );
}
});
return ret;
};
}, '3.1.1' );

View file

@ -0,0 +1,88 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('arraylist-add', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist-add
*/
/**
* Adds methods add and remove to Y.ArrayList
* @class ArrayList~add
*/
Y.mix( Y.ArrayList.prototype, {
/**
* Add a single item to the ArrayList. Does not prevent duplicates.
*
* @method add
* @param item { mixed } Item presumably of the same type as others in the
* ArrayList
* @param index {Number} (Optional.) Number representing the position at
* which the item should be inserted.
* @return {ArrayList} the instance
* @chainable
*/
add: function ( item, index ) {
var items = this._items;
if (Y.Lang.isNumber(index)) {
items.splice(index, 0, item);
}
else {
items.push(item);
}
return this;
},
/**
* Removes first or all occurrences of an item to the ArrayList. If a
* comparitor is not provided, uses itemsAreEqual method to determine
* matches.
*
* @method remove
* @param needle { mixed } Item to find and remove from the list
* @param all { Boolean } If true, remove all occurrences
* @param comparitor { Function } optional a/b function to test equivalence
* @return {ArrayList} the instance
* @chainable
*/
remove: function ( needle, all, comparitor ) {
comparitor = comparitor || this.itemsAreEqual;
for (var i = this._items.length - 1; i >= 0; --i) {
if ( comparitor.call( this, needle, this.item( i ) ) ) {
this._items.splice( i, 1 );
if ( !all ) {
break;
}
}
}
return this;
},
/**
* Default comparitor for items stored in this list. Used by remove().
*
* @method itemsAreEqual
* @param a { mixed } item to test equivalence with
* @param b { mixed } other item to test equivalance
* @return { Boolean } true if items are deemed equivalent
*/
itemsAreEqual: function ( a, b ) {
return a === b;
}
} );
}, '3.1.1' ,{requires:['arraylist']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("arraylist-add",function(A){A.mix(A.ArrayList.prototype,{add:function(D,C){var B=this._items;if(A.Lang.isNumber(C)){B.splice(C,0,D);}else{B.push(D);}return this;},remove:function(D,C,E){E=E||this.itemsAreEqual;for(var B=this._items.length-1;B>=0;--B){if(E.call(this,D,this.item(B))){this._items.splice(B,1);if(!C){break;}}}return this;},itemsAreEqual:function(C,B){return C===B;}});},"3.1.1",{requires:["arraylist"]});

View file

@ -0,0 +1,88 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('arraylist-add', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist-add
*/
/**
* Adds methods add and remove to Y.ArrayList
* @class ArrayList~add
*/
Y.mix( Y.ArrayList.prototype, {
/**
* Add a single item to the ArrayList. Does not prevent duplicates.
*
* @method add
* @param item { mixed } Item presumably of the same type as others in the
* ArrayList
* @param index {Number} (Optional.) Number representing the position at
* which the item should be inserted.
* @return {ArrayList} the instance
* @chainable
*/
add: function ( item, index ) {
var items = this._items;
if (Y.Lang.isNumber(index)) {
items.splice(index, 0, item);
}
else {
items.push(item);
}
return this;
},
/**
* Removes first or all occurrences of an item to the ArrayList. If a
* comparitor is not provided, uses itemsAreEqual method to determine
* matches.
*
* @method remove
* @param needle { mixed } Item to find and remove from the list
* @param all { Boolean } If true, remove all occurrences
* @param comparitor { Function } optional a/b function to test equivalence
* @return {ArrayList} the instance
* @chainable
*/
remove: function ( needle, all, comparitor ) {
comparitor = comparitor || this.itemsAreEqual;
for (var i = this._items.length - 1; i >= 0; --i) {
if ( comparitor.call( this, needle, this.item( i ) ) ) {
this._items.splice( i, 1 );
if ( !all ) {
break;
}
}
}
return this;
},
/**
* Default comparitor for items stored in this list. Used by remove().
*
* @method itemsAreEqual
* @param a { mixed } item to test equivalence with
* @param b { mixed } other item to test equivalance
* @return { Boolean } true if items are deemed equivalent
*/
itemsAreEqual: function ( a, b ) {
return a === b;
}
} );
}, '3.1.1' ,{requires:['arraylist']});

View file

@ -0,0 +1,204 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('arraylist', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist
*/
var YArray = Y.Array,
YArray_each = YArray.each,
ArrayListProto;
/**
* Generic ArrayList class for managing lists of items and iterating operations
* over them. The targeted use for this class is for augmentation onto a
* class that is responsible for managing multiple instances of another class
* (e.g. NodeList for Nodes). The recommended use is to augment your class with
* ArrayList, then use ArrayList.addMethod to mirror the API of the constituent
* items on the list's API.
*
* The default implementation creates immutable lists, but mutability can be
* provided via the arraylist-add submodule or by implementing mutation methods
* directly on the augmented class's prototype.
*
* @class ArrayList
* @constructor
* @param items { Array } array of items this list will be responsible for
*/
function ArrayList( items ) {
if ( items !== undefined ) {
this._items = Y.Lang.isArray( items ) ? items : YArray( items );
} else {
// ||= to support lazy initialization from augment
this._items = this._items || [];
}
}
ArrayListProto = {
/**
* Get an item by index from the list. Override this method if managing a
* list of objects that have a different public representation (e.g. Node
* instances vs DOM nodes). The iteration methods that accept a user
* function will use this method for access list items for operation.
*
* @method item
* @param i { Integer } index to fetch
* @return { mixed } the item at the requested index
*/
item: function ( i ) {
return this._items[i];
},
/**
* <p>Execute a function on each item of the list, optionally providing a
* custom execution context. Default context is the item.</p>
*
* <p>The callback signature is <code>callback( item, index )</code>.</p>
*
* @method each
* @param fn { Function } the function to execute
* @param context { mixed } optional override 'this' in the function
* @return { ArrayList } this instance
* @chainable
*/
each: function ( fn, context ) {
YArray_each( this._items, function ( item, i ) {
item = this.item( i );
fn.call( context || item, item, i, this );
}, this);
return this;
},
/**
* <p>Execute a function on each item of the list, optionally providing a
* custom execution context. Default context is the item.</p>
*
* <p>The callback signature is <code>callback( item, index )</code>.</p>
*
* <p>Unlike <code>each</code>, if the callback returns true, the
* iteratation will stop.</p>
*
* @method some
* @param fn { Function } the function to execute
* @param context { mixed } optional override 'this' in the function
* @return { Boolean } True if the function returned true on an item
*/
some: function ( fn, context ) {
return YArray.some( this._items, function ( item, i ) {
item = this.item( i );
return fn.call( context || item, item, i, this );
}, this);
},
/**
* Finds the first index of the needle in the managed array of items.
*
* @method indexOf
* @param needle { mixed } The item to search for
* @return { Integer } Array index if found. Otherwise -1
*/
indexOf: function ( needle ) {
return YArray.indexOf( this._items, needle );
},
/**
* How many items are in this list?
*
* @method size
* @return { Integer } Number of items in the list
*/
size: function () {
return this._items.length;
},
/**
* Is this instance managing any items?
*
* @method isEmpty
* @return { Boolean } true if 1 or more items are being managed
*/
isEmpty: function () {
return !this.size();
}
};
// Default implementation does not distinguish between public and private
// item getter
/**
* Protected method for optimizations that may be appropriate for API
* mirroring. Similar in functionality to <code>item</code>, but is used by
* methods added with <code>ArrayList.addMethod()</code>.
*
* @method _item
* @protected
* @param i { Integer } Index of item to fetch
* @return { mixed } The item appropriate for pass through API methods
*/
ArrayListProto._item = ArrayListProto.item;
ArrayList.prototype = ArrayListProto;
Y.mix( ArrayList, {
/**
* <p>Adds a pass through method to dest (typically the prototype of a list
* class) that calls the named method on each item in the list with
* whatever parameters are passed in. Allows for API indirection via list
* instances.</p>
*
* <p>Accepts a single string name or an array of string names.</p>
*
* <pre><code>list.each( function ( item ) {
* item.methodName( 1, 2, 3 );
* } );
* // becomes
* list.methodName( 1, 2, 3 );</code></pre>
*
* <p>Additionally, the pass through methods use the item retrieved by the
* <code>_item</code> method in case there is any special behavior that is
* appropriate for API mirroring.</p>
*
* @method addMethod
* @static
* @param dest { Object } Object or prototype to receive the iterator method
* @param name { String | Array } Name of method of methods to create
*/
addMethod: function ( dest, names ) {
names = YArray( names );
YArray_each( names, function ( name ) {
dest[ name ] = function () {
var args = YArray( arguments, 0, true ),
ret = [];
YArray_each( this._items, function ( item, i ) {
item = this._item( i );
var result = item[ name ].apply( item, args );
if ( result !== undefined && result !== item ) {
ret.push( result );
}
}, this);
return ret.length ? ret : this;
};
} );
}
} );
Y.ArrayList = ArrayList;
}, '3.1.1' );

View file

@ -0,0 +1,50 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('arraylist-filter', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist-filter
*/
/**
* Adds filter method to ArrayList prototype
* @class ArrayList~filter
*/
Y.mix( Y.ArrayList.prototype, {
/**
* <p>Create a new ArrayList (or augmenting class instance) from a subset
* of items as determined by the boolean function passed as the
* argument. The original ArrayList is unchanged.</p>
*
* <p>The validator signature is <code>validator( item )</code>.</p>
*
* @method filter
* @param validator { Function } Boolean function to determine in or out
* @return { ArrayList } New instance based on who passed the validator
*/
filter: function ( validator ) {
var items = [];
Y.Array.each( this._items, function ( item, i ) {
item = this.item( i );
if ( validator( item ) ) {
items.push( item );
}
}, this);
return new this.constructor( items );
}
} );
}, '3.1.1' ,{requires:['arraylist']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("arraylist-filter",function(A){A.mix(A.ArrayList.prototype,{filter:function(C){var B=[];A.Array.each(this._items,function(E,D){E=this.item(D);if(C(E)){B.push(E);}},this);return new this.constructor(B);}});},"3.1.1",{requires:["arraylist"]});

View file

@ -0,0 +1,50 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('arraylist-filter', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist-filter
*/
/**
* Adds filter method to ArrayList prototype
* @class ArrayList~filter
*/
Y.mix( Y.ArrayList.prototype, {
/**
* <p>Create a new ArrayList (or augmenting class instance) from a subset
* of items as determined by the boolean function passed as the
* argument. The original ArrayList is unchanged.</p>
*
* <p>The validator signature is <code>validator( item )</code>.</p>
*
* @method filter
* @param validator { Function } Boolean function to determine in or out
* @return { ArrayList } New instance based on who passed the validator
*/
filter: function ( validator ) {
var items = [];
Y.Array.each( this._items, function ( item, i ) {
item = this.item( i );
if ( validator( item ) ) {
items.push( item );
}
}, this);
return new this.constructor( items );
}
} );
}, '3.1.1' ,{requires:['arraylist']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("arraylist",function(E){var D=E.Array,C=D.each,A;function B(F){if(F!==undefined){this._items=E.Lang.isArray(F)?F:D(F);}else{this._items=this._items||[];}}A={item:function(F){return this._items[F];},each:function(G,F){C(this._items,function(I,H){I=this.item(H);G.call(F||I,I,H,this);},this);return this;},some:function(G,F){return D.some(this._items,function(I,H){I=this.item(H);return G.call(F||I,I,H,this);},this);},indexOf:function(F){return D.indexOf(this._items,F);},size:function(){return this._items.length;},isEmpty:function(){return !this.size();}};A._item=A.item;B.prototype=A;E.mix(B,{addMethod:function(F,G){G=D(G);C(G,function(H){F[H]=function(){var J=D(arguments,0,true),I=[];C(this._items,function(M,L){M=this._item(L);var K=M[H].apply(M,J);if(K!==undefined&&K!==M){I.push(K);}},this);return I.length?I:this;};});}});E.ArrayList=B;},"3.1.1");

View file

@ -0,0 +1,204 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('arraylist', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist
*/
var YArray = Y.Array,
YArray_each = YArray.each,
ArrayListProto;
/**
* Generic ArrayList class for managing lists of items and iterating operations
* over them. The targeted use for this class is for augmentation onto a
* class that is responsible for managing multiple instances of another class
* (e.g. NodeList for Nodes). The recommended use is to augment your class with
* ArrayList, then use ArrayList.addMethod to mirror the API of the constituent
* items on the list's API.
*
* The default implementation creates immutable lists, but mutability can be
* provided via the arraylist-add submodule or by implementing mutation methods
* directly on the augmented class's prototype.
*
* @class ArrayList
* @constructor
* @param items { Array } array of items this list will be responsible for
*/
function ArrayList( items ) {
if ( items !== undefined ) {
this._items = Y.Lang.isArray( items ) ? items : YArray( items );
} else {
// ||= to support lazy initialization from augment
this._items = this._items || [];
}
}
ArrayListProto = {
/**
* Get an item by index from the list. Override this method if managing a
* list of objects that have a different public representation (e.g. Node
* instances vs DOM nodes). The iteration methods that accept a user
* function will use this method for access list items for operation.
*
* @method item
* @param i { Integer } index to fetch
* @return { mixed } the item at the requested index
*/
item: function ( i ) {
return this._items[i];
},
/**
* <p>Execute a function on each item of the list, optionally providing a
* custom execution context. Default context is the item.</p>
*
* <p>The callback signature is <code>callback( item, index )</code>.</p>
*
* @method each
* @param fn { Function } the function to execute
* @param context { mixed } optional override 'this' in the function
* @return { ArrayList } this instance
* @chainable
*/
each: function ( fn, context ) {
YArray_each( this._items, function ( item, i ) {
item = this.item( i );
fn.call( context || item, item, i, this );
}, this);
return this;
},
/**
* <p>Execute a function on each item of the list, optionally providing a
* custom execution context. Default context is the item.</p>
*
* <p>The callback signature is <code>callback( item, index )</code>.</p>
*
* <p>Unlike <code>each</code>, if the callback returns true, the
* iteratation will stop.</p>
*
* @method some
* @param fn { Function } the function to execute
* @param context { mixed } optional override 'this' in the function
* @return { Boolean } True if the function returned true on an item
*/
some: function ( fn, context ) {
return YArray.some( this._items, function ( item, i ) {
item = this.item( i );
return fn.call( context || item, item, i, this );
}, this);
},
/**
* Finds the first index of the needle in the managed array of items.
*
* @method indexOf
* @param needle { mixed } The item to search for
* @return { Integer } Array index if found. Otherwise -1
*/
indexOf: function ( needle ) {
return YArray.indexOf( this._items, needle );
},
/**
* How many items are in this list?
*
* @method size
* @return { Integer } Number of items in the list
*/
size: function () {
return this._items.length;
},
/**
* Is this instance managing any items?
*
* @method isEmpty
* @return { Boolean } true if 1 or more items are being managed
*/
isEmpty: function () {
return !this.size();
}
};
// Default implementation does not distinguish between public and private
// item getter
/**
* Protected method for optimizations that may be appropriate for API
* mirroring. Similar in functionality to <code>item</code>, but is used by
* methods added with <code>ArrayList.addMethod()</code>.
*
* @method _item
* @protected
* @param i { Integer } Index of item to fetch
* @return { mixed } The item appropriate for pass through API methods
*/
ArrayListProto._item = ArrayListProto.item;
ArrayList.prototype = ArrayListProto;
Y.mix( ArrayList, {
/**
* <p>Adds a pass through method to dest (typically the prototype of a list
* class) that calls the named method on each item in the list with
* whatever parameters are passed in. Allows for API indirection via list
* instances.</p>
*
* <p>Accepts a single string name or an array of string names.</p>
*
* <pre><code>list.each( function ( item ) {
* item.methodName( 1, 2, 3 );
* } );
* // becomes
* list.methodName( 1, 2, 3 );</code></pre>
*
* <p>Additionally, the pass through methods use the item retrieved by the
* <code>_item</code> method in case there is any special behavior that is
* appropriate for API mirroring.</p>
*
* @method addMethod
* @static
* @param dest { Object } Object or prototype to receive the iterator method
* @param name { String | Array } Name of method of methods to create
*/
addMethod: function ( dest, names ) {
names = YArray( names );
YArray_each( names, function ( name ) {
dest[ name ] = function () {
var args = YArray( arguments, 0, true ),
ret = [];
YArray_each( this._items, function ( item, i ) {
item = this._item( i );
var result = item[ name ].apply( item, args );
if ( result !== undefined && result !== item ) {
ret.push( result );
}
}, this);
return ret.length ? ret : this;
};
} );
}
} );
Y.ArrayList = ArrayList;
}, '3.1.1' );

View file

@ -0,0 +1,669 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('array-extras', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule array-extras
*/
var L = Y.Lang, Native = Array.prototype, A = Y.Array;
/**
* Adds the following array utilities to the YUI instance
* (Y.Array). This is in addition to the methods provided
* in the core.
* @class YUI~array~extras
*/
/**
* Returns the index of the last item in the array
* that contains the specified value, -1 if the
* value isn't found.
* @method Array.lastIndexOf
* @static
* @param a {Array} the array to search
* @param val the value to search for
* @return {int} the index of hte item that contains the value or -1
*/
A.lastIndexOf = (Native.lastIndexOf) ?
function(a ,val) {
return a.lastIndexOf(val);
} :
function(a, val) {
for (var i=a.length-1; i>=0; i=i-1) {
if (a[i] === val) {
break;
}
}
return i;
};
/**
* Returns a copy of the array with the duplicate entries removed
* @method Array.unique
* @static
* @param a {Array} the array to find the subset of uniques for
* @param sort {bool} flag to denote if the array is sorted or not. Defaults to false, the more general operation
* @return {Array} a copy of the array with duplicate entries removed
*/
A.unique = function(a, sort) {
var b = a.slice(), i = 0, n = -1, item = null;
while (i < b.length) {
item = b[i];
while ((n = A.lastIndexOf(b, item)) !== i) {
b.splice(n, 1);
}
i += 1;
}
// Note: the sort option doesn't really belong here... I think it was added
// because there was a way to fast path the two operations together. That
// implementation was not working, so I replaced it with the following.
// Leaving it in so that the API doesn't get broken.
if (sort) {
if (L.isNumber(b[0])) {
b.sort(A.numericSort);
} else {
b.sort();
}
}
return b;
};
/**
* Executes the supplied function on each item in the array.
* Returns a new array containing the items that the supplied
* function returned true for.
* @method Array.filter
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} The items on which the supplied function
* returned true. If no items matched an empty array is
* returned.
*/
A.filter = (Native.filter) ?
function(a, f, o) {
return Native.filter.call(a, f, o);
} :
function(a, f, o) {
var results = [];
A.each(a, function(item, i, a) {
if (f.call(o, item, i, a)) {
results.push(item);
}
});
return results;
};
/**
* The inverse of filter. Executes the supplied function on each item.
* Returns a new array containing the items that the supplied
* function returned *false* for.
* @method Array.reject
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} The items on which the supplied function
* returned false.
*/
A.reject = function(a, f, o) {
return A.filter(a, function(item, i, a) {
return !f.call(o, item, i, a);
});
};
/**
* Executes the supplied function on each item in the array.
* @method Array.every
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {boolean} true if every item in the array returns true
* from the supplied function.
*/
A.every = (Native.every) ?
function(a, f, o) {
return Native.every.call(a,f,o);
} :
function(a, f, o) {
for (var i = 0, l = a.length; i < l; i=i+1) {
if (!f.call(o, a[i], i, a)) {
return false;
}
}
return true;
};
/**
* Executes the supplied function on each item in the array.
* @method Array.map
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} A new array containing the return value
* of the supplied function for each item in the original
* array.
*/
A.map = (Native.map) ?
function(a, f, o) {
return Native.map.call(a, f, o);
} :
function(a, f, o) {
var results = [];
A.each(a, function(item, i, a) {
results.push(f.call(o, item, i, a));
});
return results;
};
/**
* Executes the supplied function on each item in the array.
* Reduce "folds" the array into a single value.
* @method Array.reduce
* @param a {Array} the array to iterate
* @param init The initial value to start from
* @param f {Function} the function to execute on each item. It
* is responsible for returning the updated value of the
* computation.
* @param o Optional context object
* @static
* @return A value that results from iteratively applying the
* supplied function to each element in the array.
*/
A.reduce = (Native.reduce) ?
function(a, init, f, o) {
//Firefox's Array.reduce does not allow inclusion of a
// thisObject, so we need to implement it manually
return Native.reduce.call(a, function(init, item, i, a) {
return f.call(o, init, item, i, a);
}, init);
} :
function(a, init, f, o) {
var r = init;
A.each(a, function (item, i, a) {
r = f.call(o, r, item, i, a);
});
return r;
};
/**
* Executes the supplied function on each item in the array,
* searching for the first item that matches the supplied
* function.
* @method Array.find
* @param a {Array} the array to search
* @param f {Function} the function to execute on each item.
* Iteration is stopped as soon as this function returns true
* on an item.
* @param o Optional context object
* @static
* @return {object} the first item that the supplied function
* returns true for, or null if it never returns true
*/
A.find = function(a, f, o) {
for(var i=0, l = a.length; i < l; i++) {
if (f.call(o, a[i], i, a)) {
return a[i];
}
}
return null;
};
/**
* Iterates over an array, returning a new array of all the elements
* that match the supplied regular expression
* @method Array.grep
* @param a {Array} a collection to iterate over
* @param pattern {RegExp} The regular expression to test against
* each item
* @static
* @return {Array} All the items in the collection that
* produce a match against the supplied regular expression.
* If no items match, an empty array is returned.
*/
A.grep = function (a, pattern) {
return A.filter(a, function (item, index) {
return pattern.test(item);
});
};
/**
* Partitions an array into two new arrays, one with the items
* that match the supplied function, and one with the items that
* do not.
* @method Array.partition
* @param a {Array} a collection to iterate over
* @paran f {Function} a function that will receive each item
* in the collection and its index.
* @param o Optional execution context of f.
* @static
* @return An object with two members, 'matches' and 'rejects',
* that are arrays containing the items that were selected or
* rejected by the test function (or an empty array).
*/
A.partition = function (a, f, o) {
var results = {
matches: [],
rejects: []
};
A.each(a, function (item, index) {
var set = f.call(o, item, index, a) ? results.matches : results.rejects;
set.push(item);
});
return results;
};
/**
* Creates an array of arrays by pairing the corresponding
* elements of two arrays together into a new array.
* @method Array.zip
* @param a {Array} a collection to iterate over
* @param a2 {Array} another collection whose members will be
* paired with members of the first parameter
* @static
* @return An array of arrays formed by pairing each element
* of the first collection with an item in the second collection
* having the corresponding index.
*/
A.zip = function (a, a2) {
var results = [];
A.each(a, function (item, index) {
results.push([item, a2[index]]);
});
return results;
};
A.forEach = A.each;
}, '3.1.1' );
YUI.add('arraylist', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist
*/
var YArray = Y.Array,
YArray_each = YArray.each,
ArrayListProto;
/**
* Generic ArrayList class for managing lists of items and iterating operations
* over them. The targeted use for this class is for augmentation onto a
* class that is responsible for managing multiple instances of another class
* (e.g. NodeList for Nodes). The recommended use is to augment your class with
* ArrayList, then use ArrayList.addMethod to mirror the API of the constituent
* items on the list's API.
*
* The default implementation creates immutable lists, but mutability can be
* provided via the arraylist-add submodule or by implementing mutation methods
* directly on the augmented class's prototype.
*
* @class ArrayList
* @constructor
* @param items { Array } array of items this list will be responsible for
*/
function ArrayList( items ) {
if ( items !== undefined ) {
this._items = Y.Lang.isArray( items ) ? items : YArray( items );
} else {
// ||= to support lazy initialization from augment
this._items = this._items || [];
}
}
ArrayListProto = {
/**
* Get an item by index from the list. Override this method if managing a
* list of objects that have a different public representation (e.g. Node
* instances vs DOM nodes). The iteration methods that accept a user
* function will use this method for access list items for operation.
*
* @method item
* @param i { Integer } index to fetch
* @return { mixed } the item at the requested index
*/
item: function ( i ) {
return this._items[i];
},
/**
* <p>Execute a function on each item of the list, optionally providing a
* custom execution context. Default context is the item.</p>
*
* <p>The callback signature is <code>callback( item, index )</code>.</p>
*
* @method each
* @param fn { Function } the function to execute
* @param context { mixed } optional override 'this' in the function
* @return { ArrayList } this instance
* @chainable
*/
each: function ( fn, context ) {
YArray_each( this._items, function ( item, i ) {
item = this.item( i );
fn.call( context || item, item, i, this );
}, this);
return this;
},
/**
* <p>Execute a function on each item of the list, optionally providing a
* custom execution context. Default context is the item.</p>
*
* <p>The callback signature is <code>callback( item, index )</code>.</p>
*
* <p>Unlike <code>each</code>, if the callback returns true, the
* iteratation will stop.</p>
*
* @method some
* @param fn { Function } the function to execute
* @param context { mixed } optional override 'this' in the function
* @return { Boolean } True if the function returned true on an item
*/
some: function ( fn, context ) {
return YArray.some( this._items, function ( item, i ) {
item = this.item( i );
return fn.call( context || item, item, i, this );
}, this);
},
/**
* Finds the first index of the needle in the managed array of items.
*
* @method indexOf
* @param needle { mixed } The item to search for
* @return { Integer } Array index if found. Otherwise -1
*/
indexOf: function ( needle ) {
return YArray.indexOf( this._items, needle );
},
/**
* How many items are in this list?
*
* @method size
* @return { Integer } Number of items in the list
*/
size: function () {
return this._items.length;
},
/**
* Is this instance managing any items?
*
* @method isEmpty
* @return { Boolean } true if 1 or more items are being managed
*/
isEmpty: function () {
return !this.size();
}
};
// Default implementation does not distinguish between public and private
// item getter
/**
* Protected method for optimizations that may be appropriate for API
* mirroring. Similar in functionality to <code>item</code>, but is used by
* methods added with <code>ArrayList.addMethod()</code>.
*
* @method _item
* @protected
* @param i { Integer } Index of item to fetch
* @return { mixed } The item appropriate for pass through API methods
*/
ArrayListProto._item = ArrayListProto.item;
ArrayList.prototype = ArrayListProto;
Y.mix( ArrayList, {
/**
* <p>Adds a pass through method to dest (typically the prototype of a list
* class) that calls the named method on each item in the list with
* whatever parameters are passed in. Allows for API indirection via list
* instances.</p>
*
* <p>Accepts a single string name or an array of string names.</p>
*
* <pre><code>list.each( function ( item ) {
* item.methodName( 1, 2, 3 );
* } );
* // becomes
* list.methodName( 1, 2, 3 );</code></pre>
*
* <p>Additionally, the pass through methods use the item retrieved by the
* <code>_item</code> method in case there is any special behavior that is
* appropriate for API mirroring.</p>
*
* @method addMethod
* @static
* @param dest { Object } Object or prototype to receive the iterator method
* @param name { String | Array } Name of method of methods to create
*/
addMethod: function ( dest, names ) {
names = YArray( names );
YArray_each( names, function ( name ) {
dest[ name ] = function () {
var args = YArray( arguments, 0, true ),
ret = [];
YArray_each( this._items, function ( item, i ) {
item = this._item( i );
var result = item[ name ].apply( item, args );
if ( result !== undefined && result !== item ) {
ret.push( result );
}
}, this);
return ret.length ? ret : this;
};
} );
}
} );
Y.ArrayList = ArrayList;
}, '3.1.1' );
YUI.add('arraylist-add', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist-add
*/
/**
* Adds methods add and remove to Y.ArrayList
* @class ArrayList~add
*/
Y.mix( Y.ArrayList.prototype, {
/**
* Add a single item to the ArrayList. Does not prevent duplicates.
*
* @method add
* @param item { mixed } Item presumably of the same type as others in the
* ArrayList
* @param index {Number} (Optional.) Number representing the position at
* which the item should be inserted.
* @return {ArrayList} the instance
* @chainable
*/
add: function ( item, index ) {
var items = this._items;
if (Y.Lang.isNumber(index)) {
items.splice(index, 0, item);
}
else {
items.push(item);
}
return this;
},
/**
* Removes first or all occurrences of an item to the ArrayList. If a
* comparitor is not provided, uses itemsAreEqual method to determine
* matches.
*
* @method remove
* @param needle { mixed } Item to find and remove from the list
* @param all { Boolean } If true, remove all occurrences
* @param comparitor { Function } optional a/b function to test equivalence
* @return {ArrayList} the instance
* @chainable
*/
remove: function ( needle, all, comparitor ) {
comparitor = comparitor || this.itemsAreEqual;
for (var i = this._items.length - 1; i >= 0; --i) {
if ( comparitor.call( this, needle, this.item( i ) ) ) {
this._items.splice( i, 1 );
if ( !all ) {
break;
}
}
}
return this;
},
/**
* Default comparitor for items stored in this list. Used by remove().
*
* @method itemsAreEqual
* @param a { mixed } item to test equivalence with
* @param b { mixed } other item to test equivalance
* @return { Boolean } true if items are deemed equivalent
*/
itemsAreEqual: function ( a, b ) {
return a === b;
}
} );
}, '3.1.1' ,{requires:['arraylist']});
YUI.add('arraylist-filter', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist-filter
*/
/**
* Adds filter method to ArrayList prototype
* @class ArrayList~filter
*/
Y.mix( Y.ArrayList.prototype, {
/**
* <p>Create a new ArrayList (or augmenting class instance) from a subset
* of items as determined by the boolean function passed as the
* argument. The original ArrayList is unchanged.</p>
*
* <p>The validator signature is <code>validator( item )</code>.</p>
*
* @method filter
* @param validator { Function } Boolean function to determine in or out
* @return { ArrayList } New instance based on who passed the validator
*/
filter: function ( validator ) {
var items = [];
Y.Array.each( this._items, function ( item, i ) {
item = this.item( i );
if ( validator( item ) ) {
items.push( item );
}
}, this);
return new this.constructor( items );
}
} );
}, '3.1.1' ,{requires:['arraylist']});
YUI.add('array-invoke', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule array-invoke
*/
/**
* Adds the <code>Y.Array.invoke( items, methodName )</code> utility method.
* @class YUI~array~invoke
*/
/**
* <p>Execute a named method on an array of objects. Items in the list that do
* not have a function by that name will be skipped. For example,
* <code>Y.Array.invoke( arrayOfDrags, 'plug', Y.Plugin.DDProxy );</code></p>
*
* <p>The return values from each call are returned in an array.</p>
*
* @method invoke
* @static
* @param items { Array } Array of objects supporting the named method
* @param name { String } the name of the method to execute on each item
* @param args* { mixed } Any number of additional args are passed as
* parameters to the execution of the named method.
* @return { Array } All return values, indexed according to item index.
*/
Y.Array.invoke = function ( items, name ) {
var args = Y.Array( arguments, 2, true ),
isFunction = Y.Lang.isFunction,
ret = [];
Y.Array.each( Y.Array( items ), function ( item, i ) {
if ( isFunction( item[ name ] ) ) {
ret[i] = item[ name ].apply( item, args );
}
});
return ret;
};
}, '3.1.1' );
YUI.add('collection', function(Y){}, '3.1.1' ,{use:['array-extras', 'arraylist', 'arraylist-add', 'arraylist-filter', 'array-invoke']});

View file

@ -0,0 +1,8 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add("array-extras",function(E){var C=E.Lang,D=Array.prototype,B=E.Array;B.lastIndexOf=(D.lastIndexOf)?function(A,F){return A.lastIndexOf(F);}:function(A,G){for(var F=A.length-1;F>=0;F=F-1){if(A[F]===G){break;}}return F;};B.unique=function(F,H){var A=F.slice(),G=0,J=-1,I=null;while(G<A.length){I=A[G];while((J=B.lastIndexOf(A,I))!==G){A.splice(J,1);}G+=1;}if(H){if(C.isNumber(A[0])){A.sort(B.numericSort);}else{A.sort();}}return A;};B.filter=(D.filter)?function(A,F,G){return D.filter.call(A,F,G);}:function(A,G,H){var F=[];B.each(A,function(K,J,I){if(G.call(H,K,J,I)){F.push(K);}});return F;};B.reject=function(A,F,G){return B.filter(A,function(J,I,H){return !F.call(G,J,I,H);});};B.every=(D.every)?function(A,F,G){return D.every.call(A,F,G);}:function(F,H,I){for(var G=0,A=F.length;G<A;G=G+1){if(!H.call(I,F[G],G,F)){return false;}}return true;};B.map=(D.map)?function(A,F,G){return D.map.call(A,F,G);}:function(A,G,H){var F=[];B.each(A,function(K,J,I){F.push(G.call(H,K,J,I));});return F;};B.reduce=(D.reduce)?function(A,H,F,G){return D.reduce.call(A,function(L,K,J,I){return F.call(G,L,K,J,I);},H);}:function(A,I,G,H){var F=I;B.each(A,function(L,K,J){F=G.call(H,F,L,K,J);});return F;};B.find=function(F,H,I){for(var G=0,A=F.length;G<A;G++){if(H.call(I,F[G],G,F)){return F[G];}}return null;};B.grep=function(A,F){return B.filter(A,function(H,G){return F.test(H);});};B.partition=function(A,G,H){var F={matches:[],rejects:[]};B.each(A,function(J,I){var K=G.call(H,J,I,A)?F.matches:F.rejects;K.push(J);});return F;};B.zip=function(F,A){var G=[];B.each(F,function(I,H){G.push([I,A[H]]);});return G;};B.forEach=B.each;},"3.1.1");YUI.add("arraylist",function(E){var D=E.Array,C=D.each,A;function B(F){if(F!==undefined){this._items=E.Lang.isArray(F)?F:D(F);}else{this._items=this._items||[];}}A={item:function(F){return this._items[F];},each:function(G,F){C(this._items,function(I,H){I=this.item(H);G.call(F||I,I,H,this);},this);return this;},some:function(G,F){return D.some(this._items,function(I,H){I=this.item(H);return G.call(F||I,I,H,this);},this);},indexOf:function(F){return D.indexOf(this._items,F);},size:function(){return this._items.length;},isEmpty:function(){return !this.size();}};A._item=A.item;B.prototype=A;E.mix(B,{addMethod:function(F,G){G=D(G);C(G,function(H){F[H]=function(){var J=D(arguments,0,true),I=[];C(this._items,function(M,L){M=this._item(L);var K=M[H].apply(M,J);if(K!==undefined&&K!==M){I.push(K);}},this);return I.length?I:this;};});}});E.ArrayList=B;},"3.1.1");YUI.add("arraylist-add",function(A){A.mix(A.ArrayList.prototype,{add:function(D,C){var B=this._items;if(A.Lang.isNumber(C)){B.splice(C,0,D);}else{B.push(D);}return this;},remove:function(D,C,E){E=E||this.itemsAreEqual;for(var B=this._items.length-1;B>=0;--B){if(E.call(this,D,this.item(B))){this._items.splice(B,1);if(!C){break;}}}return this;},itemsAreEqual:function(C,B){return C===B;}});},"3.1.1",{requires:["arraylist"]});YUI.add("arraylist-filter",function(A){A.mix(A.ArrayList.prototype,{filter:function(C){var B=[];A.Array.each(this._items,function(E,D){E=this.item(D);if(C(E)){B.push(E);}},this);return new this.constructor(B);}});},"3.1.1",{requires:["arraylist"]});YUI.add("array-invoke",function(A){A.Array.invoke=function(B,E){var D=A.Array(arguments,2,true),F=A.Lang.isFunction,C=[];A.Array.each(A.Array(B),function(H,G){if(F(H[E])){C[G]=H[E].apply(H,D);}});return C;};},"3.1.1");YUI.add("collection",function(A){},"3.1.1",{use:["array-extras","arraylist","arraylist-add","arraylist-filter","array-invoke"]});

View file

@ -0,0 +1,669 @@
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 3.1.1
build: 47
*/
YUI.add('array-extras', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule array-extras
*/
var L = Y.Lang, Native = Array.prototype, A = Y.Array;
/**
* Adds the following array utilities to the YUI instance
* (Y.Array). This is in addition to the methods provided
* in the core.
* @class YUI~array~extras
*/
/**
* Returns the index of the last item in the array
* that contains the specified value, -1 if the
* value isn't found.
* @method Array.lastIndexOf
* @static
* @param a {Array} the array to search
* @param val the value to search for
* @return {int} the index of hte item that contains the value or -1
*/
A.lastIndexOf = (Native.lastIndexOf) ?
function(a ,val) {
return a.lastIndexOf(val);
} :
function(a, val) {
for (var i=a.length-1; i>=0; i=i-1) {
if (a[i] === val) {
break;
}
}
return i;
};
/**
* Returns a copy of the array with the duplicate entries removed
* @method Array.unique
* @static
* @param a {Array} the array to find the subset of uniques for
* @param sort {bool} flag to denote if the array is sorted or not. Defaults to false, the more general operation
* @return {Array} a copy of the array with duplicate entries removed
*/
A.unique = function(a, sort) {
var b = a.slice(), i = 0, n = -1, item = null;
while (i < b.length) {
item = b[i];
while ((n = A.lastIndexOf(b, item)) !== i) {
b.splice(n, 1);
}
i += 1;
}
// Note: the sort option doesn't really belong here... I think it was added
// because there was a way to fast path the two operations together. That
// implementation was not working, so I replaced it with the following.
// Leaving it in so that the API doesn't get broken.
if (sort) {
if (L.isNumber(b[0])) {
b.sort(A.numericSort);
} else {
b.sort();
}
}
return b;
};
/**
* Executes the supplied function on each item in the array.
* Returns a new array containing the items that the supplied
* function returned true for.
* @method Array.filter
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} The items on which the supplied function
* returned true. If no items matched an empty array is
* returned.
*/
A.filter = (Native.filter) ?
function(a, f, o) {
return Native.filter.call(a, f, o);
} :
function(a, f, o) {
var results = [];
A.each(a, function(item, i, a) {
if (f.call(o, item, i, a)) {
results.push(item);
}
});
return results;
};
/**
* The inverse of filter. Executes the supplied function on each item.
* Returns a new array containing the items that the supplied
* function returned *false* for.
* @method Array.reject
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} The items on which the supplied function
* returned false.
*/
A.reject = function(a, f, o) {
return A.filter(a, function(item, i, a) {
return !f.call(o, item, i, a);
});
};
/**
* Executes the supplied function on each item in the array.
* @method Array.every
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {boolean} true if every item in the array returns true
* from the supplied function.
*/
A.every = (Native.every) ?
function(a, f, o) {
return Native.every.call(a,f,o);
} :
function(a, f, o) {
for (var i = 0, l = a.length; i < l; i=i+1) {
if (!f.call(o, a[i], i, a)) {
return false;
}
}
return true;
};
/**
* Executes the supplied function on each item in the array.
* @method Array.map
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} A new array containing the return value
* of the supplied function for each item in the original
* array.
*/
A.map = (Native.map) ?
function(a, f, o) {
return Native.map.call(a, f, o);
} :
function(a, f, o) {
var results = [];
A.each(a, function(item, i, a) {
results.push(f.call(o, item, i, a));
});
return results;
};
/**
* Executes the supplied function on each item in the array.
* Reduce "folds" the array into a single value.
* @method Array.reduce
* @param a {Array} the array to iterate
* @param init The initial value to start from
* @param f {Function} the function to execute on each item. It
* is responsible for returning the updated value of the
* computation.
* @param o Optional context object
* @static
* @return A value that results from iteratively applying the
* supplied function to each element in the array.
*/
A.reduce = (Native.reduce) ?
function(a, init, f, o) {
//Firefox's Array.reduce does not allow inclusion of a
// thisObject, so we need to implement it manually
return Native.reduce.call(a, function(init, item, i, a) {
return f.call(o, init, item, i, a);
}, init);
} :
function(a, init, f, o) {
var r = init;
A.each(a, function (item, i, a) {
r = f.call(o, r, item, i, a);
});
return r;
};
/**
* Executes the supplied function on each item in the array,
* searching for the first item that matches the supplied
* function.
* @method Array.find
* @param a {Array} the array to search
* @param f {Function} the function to execute on each item.
* Iteration is stopped as soon as this function returns true
* on an item.
* @param o Optional context object
* @static
* @return {object} the first item that the supplied function
* returns true for, or null if it never returns true
*/
A.find = function(a, f, o) {
for(var i=0, l = a.length; i < l; i++) {
if (f.call(o, a[i], i, a)) {
return a[i];
}
}
return null;
};
/**
* Iterates over an array, returning a new array of all the elements
* that match the supplied regular expression
* @method Array.grep
* @param a {Array} a collection to iterate over
* @param pattern {RegExp} The regular expression to test against
* each item
* @static
* @return {Array} All the items in the collection that
* produce a match against the supplied regular expression.
* If no items match, an empty array is returned.
*/
A.grep = function (a, pattern) {
return A.filter(a, function (item, index) {
return pattern.test(item);
});
};
/**
* Partitions an array into two new arrays, one with the items
* that match the supplied function, and one with the items that
* do not.
* @method Array.partition
* @param a {Array} a collection to iterate over
* @paran f {Function} a function that will receive each item
* in the collection and its index.
* @param o Optional execution context of f.
* @static
* @return An object with two members, 'matches' and 'rejects',
* that are arrays containing the items that were selected or
* rejected by the test function (or an empty array).
*/
A.partition = function (a, f, o) {
var results = {
matches: [],
rejects: []
};
A.each(a, function (item, index) {
var set = f.call(o, item, index, a) ? results.matches : results.rejects;
set.push(item);
});
return results;
};
/**
* Creates an array of arrays by pairing the corresponding
* elements of two arrays together into a new array.
* @method Array.zip
* @param a {Array} a collection to iterate over
* @param a2 {Array} another collection whose members will be
* paired with members of the first parameter
* @static
* @return An array of arrays formed by pairing each element
* of the first collection with an item in the second collection
* having the corresponding index.
*/
A.zip = function (a, a2) {
var results = [];
A.each(a, function (item, index) {
results.push([item, a2[index]]);
});
return results;
};
A.forEach = A.each;
}, '3.1.1' );
YUI.add('arraylist', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist
*/
var YArray = Y.Array,
YArray_each = YArray.each,
ArrayListProto;
/**
* Generic ArrayList class for managing lists of items and iterating operations
* over them. The targeted use for this class is for augmentation onto a
* class that is responsible for managing multiple instances of another class
* (e.g. NodeList for Nodes). The recommended use is to augment your class with
* ArrayList, then use ArrayList.addMethod to mirror the API of the constituent
* items on the list's API.
*
* The default implementation creates immutable lists, but mutability can be
* provided via the arraylist-add submodule or by implementing mutation methods
* directly on the augmented class's prototype.
*
* @class ArrayList
* @constructor
* @param items { Array } array of items this list will be responsible for
*/
function ArrayList( items ) {
if ( items !== undefined ) {
this._items = Y.Lang.isArray( items ) ? items : YArray( items );
} else {
// ||= to support lazy initialization from augment
this._items = this._items || [];
}
}
ArrayListProto = {
/**
* Get an item by index from the list. Override this method if managing a
* list of objects that have a different public representation (e.g. Node
* instances vs DOM nodes). The iteration methods that accept a user
* function will use this method for access list items for operation.
*
* @method item
* @param i { Integer } index to fetch
* @return { mixed } the item at the requested index
*/
item: function ( i ) {
return this._items[i];
},
/**
* <p>Execute a function on each item of the list, optionally providing a
* custom execution context. Default context is the item.</p>
*
* <p>The callback signature is <code>callback( item, index )</code>.</p>
*
* @method each
* @param fn { Function } the function to execute
* @param context { mixed } optional override 'this' in the function
* @return { ArrayList } this instance
* @chainable
*/
each: function ( fn, context ) {
YArray_each( this._items, function ( item, i ) {
item = this.item( i );
fn.call( context || item, item, i, this );
}, this);
return this;
},
/**
* <p>Execute a function on each item of the list, optionally providing a
* custom execution context. Default context is the item.</p>
*
* <p>The callback signature is <code>callback( item, index )</code>.</p>
*
* <p>Unlike <code>each</code>, if the callback returns true, the
* iteratation will stop.</p>
*
* @method some
* @param fn { Function } the function to execute
* @param context { mixed } optional override 'this' in the function
* @return { Boolean } True if the function returned true on an item
*/
some: function ( fn, context ) {
return YArray.some( this._items, function ( item, i ) {
item = this.item( i );
return fn.call( context || item, item, i, this );
}, this);
},
/**
* Finds the first index of the needle in the managed array of items.
*
* @method indexOf
* @param needle { mixed } The item to search for
* @return { Integer } Array index if found. Otherwise -1
*/
indexOf: function ( needle ) {
return YArray.indexOf( this._items, needle );
},
/**
* How many items are in this list?
*
* @method size
* @return { Integer } Number of items in the list
*/
size: function () {
return this._items.length;
},
/**
* Is this instance managing any items?
*
* @method isEmpty
* @return { Boolean } true if 1 or more items are being managed
*/
isEmpty: function () {
return !this.size();
}
};
// Default implementation does not distinguish between public and private
// item getter
/**
* Protected method for optimizations that may be appropriate for API
* mirroring. Similar in functionality to <code>item</code>, but is used by
* methods added with <code>ArrayList.addMethod()</code>.
*
* @method _item
* @protected
* @param i { Integer } Index of item to fetch
* @return { mixed } The item appropriate for pass through API methods
*/
ArrayListProto._item = ArrayListProto.item;
ArrayList.prototype = ArrayListProto;
Y.mix( ArrayList, {
/**
* <p>Adds a pass through method to dest (typically the prototype of a list
* class) that calls the named method on each item in the list with
* whatever parameters are passed in. Allows for API indirection via list
* instances.</p>
*
* <p>Accepts a single string name or an array of string names.</p>
*
* <pre><code>list.each( function ( item ) {
* item.methodName( 1, 2, 3 );
* } );
* // becomes
* list.methodName( 1, 2, 3 );</code></pre>
*
* <p>Additionally, the pass through methods use the item retrieved by the
* <code>_item</code> method in case there is any special behavior that is
* appropriate for API mirroring.</p>
*
* @method addMethod
* @static
* @param dest { Object } Object or prototype to receive the iterator method
* @param name { String | Array } Name of method of methods to create
*/
addMethod: function ( dest, names ) {
names = YArray( names );
YArray_each( names, function ( name ) {
dest[ name ] = function () {
var args = YArray( arguments, 0, true ),
ret = [];
YArray_each( this._items, function ( item, i ) {
item = this._item( i );
var result = item[ name ].apply( item, args );
if ( result !== undefined && result !== item ) {
ret.push( result );
}
}, this);
return ret.length ? ret : this;
};
} );
}
} );
Y.ArrayList = ArrayList;
}, '3.1.1' );
YUI.add('arraylist-add', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist-add
*/
/**
* Adds methods add and remove to Y.ArrayList
* @class ArrayList~add
*/
Y.mix( Y.ArrayList.prototype, {
/**
* Add a single item to the ArrayList. Does not prevent duplicates.
*
* @method add
* @param item { mixed } Item presumably of the same type as others in the
* ArrayList
* @param index {Number} (Optional.) Number representing the position at
* which the item should be inserted.
* @return {ArrayList} the instance
* @chainable
*/
add: function ( item, index ) {
var items = this._items;
if (Y.Lang.isNumber(index)) {
items.splice(index, 0, item);
}
else {
items.push(item);
}
return this;
},
/**
* Removes first or all occurrences of an item to the ArrayList. If a
* comparitor is not provided, uses itemsAreEqual method to determine
* matches.
*
* @method remove
* @param needle { mixed } Item to find and remove from the list
* @param all { Boolean } If true, remove all occurrences
* @param comparitor { Function } optional a/b function to test equivalence
* @return {ArrayList} the instance
* @chainable
*/
remove: function ( needle, all, comparitor ) {
comparitor = comparitor || this.itemsAreEqual;
for (var i = this._items.length - 1; i >= 0; --i) {
if ( comparitor.call( this, needle, this.item( i ) ) ) {
this._items.splice( i, 1 );
if ( !all ) {
break;
}
}
}
return this;
},
/**
* Default comparitor for items stored in this list. Used by remove().
*
* @method itemsAreEqual
* @param a { mixed } item to test equivalence with
* @param b { mixed } other item to test equivalance
* @return { Boolean } true if items are deemed equivalent
*/
itemsAreEqual: function ( a, b ) {
return a === b;
}
} );
}, '3.1.1' ,{requires:['arraylist']});
YUI.add('arraylist-filter', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist-filter
*/
/**
* Adds filter method to ArrayList prototype
* @class ArrayList~filter
*/
Y.mix( Y.ArrayList.prototype, {
/**
* <p>Create a new ArrayList (or augmenting class instance) from a subset
* of items as determined by the boolean function passed as the
* argument. The original ArrayList is unchanged.</p>
*
* <p>The validator signature is <code>validator( item )</code>.</p>
*
* @method filter
* @param validator { Function } Boolean function to determine in or out
* @return { ArrayList } New instance based on who passed the validator
*/
filter: function ( validator ) {
var items = [];
Y.Array.each( this._items, function ( item, i ) {
item = this.item( i );
if ( validator( item ) ) {
items.push( item );
}
}, this);
return new this.constructor( items );
}
} );
}, '3.1.1' ,{requires:['arraylist']});
YUI.add('array-invoke', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule array-invoke
*/
/**
* Adds the <code>Y.Array.invoke( items, methodName )</code> utility method.
* @class YUI~array~invoke
*/
/**
* <p>Execute a named method on an array of objects. Items in the list that do
* not have a function by that name will be skipped. For example,
* <code>Y.Array.invoke( arrayOfDrags, 'plug', Y.Plugin.DDProxy );</code></p>
*
* <p>The return values from each call are returned in an array.</p>
*
* @method invoke
* @static
* @param items { Array } Array of objects supporting the named method
* @param name { String } the name of the method to execute on each item
* @param args* { mixed } Any number of additional args are passed as
* parameters to the execution of the named method.
* @return { Array } All return values, indexed according to item index.
*/
Y.Array.invoke = function ( items, name ) {
var args = Y.Array( arguments, 2, true ),
isFunction = Y.Lang.isFunction,
ret = [];
Y.Array.each( Y.Array( items ), function ( item, i ) {
if ( isFunction( item[ name ] ) ) {
ret[i] = item[ name ].apply( item, args );
}
});
return ret;
};
}, '3.1.1' );
YUI.add('collection', function(Y){}, '3.1.1' ,{use:['array-extras', 'arraylist', 'arraylist-add', 'arraylist-filter', 'array-invoke']});

Some files were not shown because too many files have changed in this diff Show more