MDL-20796 importing yui 3.0.0
@@ -247,6 +247,7 @@ if (!isset($CFG->prefix)) { // Just in case it isn't defined in config.php
|
||||
|
||||
// exact version of currently used yui2 and 3 library
|
||||
$CFG->yui2version = '2.8.0r4';
|
||||
$CFG->yui3version = '3.0.0';
|
||||
|
||||
// Load up standard libraries
|
||||
require_once($CFG->libdir .'/textlib.class.php'); // Functions to handle multibyte strings
|
||||
|
||||
@@ -0,0 +1,603 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.get(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
|
||||
*/
|
||||
from: {},
|
||||
|
||||
/**
|
||||
* The ending values for the animated properties.
|
||||
* Fields may be strings, numbers, or functions.
|
||||
* @attribute to
|
||||
* @type Object
|
||||
*/
|
||||
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, 1);
|
||||
}
|
||||
};
|
||||
|
||||
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.
|
||||
* percent start time marker.
|
||||
* @method run
|
||||
* @chainable
|
||||
*/
|
||||
run: function() {
|
||||
if (!this.get(RUNNING)) {
|
||||
this._start();
|
||||
} else if (this.get(PAUSED)) {
|
||||
this._resume();
|
||||
}
|
||||
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) {
|
||||
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 attr = this._runtimeAttr,
|
||||
customAttr = Y.Anim.behaviors,
|
||||
easing = attr.easing,
|
||||
d = attr.duration,
|
||||
t = new Date() - this.get(START_TIME),
|
||||
reversed = this.get(REVERSE),
|
||||
done = (t >= d),
|
||||
lastFrame = d,
|
||||
attribute,
|
||||
setter;
|
||||
|
||||
if (reversed) {
|
||||
t = d - t;
|
||||
done = (t <= 0);
|
||||
lastFrame = 0;
|
||||
}
|
||||
|
||||
for (var 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 (!done) {
|
||||
setter(this, i, attribute.from, attribute.to, t, d, easing, attribute.unit);
|
||||
} else { // ensure final frame value is set
|
||||
// TODO: handle keyframes
|
||||
setter(this, i, attribute.from, attribute.to, lastFrame, d, easing, attribute.unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._actualFrames += 1;
|
||||
this._set(ELAPSED_TIME, t);
|
||||
|
||||
this.fire(TWEEN);
|
||||
if (done) {
|
||||
this._lastFrame();
|
||||
}
|
||||
},
|
||||
|
||||
_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') || {},
|
||||
dur = this.get('duration') * 1000,
|
||||
node = this.get(NODE),
|
||||
easing = this.get('easing') || {},
|
||||
attr = {},
|
||||
customAttr = Y.Anim.behaviors,
|
||||
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
|
||||
};
|
||||
|
||||
attr.duration = dur;
|
||||
attr.easing = easing;
|
||||
|
||||
}, 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.0.0' ,{requires:['base-base', 'node-style']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.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.get(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,1);}};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(C)){this._start();}else{if(this.get(K)){this._resume();}}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){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 X=this._runtimeAttr,S=B.Anim.behaviors,Y=X.easing,Z=X.duration,a=new Date()-this.get(N),W=this.get(P),U=(a>=Z),Q=Z,R,T;if(W){a=Z-a;U=(a<=0);Q=0;}for(var V in X){if(X[V].to){R=X[V];T=(V in S&&"set" in S[V])?S[V].set:B.Anim.DEFAULT_SETTER;if(!U){T(this,V,R.from,R.to,a,Z,Y,R.unit);}else{T(this,V,R.from,R.to,Q,Z,Y,R.unit);}}}this._actualFrames+=1;this._set(L,a);this.fire(I);if(U){this._lastFrame();}},_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")||{},Y=this.get("to")||{},Q=this.get("duration")*1000,T=this.get(D),W=this.get("easing")||{},V={},R=B.Anim.behaviors,Z,S,U;B.each(Y,function(d,b){if(typeof d==="function"){d=d.call(this,T);}S=X[b];if(S===undefined){S=(b in R&&"get" in R[b])?R[b].get(this,b):B.Anim.DEFAULT_GETTER(this,b);}else{if(typeof S==="function"){S=S.call(this,T);}}var a=B.Anim.RE_UNITS.exec(S);var c=B.Anim.RE_UNITS.exec(d);S=a?a[1]:S;U=c?c[1]:d;Z=c?c[2]:a?a[2]:"";if(!Z&&B.Anim.RE_DEFAULT_UNIT.test(b)){Z=B.Anim.DEFAULT_UNIT;}if(!S||!U){B.error('invalid "from" or "to" for "'+b+'"',"Anim");return;}V[b]={from:S,to:U,unit:Z};V.duration=Q;V.easing=W;},this);this._runtimeAttr=V;},_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.0.0",{requires:["base-base","node-style"]});
|
||||
@@ -0,0 +1,602 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.get(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
|
||||
*/
|
||||
from: {},
|
||||
|
||||
/**
|
||||
* The ending values for the animated properties.
|
||||
* Fields may be strings, numbers, or functions.
|
||||
* @attribute to
|
||||
* @type Object
|
||||
*/
|
||||
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, 1);
|
||||
}
|
||||
};
|
||||
|
||||
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.
|
||||
* percent start time marker.
|
||||
* @method run
|
||||
* @chainable
|
||||
*/
|
||||
run: function() {
|
||||
if (!this.get(RUNNING)) {
|
||||
this._start();
|
||||
} else if (this.get(PAUSED)) {
|
||||
this._resume();
|
||||
}
|
||||
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) {
|
||||
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 attr = this._runtimeAttr,
|
||||
customAttr = Y.Anim.behaviors,
|
||||
easing = attr.easing,
|
||||
d = attr.duration,
|
||||
t = new Date() - this.get(START_TIME),
|
||||
reversed = this.get(REVERSE),
|
||||
done = (t >= d),
|
||||
lastFrame = d,
|
||||
attribute,
|
||||
setter;
|
||||
|
||||
if (reversed) {
|
||||
t = d - t;
|
||||
done = (t <= 0);
|
||||
lastFrame = 0;
|
||||
}
|
||||
|
||||
for (var 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 (!done) {
|
||||
setter(this, i, attribute.from, attribute.to, t, d, easing, attribute.unit);
|
||||
} else { // ensure final frame value is set
|
||||
// TODO: handle keyframes
|
||||
setter(this, i, attribute.from, attribute.to, lastFrame, d, easing, attribute.unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._actualFrames += 1;
|
||||
this._set(ELAPSED_TIME, t);
|
||||
|
||||
this.fire(TWEEN);
|
||||
if (done) {
|
||||
this._lastFrame();
|
||||
}
|
||||
},
|
||||
|
||||
_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') || {},
|
||||
dur = this.get('duration') * 1000,
|
||||
node = this.get(NODE),
|
||||
easing = this.get('easing') || {},
|
||||
attr = {},
|
||||
customAttr = Y.Anim.behaviors,
|
||||
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
|
||||
};
|
||||
|
||||
attr.duration = dur;
|
||||
attr.easing = easing;
|
||||
|
||||
}, 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.0.0' ,{requires:['base-base', 'node-style']});
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['anim-base']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0",{requires:["anim-base"]});
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['anim-base']});
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['anim-xy']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0",{requires:["anim-xy"]});
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['anim-xy']});
|
||||
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['anim-base']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0",{requires:["anim-base"]});
|
||||
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['anim-base']});
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['node-pluginhost', 'anim-base']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0",{requires:["node-pluginhost","anim-base"]});
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['node-pluginhost', 'anim-base']});
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['anim-base']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0",{requires:["anim-base"]});
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['anim-base']});
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['anim-base', 'node-screen']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0",{requires:["anim-base","node-screen"]});
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['anim-base', 'node-screen']});
|
||||
|
After Width: | Height: | Size: 219 B |
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
.yui-skin-sam .yui-console-ft .yui-console-filters-categories,.yui-skin-sam .yui-console-ft .yui-console-filters-sources{text-align:left;padding:5px 0;border:1px inset;margin:0 2px;}.yui-skin-sam .yui-console-ft .yui-console-filters-categories{background:#fff;border-bottom:2px ridge;}.yui-skin-sam .yui-console-ft .yui-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;}.yui-skin-sam .yui-console-filter-label{white-space:nowrap;margin-left:1ex;}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
.yui-skin-sam .yui-separate-console{position:absolute;right:1em;top:1em;z-index:999;}.yui-skin-sam .yui-inline-console{display:-moz-inline-stack;display:inline-block;*display:inline;zoom:1;vertical-align:top;}.yui-skin-sam .yui-inline-console .yui-console-content{position:relative;}.yui-skin-sam .yui-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;}.yui-skin-sam .yui-console-hd,.yui-skin-sam .yui-console-bd,.yui-skin-sam .yui-console-ft{position:relative;}.yui-skin-sam .yui-console-hd,.yui-skin-sam .yui-console-ft .yui-console-controls{text-align:right;}.yui-skin-sam .yui-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;}.yui-skin-sam .yui-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%;}.yui-skin-sam .yui-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;}.yui-skin-sam .yui-console-controls{padding:4px 1ex;zoom:1;}.yui-skin-sam .yui-console-title{color:#000;display:inline;float:left;font-weight:bold;font-size:13px;height:24px;line-height:24px;margin:0;padding-left:1ex;}.yui-skin-sam .yui-console-pause-label{float:left;}.yui-skin-sam .yui-console-button{line-height:1.3;}.yui-skin-sam .yui-console-collapsed .yui-console-bd,.yui-skin-sam .yui-console-collapsed .yui-console-ft{display:none;}.yui-skin-sam .yui-console-content.yui-console-collapsed{-webkit-border-radius:0;}.yui-skin-sam .yui-console-collapsed .yui-console-hd{border-radius:10px;-moz-border-radius:10px;-webkit-border-radius:0;}.yui-skin-sam .yui-console-entry{border-bottom:1px solid #aaa;min-height:32px;_height:32px;}.yui-skin-sam .yui-console-entry-meta{margin:0;overflow:hidden;}.yui-skin-sam .yui-console-entry-content{margin:0;padding:0 1ex;white-space:pre-wrap;word-wrap:break-word;}.yui-skin-sam .yui-console-entry-meta .yui-console-entry-src{color:#000;font-style:italic;font-weight:bold;float:right;margin:2px 5px 0 0;}.yui-skin-sam .yui-console-entry-meta .yui-console-entry-time{color:#777;padding-left:1ex;}.yui-skin-sam .yui-console-entry-warn .yui-console-entry-meta .yui-console-entry-time{color:#555;}.yui-skin-sam .yui-console-entry-info .yui-console-entry-meta .yui-console-entry-cat,.yui-skin-sam .yui-console-entry-warn .yui-console-entry-meta .yui-console-entry-cat,.yui-skin-sam .yui-console-entry-error .yui-console-entry-meta .yui-console-entry-cat{display:none;}.yui-skin-sam .yui-console-entry-warn{background:#aee url(warn_error.png) no-repeat -15px 15px;}.yui-skin-sam .yui-console-entry-error{background:#ffa url(warn_error.png) no-repeat 5px -24px;color:#900;}.yui-skin-sam .yui-console-entry-warn .yui-console-entry-content,.yui-skin-sam .yui-console-entry-error .yui-console-entry-content{padding-left:24px;}.yui-skin-sam .yui-console-entry-cat{text-transform:uppercase;padding:1px 4px;background-color:#ccc;}.yui-skin-sam .yui-console-entry-info .yui-console-entry-cat{background-color:#ac2;}.yui-skin-sam .yui-console-entry-warn .yui-console-entry-cat{background-color:#e81;}.yui-skin-sam .yui-console-entry-error .yui-console-entry-cat{background-color:#b00;color:#fff;}.yui-skin-sam .yui-console-hidden{display:none;}
|
||||
|
After Width: | Height: | Size: 879 B |
|
After Width: | Height: | Size: 206 B |
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
.yui-menu .yui-menu{position:absolute;z-index:1;}.yui-menu .yui-shim{position:absolute;top:0;left:0;z-index:-1;opacity:0;filter:alpha(opacity=0);border:none;margin:0;padding:0;height:100%;width:100%;}.yui-menu-hidden{top:-10000px;left:-10000px;visibility:hidden;}.yui-menu li{list-style-type:none;}.yui-menu ul,.yui-menu li{margin:0;padding:0;}.yui-menu-label,.yui-menuitem-content{text-align:left;white-space:nowrap;display:block;}.yui-menu-horizontal li{float:left;width:auto;}.yui-menu-horizontal li li{float:none;}.yui-menu-horizontal ul{*zoom:1;}.yui-menu-horizontal ul ul{*zoom:normal;}.yui-menu-horizontal>.yui-menu-content>ul:after{content:"";display:block;clear:both;line-height:0;font-size:0;visibility:hidden;}.yui-menu-content{*zoom:1;}.yui-menu-hidden .yui-menu-content{*zoom:normal;}.yui-menuitem-content,.yui-menu-label{_zoom:1;}.yui-menu-hiden .yui-menuitem-content,.yui-menu-hiden .yui-menu-label{_zoom:normal;}.yui-skin-sam .yui-menu-content,.yui-skin-sam .yui-menu .yui-menu .yui-menu-content{font-size:93%;line-height:1.5;*line-height:1.45;border:solid 1px #808080;background:#fff;padding:3px 0;}.yui-skin-sam .yui-menu .yui-menu .yui-menu-content{font-size:100%;}.yui-skin-sam .yui-menu-horizontal .yui-menu-content{line-height:2;*line-height:1.9;background:url(sprite.png) repeat-x 0 0;padding:0;}.yui-skin-sam .yui-menu ul,.yui-skin-sam .yui-menu ul ul{margin-top:3px;padding-top:3px;border-top:solid 1px #ccc;}.yui-skin-sam .yui-menu ul.first-of-type{border:0;margin:0;padding:0;}.yui-skin-sam .yui-menu-horizontal ul{padding:0;margin:0;border:0;}.yui-skin-sam .yui-menu li,.yui-skin-sam .yui-menu .yui-menu li{_border-bottom:solid 1px #fff;}.yui-skin-sam .yui-menu-horizontal li{_border-bottom:0;}.yui-skin-sam .yui-menubuttonnav li{border-right:solid 1px #ccc;}.yui-skin-sam .yui-splitbuttonnav li{border-right:solid 1px #808080;}.yui-skin-sam .yui-menubuttonnav li li,.yui-skin-sam .yui-splitbuttonnav li li{border-right:0;}.yui-skin-sam .yui-menu-label,.yui-skin-sam .yui-menu .yui-menu .yui-menu-label,.yui-skin-sam .yui-menuitem-content,.yui-skin-sam .yui-menu .yui-menu .yui-menuitem-content{padding:0 20px;color:#000;text-decoration:none;cursor:default;float:none;border:0;margin:0;}.yui-skin-sam .yui-menu-horizontal .yui-menu-label,.yui-skin-sam .yui-menu-horizontal .yui-menuitem-content{padding:0 10px;border-style:solid;border-color:#808080;border-width:1px 0;margin:-1px 0;float:left;width:auto;}.yui-skin-sam .yui-menu-label,.yui-skin-sam .yui-menu .yui-menu .yui-menu-label{background:url(vertical-menu-submenu-indicator.png) right center no-repeat;}.yui-skin-sam .yui-menu-horizontal .yui-menu-label{background:url(sprite.png) repeat-x 0 0;}.yui-skin-sam .yui-menubuttonnav .yui-menu-label,.yui-skin-sam .yui-splitbuttonnav .yui-menu-label{background-image:none;}.yui-skin-sam .yui-menubuttonnav .yui-menu-label{padding-right:0;}.yui-skin-sam .yui-menubuttonnav .yui-menu-label em{font-style:normal;padding-right:20px;display:block;background:url(horizontal-menu-submenu-indicator.png) right center no-repeat;}.yui-skin-sam .yui-splitbuttonnav .yui-menu-label{padding:0;}.yui-skin-sam .yui-splitbuttonnav .yui-menu-label a{float:left;width:auto;color:#000;text-decoration:none;cursor:default;padding:0 5px 0 10px;}.yui-skin-sam .yui-splitbuttonnav .yui-menu-label .yui-menu-toggle{padding:0;border-left:solid 1px #ccc;width:15px;overflow:hidden;text-indent:-1000px;background:url(horizontal-menu-submenu-indicator.png) 3px center no-repeat;}.yui-skin-sam .yui-menu-label-active,.yui-skin-sam .yui-menu-label-menuvisible,.yui-skin-sam .yui-menu .yui-menu .yui-menu-label-active,.yui-skin-sam .yui-menu .yui-menu .yui-menu-label-menuvisible{background-color:#B3D4FF;}.yui-skin-sam .yui-menuitem-active .yui-menuitem-content,.yui-skin-sam .yui-menu .yui-menu .yui-menuitem-active .yui-menuitem-content{background-image:none;background-color:#B3D4FF;border-left-width:0;margin-left:0;}.yui-skin-sam .yui-menu-horizontal .yui-menu-label-active,.yui-skin-sam .yui-menu-horizontal .yui-menuitem-active .yui-menuitem-content,.yui-skin-sam .yui-menu-horizontal .yui-menu-label-menuvisible{border-color:#7D98B8;background:url(sprite.png) repeat-x 0 -1700px;}.yui-skin-sam .yui-menubuttonnav .yui-menu-label-active,.yui-skin-sam .yui-menubuttonnav .yui-menuitem-active .yui-menuitem-content,.yui-skin-sam .yui-menubuttonnav .yui-menu-label-menuvisible,.yui-skin-sam .yui-splitbuttonnav .yui-menu-label-active,.yui-skin-sam .yui-splitbuttonnav .yui-menuitem-active .yui-menuitem-content,.yui-skin-sam .yui-splitbuttonnav .yui-menu-label-menuvisible{border-left-width:1px;margin-left:-1px;}.yui-skin-sam .yui-splitbuttonnav .yui-menu-label-menuvisible{border-color:#808080;background:transparent;}.yui-skin-sam .yui-splitbuttonnav .yui-menu-label-menuvisible .yui-menu-toggle{border-color:#7D98B8;background:url(horizontal-menu-submenu-toggle.png) left center no-repeat;}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
.yui-overlay{position:absolute;}.yui-overlay-hidden{visibility:hidden;}
|
||||
|
After Width: | Height: | Size: 92 B |
|
After Width: | Height: | Size: 90 B |
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
.yui-skin-sam .yui-console-ft .yui-console-filters-categories,.yui-skin-sam .yui-console-ft .yui-console-filters-sources{text-align:left;padding:5px 0;border:1px inset;margin:0 2px;}.yui-skin-sam .yui-console-ft .yui-console-filters-categories{background:#fff;border-bottom:2px ridge;}.yui-skin-sam .yui-console-ft .yui-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;}.yui-skin-sam .yui-console-filter-label{white-space:nowrap;margin-left:1ex;}
|
||||
.yui-skin-sam .yui-separate-console{position:absolute;right:1em;top:1em;z-index:999;}.yui-skin-sam .yui-inline-console{display:-moz-inline-stack;display:inline-block;*display:inline;zoom:1;vertical-align:top;}.yui-skin-sam .yui-inline-console .yui-console-content{position:relative;}.yui-skin-sam .yui-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;}.yui-skin-sam .yui-console-hd,.yui-skin-sam .yui-console-bd,.yui-skin-sam .yui-console-ft{position:relative;}.yui-skin-sam .yui-console-hd,.yui-skin-sam .yui-console-ft .yui-console-controls{text-align:right;}.yui-skin-sam .yui-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;}.yui-skin-sam .yui-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%;}.yui-skin-sam .yui-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;}.yui-skin-sam .yui-console-controls{padding:4px 1ex;zoom:1;}.yui-skin-sam .yui-console-title{color:#000;display:inline;float:left;font-weight:bold;font-size:13px;height:24px;line-height:24px;margin:0;padding-left:1ex;}.yui-skin-sam .yui-console-pause-label{float:left;}.yui-skin-sam .yui-console-button{line-height:1.3;}.yui-skin-sam .yui-console-collapsed .yui-console-bd,.yui-skin-sam .yui-console-collapsed .yui-console-ft{display:none;}.yui-skin-sam .yui-console-content.yui-console-collapsed{-webkit-border-radius:0;}.yui-skin-sam .yui-console-collapsed .yui-console-hd{border-radius:10px;-moz-border-radius:10px;-webkit-border-radius:0;}.yui-skin-sam .yui-console-entry{border-bottom:1px solid #aaa;min-height:32px;_height:32px;}.yui-skin-sam .yui-console-entry-meta{margin:0;overflow:hidden;}.yui-skin-sam .yui-console-entry-content{margin:0;padding:0 1ex;white-space:pre-wrap;word-wrap:break-word;}.yui-skin-sam .yui-console-entry-meta .yui-console-entry-src{color:#000;font-style:italic;font-weight:bold;float:right;margin:2px 5px 0 0;}.yui-skin-sam .yui-console-entry-meta .yui-console-entry-time{color:#777;padding-left:1ex;}.yui-skin-sam .yui-console-entry-warn .yui-console-entry-meta .yui-console-entry-time{color:#555;}.yui-skin-sam .yui-console-entry-info .yui-console-entry-meta .yui-console-entry-cat,.yui-skin-sam .yui-console-entry-warn .yui-console-entry-meta .yui-console-entry-cat,.yui-skin-sam .yui-console-entry-error .yui-console-entry-meta .yui-console-entry-cat{display:none;}.yui-skin-sam .yui-console-entry-warn{background:#aee url(warn_error.png) no-repeat -15px 15px;}.yui-skin-sam .yui-console-entry-error{background:#ffa url(warn_error.png) no-repeat 5px -24px;color:#900;}.yui-skin-sam .yui-console-entry-warn .yui-console-entry-content,.yui-skin-sam .yui-console-entry-error .yui-console-entry-content{padding-left:24px;}.yui-skin-sam .yui-console-entry-cat{text-transform:uppercase;padding:1px 4px;background-color:#ccc;}.yui-skin-sam .yui-console-entry-info .yui-console-entry-cat{background-color:#ac2;}.yui-skin-sam .yui-console-entry-warn .yui-console-entry-cat{background-color:#e81;}.yui-skin-sam .yui-console-entry-error .yui-console-entry-cat{background-color:#b00;color:#fff;}.yui-skin-sam .yui-console-hidden{display:none;}
|
||||
.yui-menu .yui-menu{position:absolute;z-index:1;}.yui-menu .yui-shim{position:absolute;top:0;left:0;z-index:-1;opacity:0;filter:alpha(opacity=0);border:none;margin:0;padding:0;height:100%;width:100%;}.yui-menu-hidden{top:-10000px;left:-10000px;visibility:hidden;}.yui-menu li{list-style-type:none;}.yui-menu ul,.yui-menu li{margin:0;padding:0;}.yui-menu-label,.yui-menuitem-content{text-align:left;white-space:nowrap;display:block;}.yui-menu-horizontal li{float:left;width:auto;}.yui-menu-horizontal li li{float:none;}.yui-menu-horizontal ul{*zoom:1;}.yui-menu-horizontal ul ul{*zoom:normal;}.yui-menu-horizontal>.yui-menu-content>ul:after{content:"";display:block;clear:both;line-height:0;font-size:0;visibility:hidden;}.yui-menu-content{*zoom:1;}.yui-menu-hidden .yui-menu-content{*zoom:normal;}.yui-menuitem-content,.yui-menu-label{_zoom:1;}.yui-menu-hiden .yui-menuitem-content,.yui-menu-hiden .yui-menu-label{_zoom:normal;}.yui-skin-sam .yui-menu-content,.yui-skin-sam .yui-menu .yui-menu .yui-menu-content{font-size:93%;line-height:1.5;*line-height:1.45;border:solid 1px #808080;background:#fff;padding:3px 0;}.yui-skin-sam .yui-menu .yui-menu .yui-menu-content{font-size:100%;}.yui-skin-sam .yui-menu-horizontal .yui-menu-content{line-height:2;*line-height:1.9;background:url(sprite.png) repeat-x 0 0;padding:0;}.yui-skin-sam .yui-menu ul,.yui-skin-sam .yui-menu ul ul{margin-top:3px;padding-top:3px;border-top:solid 1px #ccc;}.yui-skin-sam .yui-menu ul.first-of-type{border:0;margin:0;padding:0;}.yui-skin-sam .yui-menu-horizontal ul{padding:0;margin:0;border:0;}.yui-skin-sam .yui-menu li,.yui-skin-sam .yui-menu .yui-menu li{_border-bottom:solid 1px #fff;}.yui-skin-sam .yui-menu-horizontal li{_border-bottom:0;}.yui-skin-sam .yui-menubuttonnav li{border-right:solid 1px #ccc;}.yui-skin-sam .yui-splitbuttonnav li{border-right:solid 1px #808080;}.yui-skin-sam .yui-menubuttonnav li li,.yui-skin-sam .yui-splitbuttonnav li li{border-right:0;}.yui-skin-sam .yui-menu-label,.yui-skin-sam .yui-menu .yui-menu .yui-menu-label,.yui-skin-sam .yui-menuitem-content,.yui-skin-sam .yui-menu .yui-menu .yui-menuitem-content{padding:0 20px;color:#000;text-decoration:none;cursor:default;float:none;border:0;margin:0;}.yui-skin-sam .yui-menu-horizontal .yui-menu-label,.yui-skin-sam .yui-menu-horizontal .yui-menuitem-content{padding:0 10px;border-style:solid;border-color:#808080;border-width:1px 0;margin:-1px 0;float:left;width:auto;}.yui-skin-sam .yui-menu-label,.yui-skin-sam .yui-menu .yui-menu .yui-menu-label{background:url(vertical-menu-submenu-indicator.png) right center no-repeat;}.yui-skin-sam .yui-menu-horizontal .yui-menu-label{background:url(sprite.png) repeat-x 0 0;}.yui-skin-sam .yui-menubuttonnav .yui-menu-label,.yui-skin-sam .yui-splitbuttonnav .yui-menu-label{background-image:none;}.yui-skin-sam .yui-menubuttonnav .yui-menu-label{padding-right:0;}.yui-skin-sam .yui-menubuttonnav .yui-menu-label em{font-style:normal;padding-right:20px;display:block;background:url(horizontal-menu-submenu-indicator.png) right center no-repeat;}.yui-skin-sam .yui-splitbuttonnav .yui-menu-label{padding:0;}.yui-skin-sam .yui-splitbuttonnav .yui-menu-label a{float:left;width:auto;color:#000;text-decoration:none;cursor:default;padding:0 5px 0 10px;}.yui-skin-sam .yui-splitbuttonnav .yui-menu-label .yui-menu-toggle{padding:0;border-left:solid 1px #ccc;width:15px;overflow:hidden;text-indent:-1000px;background:url(horizontal-menu-submenu-indicator.png) 3px center no-repeat;}.yui-skin-sam .yui-menu-label-active,.yui-skin-sam .yui-menu-label-menuvisible,.yui-skin-sam .yui-menu .yui-menu .yui-menu-label-active,.yui-skin-sam .yui-menu .yui-menu .yui-menu-label-menuvisible{background-color:#B3D4FF;}.yui-skin-sam .yui-menuitem-active .yui-menuitem-content,.yui-skin-sam .yui-menu .yui-menu .yui-menuitem-active .yui-menuitem-content{background-image:none;background-color:#B3D4FF;border-left-width:0;margin-left:0;}.yui-skin-sam .yui-menu-horizontal .yui-menu-label-active,.yui-skin-sam .yui-menu-horizontal .yui-menuitem-active .yui-menuitem-content,.yui-skin-sam .yui-menu-horizontal .yui-menu-label-menuvisible{border-color:#7D98B8;background:url(sprite.png) repeat-x 0 -1700px;}.yui-skin-sam .yui-menubuttonnav .yui-menu-label-active,.yui-skin-sam .yui-menubuttonnav .yui-menuitem-active .yui-menuitem-content,.yui-skin-sam .yui-menubuttonnav .yui-menu-label-menuvisible,.yui-skin-sam .yui-splitbuttonnav .yui-menu-label-active,.yui-skin-sam .yui-splitbuttonnav .yui-menuitem-active .yui-menuitem-content,.yui-skin-sam .yui-splitbuttonnav .yui-menu-label-menuvisible{border-left-width:1px;margin-left:-1px;}.yui-skin-sam .yui-splitbuttonnav .yui-menu-label-menuvisible{border-color:#808080;background:transparent;}.yui-skin-sam .yui-splitbuttonnav .yui-menu-label-menuvisible .yui-menu-toggle{border-color:#7D98B8;background:url(horizontal-menu-submenu-toggle.png) left center no-repeat;}
|
||||
.yui-overlay{position:absolute;}.yui-overlay-hidden{visibility:hidden;}
|
||||
.yui-slider{display:-moz-inline-stack;display:inline-block;*display:inline;zoom:1;vertical-align:middle;}.yui-slider-content{position:relative;}.yui-slider-rail{position:relative;}.yui-slider-thumb{position:absolute;}.yui-slider-thumb-image{display:block;}.yui-slider-image-error .yui-slider-thumb{height:10px;width:10px;background:#000;color:#000;overflow:hidden;}.yui-slider-image-error .yui-slider-thumb-image{display:none;}.yui-skin-sam .yui-slider-rail-x{background:url("rail-classic-x.png") repeat-x 0 7px;min-height:19px;*height:19px;}.yui-skin-sam .yui-slider-rail-y{background:url("rail-classic-y.png") repeat-y 7px 0;min-width:19px;*width:19px;}
|
||||
.yui-widget-stacked .yui-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;}
|
||||
.yui-widget-hidden{display:none;}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
.yui-slider{display:-moz-inline-stack;display:inline-block;*display:inline;zoom:1;vertical-align:middle;}.yui-slider-content{position:relative;}.yui-slider-rail{position:relative;}.yui-slider-thumb{position:absolute;}.yui-slider-thumb-image{display:block;}.yui-slider-image-error .yui-slider-thumb{height:10px;width:10px;background:#000;color:#000;overflow:hidden;}.yui-slider-image-error .yui-slider-thumb-image{display:none;}.yui-skin-sam .yui-slider-rail-x{background:url("rail-classic-x.png") repeat-x 0 7px;min-height:19px;*height:19px;}.yui-skin-sam .yui-slider-rail-y{background:url("rail-classic-y.png") repeat-y 7px 0;min-width:19px;*width:19px;}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 374 B |
|
After Width: | Height: | Size: 341 B |
|
After Width: | Height: | Size: 880 B |
|
After Width: | Height: | Size: 703 B |
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
.yui-widget-stacked .yui-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;}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
.yui-widget-hidden{display:none;}
|
||||
@@ -0,0 +1,536 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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 <= 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 },
|
||||
'shift' : { defaultFn : this._defShiftFn },
|
||||
'add' : { defaultFn : this._defAddFn },
|
||||
'promote' : { defaultFn : this._defPromoteFn },
|
||||
'remove' : { defaultFn : this._defRemoveFn }
|
||||
});
|
||||
*/
|
||||
this.publish('execute' , { defaultFn : this._defExecFn, emitFacade: true });
|
||||
this.publish('shift' , { defaultFn : this._defShiftFn, emitFacade: true });
|
||||
this.publish('add' , { defaultFn : this._defAddFn, emitFacade: true });
|
||||
this.publish('promote' , { defaultFn : this._defPromoteFn, emitFacade: true });
|
||||
this.publish('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 "shift" 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 "execute" 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 "add" 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 "promote" event. Promotes the
|
||||
* named callback to the head of the queue.</p>
|
||||
*
|
||||
* <p>The event object will contain a property "callback", 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 "remove" event. Removes the
|
||||
* callback from the queue.</p>
|
||||
*
|
||||
* <p>The event object will contain a property "callback", 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.0.0' ,{requires:['event-custom']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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});this.publish("shift",{defaultFn:this._defShiftFn,emitFacade:true});this.publish("add",{defaultFn:this._defAddFn,emitFacade:true});this.publish("promote",{defaultFn:this._defPromoteFn,emitFacade:true});this.publish("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.0.0",{requires:["event-custom"]});
|
||||
@@ -0,0 +1,536 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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 <= 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 },
|
||||
'shift' : { defaultFn : this._defShiftFn },
|
||||
'add' : { defaultFn : this._defAddFn },
|
||||
'promote' : { defaultFn : this._defPromoteFn },
|
||||
'remove' : { defaultFn : this._defRemoveFn }
|
||||
});
|
||||
*/
|
||||
this.publish('execute' , { defaultFn : this._defExecFn, emitFacade: true });
|
||||
this.publish('shift' , { defaultFn : this._defShiftFn, emitFacade: true });
|
||||
this.publish('add' , { defaultFn : this._defAddFn, emitFacade: true });
|
||||
this.publish('promote' , { defaultFn : this._defPromoteFn, emitFacade: true });
|
||||
this.publish('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 "shift" 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 "execute" 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 "add" 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 "promote" event. Promotes the
|
||||
* named callback to the head of the queue.</p>
|
||||
*
|
||||
* <p>The event object will contain a property "callback", 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 "remove" event. Removes the
|
||||
* callback from the queue.</p>
|
||||
*
|
||||
* <p>The event object will contain a property "callback", 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.0.0' ,{requires:['event-custom']});
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.valueFn) ? cfg.valueFn.call(this) : cfg.value,
|
||||
simple,
|
||||
complex,
|
||||
i,
|
||||
l,
|
||||
path,
|
||||
subval,
|
||||
subvals;
|
||||
|
||||
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.0.0' ,{requires:['attribute-base']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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,M){var E=(I.valueFn)?I.valueFn.call(this):I.value,D,F,H,G,N,L,J;if(!I.readOnly&&M){D=M.simple;if(D&&D.hasOwnProperty(K)){E=D[K];}F=M.complex;if(F&&F.hasOwnProperty(K)){J=F[K];for(H=0,G=J.length;H<G;++H){N=J[H].path;L=J[H].value;A.setValue(E,N,L);}}}return E;}};B.mix(B.Attribute,B.Attribute.Complex,true,null,1);},"3.0.0",{requires:["attribute-base"]});
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.valueFn) ? cfg.valueFn.call(this) : cfg.value,
|
||||
simple,
|
||||
complex,
|
||||
i,
|
||||
l,
|
||||
path,
|
||||
subval,
|
||||
subvals;
|
||||
|
||||
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.0.0' ,{requires:['attribute-base']});
|
||||
@@ -0,0 +1,536 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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 - An augmentable Plugin.Host interface which provides plugin support
|
||||
* (which is augmented to the Base class) and Base.build 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",
|
||||
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
|
||||
*/
|
||||
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; }
|
||||
|
||||
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');
|
||||
|
||||
/**
|
||||
* The string used to identify the class of this object.
|
||||
*
|
||||
* @deprecated Use this.constructor.NAME
|
||||
* @property name
|
||||
* @type String
|
||||
*/
|
||||
this._yuievt.config.prefix = this.name = this.constructor.NAME;
|
||||
|
||||
/**
|
||||
* <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,
|
||||
defaultFn:this._defInitFn
|
||||
});
|
||||
|
||||
if (config) {
|
||||
if (config.on) {
|
||||
this.on(config.on);
|
||||
}
|
||||
if (config.after) {
|
||||
this.after(config.after);
|
||||
}
|
||||
}
|
||||
|
||||
this.fire(INIT, {cfg: config});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* <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,
|
||||
defaultFn: this._defDestroyFn
|
||||
});
|
||||
this.fire(DESTROY);
|
||||
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 && !constr._yuibuild.dynamic) {
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
// Fix constructor
|
||||
Base.prototype.constructor = Base;
|
||||
|
||||
|
||||
}, '3.0.0' ,{requires:['attribute-base']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add("base-base",function(B){var H=B.Object,J=B.Lang,I=".",F="destroy",P="init",N="initialized",G="destroyed",D="initializer",C=Object.prototype.constructor,K="deep",Q="shallow",M="destructor",A=B.Attribute;function E(){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.init.apply(this,arguments);}E._ATTR_CFG=A._ATTR_CFG.concat("cloneDefaultValue");E.NAME="base";E.ATTRS={initialized:{readOnly:true,value:false},destroyed:{readOnly:true,value:false}};E.prototype={init:function(L){this._yuievt.config.prefix=this.name=this.constructor.NAME;this.publish(P,{queuable:false,defaultFn:this._defInitFn});if(L){if(L.on){this.on(L.on);}if(L.after){this.after(L.after);}}this.fire(P,{cfg:L});return this;},destroy:function(){this.publish(F,{queuable:false,defaultFn:this._defDestroyFn});this.fire(F);return this;},_defInitFn:function(L){this._initHierarchy(L.cfg);if(this._initPlugins){this._initPlugins(L.cfg);}this._set(N,true);},_defDestroyFn:function(L){this._destroyHierarchy();if(this._destroyPlugins){this._destroyPlugins();}this._set(G,true);},_getClasses:function(){if(!this._classes){this._initHierarchyData();}return this._classes;},_getAttrCfgs:function(){if(!this._attrs){this._initHierarchyData();}return this._attrs;},_filterAttrCfgs:function(T,O){var R=null,L,S=T.ATTRS;if(S){for(L in S){if(S.hasOwnProperty(L)&&O[L]){R=R||{};R[L]=O[L];delete O[L];}}}return R;},_initHierarchyData:function(){var R=this.constructor,O=[],L=[];while(R){O[O.length]=R;if(R.ATTRS){L[L.length]=R.ATTRS;}R=R.superclass?R.superclass.constructor:null;}this._classes=O;this._attrs=this._aggregateAttrs(L);},_aggregateAttrs:function(W){var T,X,S,L,Y,O,V,R=E._ATTR_CFG,U={};if(W){for(O=W.length-1;O>=0;--O){X=W[O];for(T in X){if(X.hasOwnProperty(T)){S=B.mix({},X[T],true,R);L=S.value;V=S.cloneDefaultValue;if(L){if((V===undefined&&(C===L.constructor||J.isArray(L)))||V===K||V===true){S.value=B.clone(L);}else{if(V===Q){S.value=B.merge(L);}}}Y=null;if(T.indexOf(I)!==-1){Y=T.split(I);T=Y.shift();}if(Y&&U[T]&&U[T].value){H.setValue(U[T].value,Y,L);}else{if(!Y){if(!U[T]){U[T]=S;}else{B.mix(U[T],S,true,R);}}}}}}}return U;},_initHierarchy:function(U){var R=this._lazyAddAttrs,V,W,X,S,O,T=this._getClasses(),L=this._getAttrCfgs();for(X=T.length-1;X>=0;X--){V=T[X];W=V.prototype;if(V._yuibuild&&V._yuibuild.exts&&!V._yuibuild.dynamic){for(S=0,O=V._yuibuild.exts.length;S<O;S++){V._yuibuild.exts[S].apply(this,arguments);}}this.addAttrs(this._filterAttrCfgs(V,L),U,R);if(W.hasOwnProperty(D)){W.initializer.apply(this,arguments);}}},_destroyHierarchy:function(){var T,O,S,L,R=this._getClasses();for(S=0,L=R.length;S<L;S++){T=R[S];O=T.prototype;if(O.hasOwnProperty(M)){O.destructor.apply(this,arguments);}}},toString:function(){return this.constructor.NAME+"["+B.stamp(this)+"]";}};B.mix(E,A,false,null,1);E.prototype.constructor=E;B.Base=E;E.prototype.constructor=E;},"3.0.0",{requires:["attribute-base"]});
|
||||
@@ -0,0 +1,531 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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 - An augmentable Plugin.Host interface which provides plugin support
|
||||
* (which is augmented to the Base class) and Base.build 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",
|
||||
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
|
||||
*/
|
||||
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; }
|
||||
|
||||
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) {
|
||||
|
||||
/**
|
||||
* The string used to identify the class of this object.
|
||||
*
|
||||
* @deprecated Use this.constructor.NAME
|
||||
* @property name
|
||||
* @type String
|
||||
*/
|
||||
this._yuievt.config.prefix = this.name = this.constructor.NAME;
|
||||
|
||||
/**
|
||||
* <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,
|
||||
defaultFn:this._defInitFn
|
||||
});
|
||||
|
||||
if (config) {
|
||||
if (config.on) {
|
||||
this.on(config.on);
|
||||
}
|
||||
if (config.after) {
|
||||
this.after(config.after);
|
||||
}
|
||||
}
|
||||
|
||||
this.fire(INIT, {cfg: config});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* <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,
|
||||
defaultFn: this._defDestroyFn
|
||||
});
|
||||
this.fire(DESTROY);
|
||||
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 && !constr._yuibuild.dynamic) {
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
// Fix constructor
|
||||
Base.prototype.constructor = Base;
|
||||
|
||||
|
||||
}, '3.0.0' ,{requires:['attribute-base']});
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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 = {
|
||||
aggregates : ["ATTRS", "_PLUG", "_UNPLUG"]
|
||||
};
|
||||
|
||||
/**
|
||||
* <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 <boolean></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 <String[]></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) {
|
||||
|
||||
var build = Base.build,
|
||||
builtClass = build._getClass(main, cfg),
|
||||
aggregates = build._getAggregates(main, cfg),
|
||||
dynamic = builtClass._yuibuild.dynamic,
|
||||
i, l, val, extClass;
|
||||
|
||||
// Shallow isolate aggregates
|
||||
if (dynamic) {
|
||||
if (aggregates) {
|
||||
for (i = 0, l = aggregates.length; i < l; ++i) {
|
||||
val = aggregates[i];
|
||||
if (main.hasOwnProperty(val)) {
|
||||
builtClass[val] = L.isArray(main[val]) ? [] : {};
|
||||
}
|
||||
}
|
||||
Y.aggregate(builtClass, main, true, aggregates);
|
||||
}
|
||||
}
|
||||
|
||||
// Augment/Aggregate
|
||||
for (i = 0, l = extensions.length; i < l; i++) {
|
||||
extClass = extensions[i];
|
||||
|
||||
if (aggregates) {
|
||||
Y.aggregate(builtClass, extClass, true, aggregates);
|
||||
}
|
||||
|
||||
// Old augment
|
||||
Y.mix(builtClass, extClass, true, null, 1);
|
||||
|
||||
builtClass._yuibuild.exts.push(extClass);
|
||||
}
|
||||
|
||||
builtClass.prototype.hasImpl = build._hasImpl;
|
||||
|
||||
if (dynamic) {
|
||||
builtClass.NAME = name;
|
||||
builtClass.prototype.constructor = builtClass;
|
||||
}
|
||||
|
||||
return builtClass;
|
||||
};
|
||||
|
||||
Y.mix(Base.build, {
|
||||
|
||||
_template: function(main) {
|
||||
|
||||
function BuiltClass() {
|
||||
|
||||
BuiltClass.superclass.constructor.apply(this, arguments);
|
||||
|
||||
var f = BuiltClass._yuibuild.exts,
|
||||
l = f.length,
|
||||
i;
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
f[i].apply(this, arguments);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
Y.extend(BuiltClass, main);
|
||||
|
||||
return BuiltClass;
|
||||
},
|
||||
|
||||
_hasImpl : function(extClass) {
|
||||
var classes = this._getClasses();
|
||||
for (var i = 0, l = classes.length; i < l; i++) {
|
||||
var cls = classes[i];
|
||||
|
||||
if (cls._yuibuild) {
|
||||
var exts = cls._yuibuild.exts,
|
||||
ll = exts.length,
|
||||
j;
|
||||
|
||||
for (j = 0; j < ll; j++) {
|
||||
if (exts[j] === extClass) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_getClass : function(main, cfg) {
|
||||
|
||||
var dynamic = (cfg && false === cfg.dynamic) ? false : true,
|
||||
builtClass = (dynamic) ? Base.build._template(main) : main;
|
||||
|
||||
builtClass._yuibuild = {
|
||||
id: null,
|
||||
exts : [],
|
||||
dynamic : dynamic
|
||||
};
|
||||
|
||||
return builtClass;
|
||||
},
|
||||
|
||||
_getAggregates : function(main, cfg) {
|
||||
var aggr = [],
|
||||
cfgAggr = (cfg && cfg.aggregates),
|
||||
c = main,
|
||||
classAggr;
|
||||
|
||||
while (c && c.prototype) {
|
||||
classAggr = c._buildCfg && c._buildCfg.aggregates;
|
||||
if (classAggr) {
|
||||
aggr = aggr.concat(classAggr);
|
||||
}
|
||||
c = c.superclass ? c.superclass.constructor : null;
|
||||
}
|
||||
|
||||
if (cfgAggr) {
|
||||
aggr = aggr.concat(cfgAggr);
|
||||
}
|
||||
|
||||
return aggr;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}, '3.0.0' ,{requires:['base-base']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add("base-build",function(C){var B=C.Base,A=C.Lang;B._buildCfg={aggregates:["ATTRS","_PLUG","_UNPLUG"]};B.build=function(D,I,M,L){var O=B.build,E=O._getClass(I,L),K=O._getAggregates(I,L),G=E._yuibuild.dynamic,J,H,F,N;if(G){if(K){for(J=0,H=K.length;J<H;++J){F=K[J];if(I.hasOwnProperty(F)){E[F]=A.isArray(I[F])?[]:{};}}C.aggregate(E,I,true,K);}}for(J=0,H=M.length;J<H;J++){N=M[J];if(K){C.aggregate(E,N,true,K);}C.mix(E,N,true,null,1);E._yuibuild.exts.push(N);}E.prototype.hasImpl=O._hasImpl;if(G){E.NAME=D;E.prototype.constructor=E;}return E;};C.mix(B.build,{_template:function(D){function E(){E.superclass.constructor.apply(this,arguments);var H=E._yuibuild.exts,F=H.length,G;for(G=0;G<F;G++){H[G].apply(this,arguments);}return this;}C.extend(E,D);return E;},_hasImpl:function(G){var J=this._getClasses();for(var I=0,E=J.length;I<E;I++){var D=J[I];if(D._yuibuild){var H=D._yuibuild.exts,K=H.length,F;for(F=0;F<K;F++){if(H[F]===G){return true;}}}}return false;},_getClass:function(D,E){var F=(E&&false===E.dynamic)?false:true,G=(F)?B.build._template(D):D;G._yuibuild={id:null,exts:[],dynamic:F};return G;},_getAggregates:function(D,E){var F=[],H=(E&&E.aggregates),I=D,G;while(I&&I.prototype){G=I._buildCfg&&I._buildCfg.aggregates;if(G){F=F.concat(G);}I=I.superclass?I.superclass.constructor:null;}if(H){F=F.concat(H);}return F;}});},"3.0.0",{requires:["base-base"]});
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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 = {
|
||||
aggregates : ["ATTRS", "_PLUG", "_UNPLUG"]
|
||||
};
|
||||
|
||||
/**
|
||||
* <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 <boolean></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 <String[]></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) {
|
||||
|
||||
var build = Base.build,
|
||||
builtClass = build._getClass(main, cfg),
|
||||
aggregates = build._getAggregates(main, cfg),
|
||||
dynamic = builtClass._yuibuild.dynamic,
|
||||
i, l, val, extClass;
|
||||
|
||||
// Shallow isolate aggregates
|
||||
if (dynamic) {
|
||||
if (aggregates) {
|
||||
for (i = 0, l = aggregates.length; i < l; ++i) {
|
||||
val = aggregates[i];
|
||||
if (main.hasOwnProperty(val)) {
|
||||
builtClass[val] = L.isArray(main[val]) ? [] : {};
|
||||
}
|
||||
}
|
||||
Y.aggregate(builtClass, main, true, aggregates);
|
||||
}
|
||||
}
|
||||
|
||||
// Augment/Aggregate
|
||||
for (i = 0, l = extensions.length; i < l; i++) {
|
||||
extClass = extensions[i];
|
||||
|
||||
if (aggregates) {
|
||||
Y.aggregate(builtClass, extClass, true, aggregates);
|
||||
}
|
||||
|
||||
// Old augment
|
||||
Y.mix(builtClass, extClass, true, null, 1);
|
||||
|
||||
builtClass._yuibuild.exts.push(extClass);
|
||||
}
|
||||
|
||||
builtClass.prototype.hasImpl = build._hasImpl;
|
||||
|
||||
if (dynamic) {
|
||||
builtClass.NAME = name;
|
||||
builtClass.prototype.constructor = builtClass;
|
||||
}
|
||||
|
||||
return builtClass;
|
||||
};
|
||||
|
||||
Y.mix(Base.build, {
|
||||
|
||||
_template: function(main) {
|
||||
|
||||
function BuiltClass() {
|
||||
|
||||
BuiltClass.superclass.constructor.apply(this, arguments);
|
||||
|
||||
var f = BuiltClass._yuibuild.exts,
|
||||
l = f.length,
|
||||
i;
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
f[i].apply(this, arguments);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
Y.extend(BuiltClass, main);
|
||||
|
||||
return BuiltClass;
|
||||
},
|
||||
|
||||
_hasImpl : function(extClass) {
|
||||
var classes = this._getClasses();
|
||||
for (var i = 0, l = classes.length; i < l; i++) {
|
||||
var cls = classes[i];
|
||||
|
||||
if (cls._yuibuild) {
|
||||
var exts = cls._yuibuild.exts,
|
||||
ll = exts.length,
|
||||
j;
|
||||
|
||||
for (j = 0; j < ll; j++) {
|
||||
if (exts[j] === extClass) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_getClass : function(main, cfg) {
|
||||
|
||||
var dynamic = (cfg && false === cfg.dynamic) ? false : true,
|
||||
builtClass = (dynamic) ? Base.build._template(main) : main;
|
||||
|
||||
builtClass._yuibuild = {
|
||||
id: null,
|
||||
exts : [],
|
||||
dynamic : dynamic
|
||||
};
|
||||
|
||||
return builtClass;
|
||||
},
|
||||
|
||||
_getAggregates : function(main, cfg) {
|
||||
var aggr = [],
|
||||
cfgAggr = (cfg && cfg.aggregates),
|
||||
c = main,
|
||||
classAggr;
|
||||
|
||||
while (c && c.prototype) {
|
||||
classAggr = c._buildCfg && c._buildCfg.aggregates;
|
||||
if (classAggr) {
|
||||
aggr = aggr.concat(classAggr);
|
||||
}
|
||||
c = c.superclass ? c.superclass.constructor : null;
|
||||
}
|
||||
|
||||
if (cfgAggr) {
|
||||
aggr = aggr.concat(cfgAggr);
|
||||
}
|
||||
|
||||
return aggr;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}, '3.0.0' ,{requires:['base-base']});
|
||||
@@ -0,0 +1,770 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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 - An augmentable Plugin.Host interface which provides plugin support
|
||||
* (which is augmented to the Base class) and Base.build 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",
|
||||
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
|
||||
*/
|
||||
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; }
|
||||
|
||||
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');
|
||||
|
||||
/**
|
||||
* The string used to identify the class of this object.
|
||||
*
|
||||
* @deprecated Use this.constructor.NAME
|
||||
* @property name
|
||||
* @type String
|
||||
*/
|
||||
this._yuievt.config.prefix = this.name = this.constructor.NAME;
|
||||
|
||||
/**
|
||||
* <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,
|
||||
defaultFn:this._defInitFn
|
||||
});
|
||||
|
||||
if (config) {
|
||||
if (config.on) {
|
||||
this.on(config.on);
|
||||
}
|
||||
if (config.after) {
|
||||
this.after(config.after);
|
||||
}
|
||||
}
|
||||
|
||||
this.fire(INIT, {cfg: config});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* <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,
|
||||
defaultFn: this._defDestroyFn
|
||||
});
|
||||
this.fire(DESTROY);
|
||||
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 && !constr._yuibuild.dynamic) {
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
// Fix constructor
|
||||
Base.prototype.constructor = Base;
|
||||
|
||||
|
||||
}, '3.0.0' ,{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.0.0' ,{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;
|
||||
|
||||
/**
|
||||
* 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 = {
|
||||
aggregates : ["ATTRS", "_PLUG", "_UNPLUG"]
|
||||
};
|
||||
|
||||
/**
|
||||
* <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 <boolean></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 <String[]></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) {
|
||||
|
||||
var build = Base.build,
|
||||
builtClass = build._getClass(main, cfg),
|
||||
aggregates = build._getAggregates(main, cfg),
|
||||
dynamic = builtClass._yuibuild.dynamic,
|
||||
i, l, val, extClass;
|
||||
|
||||
// Shallow isolate aggregates
|
||||
if (dynamic) {
|
||||
if (aggregates) {
|
||||
for (i = 0, l = aggregates.length; i < l; ++i) {
|
||||
val = aggregates[i];
|
||||
if (main.hasOwnProperty(val)) {
|
||||
builtClass[val] = L.isArray(main[val]) ? [] : {};
|
||||
}
|
||||
}
|
||||
Y.aggregate(builtClass, main, true, aggregates);
|
||||
}
|
||||
}
|
||||
|
||||
// Augment/Aggregate
|
||||
for (i = 0, l = extensions.length; i < l; i++) {
|
||||
extClass = extensions[i];
|
||||
|
||||
if (aggregates) {
|
||||
Y.aggregate(builtClass, extClass, true, aggregates);
|
||||
}
|
||||
|
||||
// Old augment
|
||||
Y.mix(builtClass, extClass, true, null, 1);
|
||||
|
||||
builtClass._yuibuild.exts.push(extClass);
|
||||
}
|
||||
|
||||
builtClass.prototype.hasImpl = build._hasImpl;
|
||||
|
||||
if (dynamic) {
|
||||
builtClass.NAME = name;
|
||||
builtClass.prototype.constructor = builtClass;
|
||||
}
|
||||
|
||||
return builtClass;
|
||||
};
|
||||
|
||||
Y.mix(Base.build, {
|
||||
|
||||
_template: function(main) {
|
||||
|
||||
function BuiltClass() {
|
||||
|
||||
BuiltClass.superclass.constructor.apply(this, arguments);
|
||||
|
||||
var f = BuiltClass._yuibuild.exts,
|
||||
l = f.length,
|
||||
i;
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
f[i].apply(this, arguments);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
Y.extend(BuiltClass, main);
|
||||
|
||||
return BuiltClass;
|
||||
},
|
||||
|
||||
_hasImpl : function(extClass) {
|
||||
var classes = this._getClasses();
|
||||
for (var i = 0, l = classes.length; i < l; i++) {
|
||||
var cls = classes[i];
|
||||
|
||||
if (cls._yuibuild) {
|
||||
var exts = cls._yuibuild.exts,
|
||||
ll = exts.length,
|
||||
j;
|
||||
|
||||
for (j = 0; j < ll; j++) {
|
||||
if (exts[j] === extClass) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_getClass : function(main, cfg) {
|
||||
|
||||
var dynamic = (cfg && false === cfg.dynamic) ? false : true,
|
||||
builtClass = (dynamic) ? Base.build._template(main) : main;
|
||||
|
||||
builtClass._yuibuild = {
|
||||
id: null,
|
||||
exts : [],
|
||||
dynamic : dynamic
|
||||
};
|
||||
|
||||
return builtClass;
|
||||
},
|
||||
|
||||
_getAggregates : function(main, cfg) {
|
||||
var aggr = [],
|
||||
cfgAggr = (cfg && cfg.aggregates),
|
||||
c = main,
|
||||
classAggr;
|
||||
|
||||
while (c && c.prototype) {
|
||||
classAggr = c._buildCfg && c._buildCfg.aggregates;
|
||||
if (classAggr) {
|
||||
aggr = aggr.concat(classAggr);
|
||||
}
|
||||
c = c.superclass ? c.superclass.constructor : null;
|
||||
}
|
||||
|
||||
if (cfgAggr) {
|
||||
aggr = aggr.concat(cfgAggr);
|
||||
}
|
||||
|
||||
return aggr;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}, '3.0.0' ,{requires:['base-base']});
|
||||
|
||||
|
||||
YUI.add('base', function(Y){}, '3.0.0' ,{use:['base-base', 'base-pluginhost', 'base-build']});
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add("base-base",function(B){var H=B.Object,J=B.Lang,I=".",F="destroy",P="init",N="initialized",G="destroyed",D="initializer",C=Object.prototype.constructor,K="deep",Q="shallow",M="destructor",A=B.Attribute;function E(){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.init.apply(this,arguments);}E._ATTR_CFG=A._ATTR_CFG.concat("cloneDefaultValue");E.NAME="base";E.ATTRS={initialized:{readOnly:true,value:false},destroyed:{readOnly:true,value:false}};E.prototype={init:function(L){this._yuievt.config.prefix=this.name=this.constructor.NAME;this.publish(P,{queuable:false,defaultFn:this._defInitFn});if(L){if(L.on){this.on(L.on);}if(L.after){this.after(L.after);}}this.fire(P,{cfg:L});return this;},destroy:function(){this.publish(F,{queuable:false,defaultFn:this._defDestroyFn});this.fire(F);return this;},_defInitFn:function(L){this._initHierarchy(L.cfg);if(this._initPlugins){this._initPlugins(L.cfg);}this._set(N,true);},_defDestroyFn:function(L){this._destroyHierarchy();if(this._destroyPlugins){this._destroyPlugins();}this._set(G,true);},_getClasses:function(){if(!this._classes){this._initHierarchyData();}return this._classes;},_getAttrCfgs:function(){if(!this._attrs){this._initHierarchyData();}return this._attrs;},_filterAttrCfgs:function(T,O){var R=null,L,S=T.ATTRS;if(S){for(L in S){if(S.hasOwnProperty(L)&&O[L]){R=R||{};R[L]=O[L];delete O[L];}}}return R;},_initHierarchyData:function(){var R=this.constructor,O=[],L=[];while(R){O[O.length]=R;if(R.ATTRS){L[L.length]=R.ATTRS;}R=R.superclass?R.superclass.constructor:null;}this._classes=O;this._attrs=this._aggregateAttrs(L);},_aggregateAttrs:function(W){var T,X,S,L,Y,O,V,R=E._ATTR_CFG,U={};if(W){for(O=W.length-1;O>=0;--O){X=W[O];for(T in X){if(X.hasOwnProperty(T)){S=B.mix({},X[T],true,R);L=S.value;V=S.cloneDefaultValue;if(L){if((V===undefined&&(C===L.constructor||J.isArray(L)))||V===K||V===true){S.value=B.clone(L);}else{if(V===Q){S.value=B.merge(L);}}}Y=null;if(T.indexOf(I)!==-1){Y=T.split(I);T=Y.shift();}if(Y&&U[T]&&U[T].value){H.setValue(U[T].value,Y,L);}else{if(!Y){if(!U[T]){U[T]=S;}else{B.mix(U[T],S,true,R);}}}}}}}return U;},_initHierarchy:function(U){var R=this._lazyAddAttrs,V,W,X,S,O,T=this._getClasses(),L=this._getAttrCfgs();for(X=T.length-1;X>=0;X--){V=T[X];W=V.prototype;if(V._yuibuild&&V._yuibuild.exts&&!V._yuibuild.dynamic){for(S=0,O=V._yuibuild.exts.length;S<O;S++){V._yuibuild.exts[S].apply(this,arguments);}}this.addAttrs(this._filterAttrCfgs(V,L),U,R);if(W.hasOwnProperty(D)){W.initializer.apply(this,arguments);}}},_destroyHierarchy:function(){var T,O,S,L,R=this._getClasses();for(S=0,L=R.length;S<L;S++){T=R[S];O=T.prototype;if(O.hasOwnProperty(M)){O.destructor.apply(this,arguments);}}},toString:function(){return this.constructor.NAME+"["+B.stamp(this)+"]";}};B.mix(E,A,false,null,1);E.prototype.constructor=E;B.Base=E;E.prototype.constructor=E;},"3.0.0",{requires:["attribute-base"]});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.0.0",{requires:["base-base","pluginhost"]});YUI.add("base-build",function(C){var B=C.Base,A=C.Lang;B._buildCfg={aggregates:["ATTRS","_PLUG","_UNPLUG"]};B.build=function(D,I,M,L){var O=B.build,E=O._getClass(I,L),K=O._getAggregates(I,L),G=E._yuibuild.dynamic,J,H,F,N;if(G){if(K){for(J=0,H=K.length;J<H;++J){F=K[J];if(I.hasOwnProperty(F)){E[F]=A.isArray(I[F])?[]:{};}}C.aggregate(E,I,true,K);}}for(J=0,H=M.length;J<H;J++){N=M[J];if(K){C.aggregate(E,N,true,K);}C.mix(E,N,true,null,1);E._yuibuild.exts.push(N);}E.prototype.hasImpl=O._hasImpl;if(G){E.NAME=D;E.prototype.constructor=E;}return E;};C.mix(B.build,{_template:function(D){function E(){E.superclass.constructor.apply(this,arguments);var H=E._yuibuild.exts,F=H.length,G;for(G=0;G<F;G++){H[G].apply(this,arguments);}return this;}C.extend(E,D);return E;},_hasImpl:function(G){var J=this._getClasses();for(var I=0,E=J.length;I<E;I++){var D=J[I];if(D._yuibuild){var H=D._yuibuild.exts,K=H.length,F;for(F=0;F<K;F++){if(H[F]===G){return true;}}}}return false;},_getClass:function(D,E){var F=(E&&false===E.dynamic)?false:true,G=(F)?B.build._template(D):D;G._yuibuild={id:null,exts:[],dynamic:F};return G;},_getAggregates:function(D,E){var F=[],H=(E&&E.aggregates),I=D,G;while(I&&I.prototype){G=I._buildCfg&&I._buildCfg.aggregates;if(G){F=F.concat(G);}I=I.superclass?I.superclass.constructor:null;}if(H){F=F.concat(H);}return F;}});},"3.0.0",{requires:["base-base"]});YUI.add("base",function(A){},"3.0.0",{use:["base-base","base-pluginhost","base-build"]});
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['base-base', 'pluginhost']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0",{requires:["base-base","pluginhost"]});
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['base-base', 'pluginhost']});
|
||||
@@ -0,0 +1,765 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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 - An augmentable Plugin.Host interface which provides plugin support
|
||||
* (which is augmented to the Base class) and Base.build 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",
|
||||
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
|
||||
*/
|
||||
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; }
|
||||
|
||||
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) {
|
||||
|
||||
/**
|
||||
* The string used to identify the class of this object.
|
||||
*
|
||||
* @deprecated Use this.constructor.NAME
|
||||
* @property name
|
||||
* @type String
|
||||
*/
|
||||
this._yuievt.config.prefix = this.name = this.constructor.NAME;
|
||||
|
||||
/**
|
||||
* <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,
|
||||
defaultFn:this._defInitFn
|
||||
});
|
||||
|
||||
if (config) {
|
||||
if (config.on) {
|
||||
this.on(config.on);
|
||||
}
|
||||
if (config.after) {
|
||||
this.after(config.after);
|
||||
}
|
||||
}
|
||||
|
||||
this.fire(INIT, {cfg: config});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* <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,
|
||||
defaultFn: this._defDestroyFn
|
||||
});
|
||||
this.fire(DESTROY);
|
||||
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 && !constr._yuibuild.dynamic) {
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
// Fix constructor
|
||||
Base.prototype.constructor = Base;
|
||||
|
||||
|
||||
}, '3.0.0' ,{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.0.0' ,{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;
|
||||
|
||||
/**
|
||||
* 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 = {
|
||||
aggregates : ["ATTRS", "_PLUG", "_UNPLUG"]
|
||||
};
|
||||
|
||||
/**
|
||||
* <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 <boolean></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 <String[]></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) {
|
||||
|
||||
var build = Base.build,
|
||||
builtClass = build._getClass(main, cfg),
|
||||
aggregates = build._getAggregates(main, cfg),
|
||||
dynamic = builtClass._yuibuild.dynamic,
|
||||
i, l, val, extClass;
|
||||
|
||||
// Shallow isolate aggregates
|
||||
if (dynamic) {
|
||||
if (aggregates) {
|
||||
for (i = 0, l = aggregates.length; i < l; ++i) {
|
||||
val = aggregates[i];
|
||||
if (main.hasOwnProperty(val)) {
|
||||
builtClass[val] = L.isArray(main[val]) ? [] : {};
|
||||
}
|
||||
}
|
||||
Y.aggregate(builtClass, main, true, aggregates);
|
||||
}
|
||||
}
|
||||
|
||||
// Augment/Aggregate
|
||||
for (i = 0, l = extensions.length; i < l; i++) {
|
||||
extClass = extensions[i];
|
||||
|
||||
if (aggregates) {
|
||||
Y.aggregate(builtClass, extClass, true, aggregates);
|
||||
}
|
||||
|
||||
// Old augment
|
||||
Y.mix(builtClass, extClass, true, null, 1);
|
||||
|
||||
builtClass._yuibuild.exts.push(extClass);
|
||||
}
|
||||
|
||||
builtClass.prototype.hasImpl = build._hasImpl;
|
||||
|
||||
if (dynamic) {
|
||||
builtClass.NAME = name;
|
||||
builtClass.prototype.constructor = builtClass;
|
||||
}
|
||||
|
||||
return builtClass;
|
||||
};
|
||||
|
||||
Y.mix(Base.build, {
|
||||
|
||||
_template: function(main) {
|
||||
|
||||
function BuiltClass() {
|
||||
|
||||
BuiltClass.superclass.constructor.apply(this, arguments);
|
||||
|
||||
var f = BuiltClass._yuibuild.exts,
|
||||
l = f.length,
|
||||
i;
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
f[i].apply(this, arguments);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
Y.extend(BuiltClass, main);
|
||||
|
||||
return BuiltClass;
|
||||
},
|
||||
|
||||
_hasImpl : function(extClass) {
|
||||
var classes = this._getClasses();
|
||||
for (var i = 0, l = classes.length; i < l; i++) {
|
||||
var cls = classes[i];
|
||||
|
||||
if (cls._yuibuild) {
|
||||
var exts = cls._yuibuild.exts,
|
||||
ll = exts.length,
|
||||
j;
|
||||
|
||||
for (j = 0; j < ll; j++) {
|
||||
if (exts[j] === extClass) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_getClass : function(main, cfg) {
|
||||
|
||||
var dynamic = (cfg && false === cfg.dynamic) ? false : true,
|
||||
builtClass = (dynamic) ? Base.build._template(main) : main;
|
||||
|
||||
builtClass._yuibuild = {
|
||||
id: null,
|
||||
exts : [],
|
||||
dynamic : dynamic
|
||||
};
|
||||
|
||||
return builtClass;
|
||||
},
|
||||
|
||||
_getAggregates : function(main, cfg) {
|
||||
var aggr = [],
|
||||
cfgAggr = (cfg && cfg.aggregates),
|
||||
c = main,
|
||||
classAggr;
|
||||
|
||||
while (c && c.prototype) {
|
||||
classAggr = c._buildCfg && c._buildCfg.aggregates;
|
||||
if (classAggr) {
|
||||
aggr = aggr.concat(classAggr);
|
||||
}
|
||||
c = c.superclass ? c.superclass.constructor : null;
|
||||
}
|
||||
|
||||
if (cfgAggr) {
|
||||
aggr = aggr.concat(cfgAggr);
|
||||
}
|
||||
|
||||
return aggr;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}, '3.0.0' ,{requires:['base-base']});
|
||||
|
||||
|
||||
YUI.add('base', function(Y){}, '3.0.0' ,{use:['base-base', 'base-pluginhost', 'base-build']});
|
||||
|
||||
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['plugin']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0",{requires:["plugin"]});
|
||||
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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.0.0' ,{requires:['plugin']});
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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] || 'yui';
|
||||
|
||||
/**
|
||||
* 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}+ one or more classname bits to be joined and prefixed
|
||||
*/
|
||||
getClassName: Y.cached(function (c, x) {
|
||||
|
||||
var sClass = sPrefix + sDelimiter +
|
||||
// ((x) ? Y.Array(arguments, 0, true).join(sDelimiter) : c);
|
||||
((x) ? Array.prototype.join.call(arguments, sDelimiter) : c);
|
||||
|
||||
return sClass.replace(/\s/g, '');
|
||||
|
||||
})
|
||||
|
||||
};
|
||||
|
||||
}();
|
||||
|
||||
|
||||
}, '3.0.0' );
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add("classnamemanager",function(C){var B="classNamePrefix",D="classNameDelimiter",A=C.config;A[B]=A[B]||"yui";A[D]=A[D]||"-";C.ClassNameManager=function(){var E=A[B],F=A[D];return{getClassName:C.cached(function(I,G){var H=E+F+((G)?Array.prototype.join.call(arguments,F):I);return H.replace(/\s/g,"");})};}();},"3.0.0");
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
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] || 'yui';
|
||||
|
||||
/**
|
||||
* 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}+ one or more classname bits to be joined and prefixed
|
||||
*/
|
||||
getClassName: Y.cached(function (c, x) {
|
||||
|
||||
var sClass = sPrefix + sDelimiter +
|
||||
// ((x) ? Y.Array(arguments, 0, true).join(sDelimiter) : c);
|
||||
((x) ? Array.prototype.join.call(arguments, sDelimiter) : c);
|
||||
|
||||
return sClass.replace(/\s/g, '');
|
||||
|
||||
})
|
||||
|
||||
};
|
||||
|
||||
}();
|
||||
|
||||
|
||||
}, '3.0.0' );
|
||||
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add('collection', function(Y) {
|
||||
|
||||
/**
|
||||
* Collection utilities beyond what is provided in the YUI core
|
||||
* @module collection
|
||||
*/
|
||||
|
||||
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 = b.lastIndexOf(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) {
|
||||
var l = a.length;
|
||||
for (var i = 0; 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) {
|
||||
var l = a.length;
|
||||
for(var i=0; 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;
|
||||
};
|
||||
|
||||
|
||||
}, '3.0.0' );
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add("collection",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=A.lastIndexOf(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){var A=F.length;for(var G=0;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){var A=F.length;for(var G=0;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;};},"3.0.0");
|
||||
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add('collection', function(Y) {
|
||||
|
||||
/**
|
||||
* Collection utilities beyond what is provided in the YUI core
|
||||
* @module collection
|
||||
*/
|
||||
|
||||
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 = b.lastIndexOf(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) {
|
||||
var l = a.length;
|
||||
for (var i = 0; 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) {
|
||||
var l = a.length;
|
||||
for(var i=0; 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;
|
||||
};
|
||||
|
||||
|
||||
}, '3.0.0' );
|
||||
@@ -0,0 +1,900 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add('compat', function(Y) {
|
||||
|
||||
|
||||
var COMPAT_ARG = '~yui|2|compat~';
|
||||
|
||||
|
||||
if (window.YAHOO != YUI) {
|
||||
|
||||
// get any existing YAHOO obj props
|
||||
var o = (window.YAHOO) ? YUI.merge(window.YAHOO) : null;
|
||||
|
||||
// Make the YUI global the YAHOO global
|
||||
window.YAHOO = YUI;
|
||||
|
||||
// augment old YAHOO props
|
||||
if (o) {
|
||||
Y.mix(Y, o);
|
||||
}
|
||||
}
|
||||
|
||||
// add old namespaces
|
||||
Y.namespace("util", "widget", "example");
|
||||
|
||||
// case/location change
|
||||
Y.env = (Y.env) ? Y.mix(Y.env, Y.Env) : Y.Env;
|
||||
Y.lang = (Y.lang) ? Y.mix(Y.lang, Y.Lang) : Y.Lang;
|
||||
Y.env.ua = Y.UA;
|
||||
|
||||
// support Y.register
|
||||
Y.mix(Y.env, {
|
||||
modules: [],
|
||||
listeners: [],
|
||||
getVersion: function(name) {
|
||||
return this.Env.modules[name] || null;
|
||||
}
|
||||
});
|
||||
|
||||
var L = Y.lang;
|
||||
|
||||
// add old lang properties
|
||||
Y.mix(L, {
|
||||
|
||||
augmentObject: function(r, s) {
|
||||
var a = arguments, wl = (a.length > 2) ? Y.Array(a, 2, true) : null;
|
||||
return Y.mix(r, s, (wl), wl);
|
||||
},
|
||||
|
||||
augmentProto: function(r, s) {
|
||||
var a = arguments, wl = (a.length > 2) ? Y.Array(a, 2, true) : null;
|
||||
return Y.mix(r, s, (wl), wl, 1);
|
||||
},
|
||||
|
||||
// extend: Y.bind(Y.extend, Y),
|
||||
extend: Y.extend,
|
||||
// merge: Y.bind(Y.merge, Y)
|
||||
merge: Y.merge
|
||||
}, true);
|
||||
|
||||
L.augment = L.augmentProto;
|
||||
|
||||
L.hasOwnProperty = function(o, k) {
|
||||
return (o.hasOwnProperty(k));
|
||||
};
|
||||
|
||||
Y.augmentProto = L.augmentProto;
|
||||
|
||||
// add register function
|
||||
Y.mix(Y, {
|
||||
register: function(name, mainClass, data) {
|
||||
var mods = Y.Env.modules;
|
||||
if (!mods[name]) {
|
||||
mods[name] = { versions:[], builds:[] };
|
||||
}
|
||||
var m=mods[name],v=data.version,b=data.build,ls=Y.Env.listeners;
|
||||
m.name = name;
|
||||
m.version = v;
|
||||
m.build = b;
|
||||
m.versions.push(v);
|
||||
m.builds.push(b);
|
||||
m.mainClass = mainClass;
|
||||
// fire the module load listeners
|
||||
for (var i=0;i<ls.length;i=i+1) {
|
||||
ls[i](m);
|
||||
}
|
||||
// label the main class
|
||||
if (mainClass) {
|
||||
mainClass.VERSION = v;
|
||||
mainClass.BUILD = b;
|
||||
} else {
|
||||
Y.log("mainClass is undefined for module " + name, "warn");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// add old load listeners
|
||||
if ("undefined" !== typeof YAHOO_config) {
|
||||
var l=YAHOO_config.listener,ls=Y.Env.listeners,unique=true,i;
|
||||
if (l) {
|
||||
// if YAHOO is loaded multiple times we need to check to see if
|
||||
// this is a new config object. If it is, add the new component
|
||||
// load listener to the stack
|
||||
for (i=0;i<ls.length;i=i+1) {
|
||||
if (ls[i]==l) {
|
||||
unique=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (unique) {
|
||||
ls.push(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add old registration for yahoo
|
||||
Y.register("yahoo", Y, {version: "3.0.0", build: "1549"});
|
||||
|
||||
if (Y.Event) {
|
||||
|
||||
var o = {
|
||||
|
||||
/**
|
||||
* Safari detection
|
||||
* @property isSafari
|
||||
* @private
|
||||
* @static
|
||||
* @deprecated use Y.Env.UA.webkit
|
||||
*/
|
||||
isSafari: Y.UA.webkit,
|
||||
|
||||
/**
|
||||
* webkit version
|
||||
* @property webkit
|
||||
* @type string
|
||||
* @private
|
||||
* @static
|
||||
* @deprecated use Y.Env.UA.webkit
|
||||
*/
|
||||
webkit: Y.UA.webkit,
|
||||
|
||||
/**
|
||||
* Normalized keycodes for webkit/safari
|
||||
* @property webkitKeymap
|
||||
* @type {int: int}
|
||||
* @private
|
||||
* @static
|
||||
* @final
|
||||
*/
|
||||
webkitKeymap: {
|
||||
63232: 38, // up
|
||||
63233: 40, // down
|
||||
63234: 37, // left
|
||||
63235: 39, // right
|
||||
63276: 33, // page up
|
||||
63277: 34, // page down
|
||||
25: 9 // SHIFT-TAB (Safari provides a different key code in
|
||||
// this case, even though the shiftKey modifier is set)
|
||||
},
|
||||
|
||||
/**
|
||||
* IE detection
|
||||
* @property isIE
|
||||
* @private
|
||||
* @static
|
||||
* @deprecated use Y.Env.UA.ie
|
||||
*/
|
||||
isIE: Y.UA.ie,
|
||||
|
||||
/**
|
||||
* Returns scrollLeft
|
||||
* @method _getScrollLeft
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
_getScrollLeft: function() {
|
||||
return this._getScroll()[1];
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns scrollTop
|
||||
* @method _getScrollTop
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
_getScrollTop: function() {
|
||||
return this._getScroll()[0];
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the scrollTop and scrollLeft. Used to calculate the
|
||||
* pageX and pageY in Internet Explorer
|
||||
* @method _getScroll
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
_getScroll: function() {
|
||||
var d = Y.config.doc, dd = d.documentElement, db = d.body;
|
||||
if (dd && (dd.scrollTop || dd.scrollLeft)) {
|
||||
return [dd.scrollTop, dd.scrollLeft];
|
||||
} else if (db) {
|
||||
return [db.scrollTop, db.scrollLeft];
|
||||
} else {
|
||||
return [0, 0];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the event's pageX
|
||||
* @method getPageX
|
||||
* @param {Event} ev the event
|
||||
* @return {int} the event's pageX
|
||||
* @static
|
||||
*/
|
||||
getPageX: function(ev) {
|
||||
var x = ev.pageX;
|
||||
if (!x && 0 !== x) {
|
||||
x = ev.clientX || 0;
|
||||
|
||||
if ( Y.UA.ie ) {
|
||||
x += this._getScrollLeft();
|
||||
}
|
||||
}
|
||||
|
||||
return x;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the charcode for an event
|
||||
* @method getCharCode
|
||||
* @param {Event} ev the event
|
||||
* @return {int} the event's charCode
|
||||
* @static
|
||||
*/
|
||||
getCharCode: function(ev) {
|
||||
var code = ev.keyCode || ev.charCode || 0;
|
||||
|
||||
// webkit normalization
|
||||
if (Y.UA.webkit && (code in Y.Event.webkitKeymap)) {
|
||||
code = Y.Event.webkitKeymap[code];
|
||||
}
|
||||
return code;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the event's pageY
|
||||
* @method getPageY
|
||||
* @param {Event} ev the event
|
||||
* @return {int} the event's pageY
|
||||
* @static
|
||||
*/
|
||||
getPageY: function(ev) {
|
||||
var y = ev.pageY;
|
||||
if (!y && 0 !== y) {
|
||||
y = ev.clientY || 0;
|
||||
|
||||
if ( Y.UA.ie ) {
|
||||
y += this._getScrollTop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return y;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the pageX and pageY properties as an indexed array.
|
||||
* @method getXY
|
||||
* @param {Event} ev the event
|
||||
* @return {[x, y]} the pageX and pageY properties of the event
|
||||
* @static
|
||||
*/
|
||||
getXY: function(ev) {
|
||||
return [this.getPageX(ev), this.getPageY(ev)];
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the event's related target
|
||||
* @method getRelatedTarget
|
||||
* @param {Event} ev the event
|
||||
* @return {HTMLElement} the event's relatedTarget
|
||||
* @static
|
||||
*/
|
||||
getRelatedTarget: function(ev) {
|
||||
var t = ev.relatedTarget;
|
||||
if (!t) {
|
||||
if (ev.type == "mouseout") {
|
||||
t = ev.toElement;
|
||||
} else if (ev.type == "mouseover") {
|
||||
t = ev.fromElement;
|
||||
}
|
||||
}
|
||||
|
||||
return this.resolveTextNode(t);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the time of the event. If the time is not included, the
|
||||
* event is modified using the current time.
|
||||
* @method getTime
|
||||
* @param {Event} ev the event
|
||||
* @return {Date} the time of the event
|
||||
* @static
|
||||
*/
|
||||
getTime: function(ev) {
|
||||
if (!ev.time) {
|
||||
var t = new Date().getTime();
|
||||
try {
|
||||
ev.time = t;
|
||||
} catch(ex) {
|
||||
this.lastError = ex;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
return ev.time;
|
||||
},
|
||||
|
||||
/**
|
||||
* Convenience method for stopPropagation + preventDefault
|
||||
* @method stopEvent
|
||||
* @param {Event} ev the event
|
||||
* @static
|
||||
*/
|
||||
stopEvent: function(ev) {
|
||||
this.stopPropagation(ev);
|
||||
this.preventDefault(ev);
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops event propagation
|
||||
* @method stopPropagation
|
||||
* @param {Event} ev the event
|
||||
* @static
|
||||
*/
|
||||
stopPropagation: function(ev) {
|
||||
if (ev.stopPropagation) {
|
||||
ev.stopPropagation();
|
||||
} else {
|
||||
ev.cancelBubble = true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Prevents the default behavior of the event
|
||||
* @method preventDefault
|
||||
* @param {Event} ev the event
|
||||
* @static
|
||||
*/
|
||||
preventDefault: function(ev) {
|
||||
if (ev.preventDefault) {
|
||||
ev.preventDefault();
|
||||
} else {
|
||||
ev.returnValue = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the event's target element. Safari sometimes provides
|
||||
* a text node, and this is automatically resolved to the text
|
||||
* node's parent so that it behaves like other browsers.
|
||||
* @method getTarget
|
||||
* @param {Event} ev the event
|
||||
* @param {boolean} resolveTextNode when set to true the target's
|
||||
* parent will be returned if the target is a
|
||||
* text node. @deprecated, the text node is
|
||||
* now resolved automatically
|
||||
* @return {HTMLElement} the event's target
|
||||
* @static
|
||||
*/
|
||||
getTarget: function(ev, resolveTextNode) {
|
||||
var t = ev.target || ev.srcElement;
|
||||
return this.resolveTextNode(t);
|
||||
},
|
||||
|
||||
/**
|
||||
* In some cases, some browsers will return a text node inside
|
||||
* the actual element that was targeted. This normalizes the
|
||||
* return value for getTarget and getRelatedTarget.
|
||||
* @method resolveTextNode
|
||||
* @param {HTMLElement} node node to resolve
|
||||
* @return {HTMLElement} the normized node
|
||||
* @static
|
||||
*/
|
||||
resolveTextNode: function(node) {
|
||||
if (node && 3 == node.nodeType) {
|
||||
return node.parentNode;
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* We cache elements bound by id because when the unload event
|
||||
* fires, we can no longer use document.getElementById
|
||||
* @method getEl
|
||||
* @static
|
||||
* @private
|
||||
* @deprecated Elements are not cached any longer
|
||||
*/
|
||||
getEl: function(id) {
|
||||
return Y.get(id);
|
||||
}
|
||||
};
|
||||
|
||||
Y.mix(Y.Event, o);
|
||||
|
||||
/**
|
||||
* Calls Y.Event.attach with the correct argument order
|
||||
* @method removeListener
|
||||
*/
|
||||
Y.Event.removeListener = function(el, type, fn, data, override) {
|
||||
|
||||
var context, a=[type, fn, el];
|
||||
|
||||
if (data) {
|
||||
|
||||
if (override) {
|
||||
context = (override === true) ? data : override;
|
||||
}
|
||||
|
||||
a.push(context);
|
||||
a.push(data);
|
||||
}
|
||||
|
||||
a.push(COMPAT_ARG);
|
||||
|
||||
return Y.Event.detach.apply(Y.Event, a);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calls Y.Event.detach with the correct argument order
|
||||
* @method addListener
|
||||
*/
|
||||
Y.Event.addListener = function(el, type, fn, data, override) {
|
||||
|
||||
// Y.log('addListener:');
|
||||
// Y.log(Y.Array(arguments, 0, true), 1);
|
||||
|
||||
// var a = Y.Array(arguments, 0, true), el = a.shift();
|
||||
// a.splice(2, 0, el);
|
||||
// return Y.Event.attach.apply(Y.Event, a);
|
||||
var context, a=[type, fn, el];
|
||||
|
||||
if (data) {
|
||||
|
||||
if (override) {
|
||||
context = (override === true) ? data : override;
|
||||
}
|
||||
|
||||
a.push(context);
|
||||
a.push(data);
|
||||
}
|
||||
|
||||
a.push(COMPAT_ARG);
|
||||
|
||||
return Y.Event.attach.apply(Y.Event, a);
|
||||
};
|
||||
|
||||
Y.Event.on = Y.Event.addListener;
|
||||
|
||||
var newOnavail = Y.Event.onAvailable;
|
||||
|
||||
Y.Event.onAvailable = function(id, fn, p_obj, p_override) {
|
||||
return newOnavail(id, fn, p_obj, p_override, false, true);
|
||||
};
|
||||
|
||||
Y.Event.onContentReady = function(id, fn, p_obj, p_override) {
|
||||
return newOnavail(id, fn, p_obj, p_override, true, true);
|
||||
};
|
||||
|
||||
Y.Event.onDOMReady = function(fn) {
|
||||
var a = Y.Array(arguments, 0, true);
|
||||
a.unshift('event:ready');
|
||||
return Y.on.apply(Y, a);
|
||||
};
|
||||
|
||||
Y.util.Event = Y.Event;
|
||||
|
||||
var CE = function(type, oScope, silent, signature) {
|
||||
//debugger;
|
||||
|
||||
var o = {
|
||||
context: oScope,
|
||||
silent: silent || false
|
||||
// signature: signature || CE.LIST
|
||||
};
|
||||
|
||||
CE.superclass.constructor.call(this, type, o);
|
||||
|
||||
this.signature = signature || CE.LIST;
|
||||
};
|
||||
|
||||
Y.extend(CE, Y.CustomEvent, {
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Subscriber listener sigature constant. The LIST type returns three
|
||||
* parameters: the event type, the array of args passed to fire, and
|
||||
* the optional custom object
|
||||
* @property YAHOO.util.CustomEvent.LIST
|
||||
* @static
|
||||
* @type int
|
||||
*/
|
||||
CE.LIST = 0;
|
||||
|
||||
/**
|
||||
* Subscriber listener sigature constant. The FLAT type returns two
|
||||
* parameters: the first argument passed to fire and the optional
|
||||
* custom object
|
||||
* @property YAHOO.util.CustomEvent.FLAT
|
||||
* @static
|
||||
* @type int
|
||||
*/
|
||||
CE.FLAT = 1;
|
||||
|
||||
Y.util.CustomEvent = CE;
|
||||
|
||||
var EP = function() {
|
||||
//console.log('Compat CustomEvent constructor executed: ' + this._yuid);
|
||||
if (!this._yuievt) {
|
||||
var sub = this.subscribe;
|
||||
Y.EventTarget.apply(this, arguments);
|
||||
this.subscribe = sub;
|
||||
this.__yuiepinit = function() {};
|
||||
}
|
||||
};
|
||||
|
||||
Y.extend(EP, Y.EventTarget, {
|
||||
|
||||
createEvent: function(type, o) {
|
||||
o = o || {};
|
||||
o.signature = o.signature || CE.FLAT;
|
||||
return this.publish(type, o);
|
||||
},
|
||||
|
||||
subscribe: function(type, fn, obj, override) {
|
||||
var ce = this._yuievt.events[type] || this.createEvent(type),
|
||||
a = Y.Array(arguments);
|
||||
|
||||
if (override && true !== override) {
|
||||
// a[2] = override;
|
||||
// a[1] = obj;
|
||||
}
|
||||
|
||||
Y.EventTarget.prototype.subscribe.apply(this, a);
|
||||
},
|
||||
|
||||
fireEvent: function(type) {
|
||||
return this.fire.apply(this, arguments);
|
||||
},
|
||||
|
||||
hasEvent: function(type) {
|
||||
return this.getEvent(type);
|
||||
}
|
||||
});
|
||||
|
||||
Y.util.EventProvider = EP;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Y.register("event", Y, {version: "3.0.0", build: "1549"});
|
||||
|
||||
|
||||
var propertyCache = {};
|
||||
var patterns = {
|
||||
HYPHEN: /(-[a-z])/i, // to normalize get/setStyle
|
||||
ROOT_TAG: /^body|html$/i, // body for quirks mode, html for standards,
|
||||
OP_SCROLL:/^(?:inline|table-row)$/i
|
||||
};
|
||||
|
||||
var hyphenToCamel = function(property) {
|
||||
if ( !patterns.HYPHEN.test(property) ) {
|
||||
return property; // no hyphens
|
||||
}
|
||||
|
||||
if (propertyCache[property]) { // already converted
|
||||
return propertyCache[property];
|
||||
}
|
||||
|
||||
var converted = property;
|
||||
|
||||
while( patterns.HYPHEN.exec(converted) ) {
|
||||
converted = converted.replace(RegExp.$1,
|
||||
RegExp.$1.substr(1).toUpperCase());
|
||||
}
|
||||
|
||||
propertyCache[property] = converted;
|
||||
return converted;
|
||||
//return property.replace(/-([a-z])/gi, function(m0, m1) {return m1.toUpperCase()}) // cant use function as 2nd arg yet due to safari bug
|
||||
};
|
||||
|
||||
var Dom = {
|
||||
get: function(el) {
|
||||
if (el) {
|
||||
if (el.nodeType || el.item) { // Node, or NodeList
|
||||
return el;
|
||||
}
|
||||
|
||||
if (typeof el === 'string') { // id
|
||||
return document.getElementById(el);
|
||||
}
|
||||
|
||||
if ('length' in el) { // array-like
|
||||
var c = [];
|
||||
for (var i = 0, len = el.length; i < len; ++i) {
|
||||
c[c.length] = Dom.get(el[i]);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
return el; // some other object, just pass it back
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
isAncestor: function(haystack, needle) {
|
||||
return YUI.DOM.contains(Dom.get(haystack), Dom.get(needle));
|
||||
},
|
||||
|
||||
inDocument: function(el) {
|
||||
return Dom.isAncestor(Y.config.doc.documentElement, el);
|
||||
},
|
||||
|
||||
batch: function(el, method, o, override, args) {
|
||||
el = (el && (el.tagName || el.item)) ? el : Dom.get(el); // skip get() when possible
|
||||
|
||||
if (!el || !method) {
|
||||
return false;
|
||||
}
|
||||
if (args) {
|
||||
args = Y.Array(args);
|
||||
}
|
||||
var scope = (override) ? o : window;
|
||||
|
||||
var apply = function(el) {
|
||||
if (args) {
|
||||
var tmp = slice.call(args);
|
||||
tmp.unshift(el);
|
||||
return method.apply(scope, tmp);
|
||||
} else {
|
||||
return method.call(scope, el, o);
|
||||
}
|
||||
};
|
||||
|
||||
if (el.tagName || el.length === undefined) { // element or not array-like
|
||||
return apply(el);
|
||||
}
|
||||
|
||||
var collection = [];
|
||||
|
||||
for (var i = 0, len = el.length; i < len; ++i) {
|
||||
collection[collection.length] = apply(el[i]);
|
||||
}
|
||||
|
||||
return collection;
|
||||
},
|
||||
|
||||
// 2.x returns false if already present
|
||||
_addClass: function(el, className) {
|
||||
if ( YUI.DOM.hasClass(el, className) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
YUI.DOM.addClass(el, className);
|
||||
return true;
|
||||
},
|
||||
|
||||
// 2.x returns false if not present
|
||||
_removeClass: function(el, className) {
|
||||
if ( !YUI.DOM.hasClass(el, className) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
YUI.DOM.removeClass(el, className);
|
||||
return true;
|
||||
},
|
||||
|
||||
// 2.x returns false if no newClass or same as oldClass
|
||||
_replaceClass: function(el, oldClass, newClass) {
|
||||
if (!newClass || oldClass === newClass) {
|
||||
return false;
|
||||
}
|
||||
|
||||
YUI.DOM.replaceClass(el, oldClass, newClass);
|
||||
return true;
|
||||
},
|
||||
|
||||
getElementsByClassName: function(className, tag, root) {
|
||||
tag = tag || '*';
|
||||
root = (root) ? Dom.get(root) : Y.config.doc;
|
||||
var nodes = [];
|
||||
if (root) {
|
||||
nodes = Y.Selector.query(tag + '.' + className, root);
|
||||
}
|
||||
return nodes;
|
||||
},
|
||||
|
||||
getElementsBy: function(method, tag, root) {
|
||||
tag = tag || '*';
|
||||
root = (root) ? Dom.get(root) : null || document;
|
||||
|
||||
var nodes = [];
|
||||
if (root) {
|
||||
nodes = YUI.DOM.byTag(tag, root, method);
|
||||
}
|
||||
return nodes;
|
||||
},
|
||||
|
||||
getViewportWidth: YUI.DOM.winWidth,
|
||||
getViewportHeight: YUI.DOM.winHeight,
|
||||
getDocumentWidth: YUI.DOM.docWidth,
|
||||
getDocumentHeight: YUI.DOM.docHeight,
|
||||
getDocumentScrollTop: YUI.DOM.docScrollY,
|
||||
getDocumentScrollLeft: YUI.DOM.docScrollX,
|
||||
getDocumentHeight: YUI.DOM.docHeight,
|
||||
|
||||
_guid: function(el, prefix) {
|
||||
prefix = prefix || 'yui-gen';
|
||||
Dom._id_counter = Dom._id_counter || 0;
|
||||
|
||||
if (el && el.id) { // do not override existing ID
|
||||
return el.id;
|
||||
}
|
||||
|
||||
var id = prefix + Dom._id_counter++;
|
||||
|
||||
if (el) {
|
||||
el.id = id;
|
||||
}
|
||||
|
||||
return id;
|
||||
},
|
||||
|
||||
_region: function(el) {
|
||||
if ( (el.parentNode === null || el.offsetParent === null ||
|
||||
YUI.DOM.getStyle(el, 'display') == 'none') && el != el.ownerDocument.body) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return YUI.DOM.region(el);
|
||||
|
||||
},
|
||||
|
||||
_ancestorByClass: function(element, className) {
|
||||
return YUI.DOM.ancestor(element, function(el) {
|
||||
return YUI.DOM.hasClass(el, className);
|
||||
});
|
||||
},
|
||||
|
||||
_ancestorByTag: function(element, tag) {
|
||||
tag = tag.toUpperCase();
|
||||
return YUI.DOM.ancestor(element, function(el) {
|
||||
return el.tagName.toUpperCase() === tag;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var slice = [].slice;
|
||||
|
||||
var wrap = function(fn, name) {
|
||||
Dom[name] = function() {
|
||||
var args = slice.call(arguments);
|
||||
args[0] = Dom.get(args[0]);
|
||||
return fn.apply(Dom, args);
|
||||
};
|
||||
};
|
||||
|
||||
var wrapped = {
|
||||
getAncestorBy: YUI.DOM.ancestor,
|
||||
getAncestorByClassName: Dom._ancestorByClass,
|
||||
getAncestorByTagName: Dom._ancestorByTag,
|
||||
getPreviousSiblingBy: YUI.DOM.previous,
|
||||
getPreviousSibling: YUI.DOM.previous,
|
||||
getNextSiblingBy: YUI.DOM.next,
|
||||
getNextSibling: YUI.DOM.next,
|
||||
getFirstChildBy: YUI.DOM.firstChild,
|
||||
getFirstChild: YUI.DOM.firstChild,
|
||||
getLastChildBy: YUI.DOM.lastChild,
|
||||
getLastChild: YUI.DOM.lastChild,
|
||||
getChildrenBy: YUI.DOM.children,
|
||||
getChildren: YUI.DOM.children,
|
||||
insertBefore: function(newNode, refNode) {
|
||||
YUI.DOM.insertBefore(Dom.get(newNode), Dom.get(refNode));
|
||||
},
|
||||
insertAfter: function(newNode, refNode) {
|
||||
YUI.DOM.insertAfter(Dom.get(newNode), Dom.get(refNode));
|
||||
}
|
||||
};
|
||||
|
||||
Y.each(wrapped, wrap);
|
||||
|
||||
var batched = {
|
||||
getStyle: YUI.DOM.getStyle,
|
||||
setStyle: YUI.DOM.setStyle,
|
||||
getXY: YUI.DOM.getXY,
|
||||
setXY: YUI.DOM.setXY,
|
||||
getX: YUI.DOM.getX,
|
||||
getY: YUI.DOM.getY,
|
||||
setX: YUI.DOM.setX,
|
||||
setY: YUI.DOM.setY,
|
||||
getRegion: Dom._region,
|
||||
hasClass: YUI.DOM.hasClass,
|
||||
addClass: Dom._addClass,
|
||||
removeClass: Dom._removeClass,
|
||||
replaceClass: Dom._replaceClass,
|
||||
generateId: Dom._guid
|
||||
};
|
||||
|
||||
Y.each(batched, function(v, n) {
|
||||
Dom[n] = function(el) {
|
||||
var args = slice.call(arguments, 1);
|
||||
return Dom.batch(el, v, null, null, args);
|
||||
};
|
||||
});
|
||||
|
||||
Y.util.Dom = Dom;
|
||||
|
||||
YAHOO.util.Region = function(t, r, b, l) {
|
||||
this.top = t;
|
||||
this[1] = t;
|
||||
this.right = r;
|
||||
this.bottom = b;
|
||||
this.left = l;
|
||||
this[0] = l;
|
||||
};
|
||||
|
||||
YAHOO.util.Region.prototype.contains = function(region) {
|
||||
return ( region.left >= this.left &&
|
||||
region.right <= this.right &&
|
||||
region.top >= this.top &&
|
||||
region.bottom <= this.bottom );
|
||||
|
||||
// this.logger.debug("does " + this + " contain " + region + " ... " + ret);
|
||||
};
|
||||
|
||||
YAHOO.util.Region.prototype.getArea = function() {
|
||||
return ( (this.bottom - this.top) * (this.right - this.left) );
|
||||
};
|
||||
|
||||
YAHOO.util.Region.prototype.intersect = function(region) {
|
||||
var t = Math.max( this.top, region.top );
|
||||
var r = Math.min( this.right, region.right );
|
||||
var b = Math.min( this.bottom, region.bottom );
|
||||
var l = Math.max( this.left, region.left );
|
||||
|
||||
if (b >= t && r >= l) {
|
||||
return new YAHOO.util.Region(t, r, b, l);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
YAHOO.util.Region.prototype.union = function(region) {
|
||||
var t = Math.min( this.top, region.top );
|
||||
var r = Math.max( this.right, region.right );
|
||||
var b = Math.max( this.bottom, region.bottom );
|
||||
var l = Math.min( this.left, region.left );
|
||||
|
||||
return new YAHOO.util.Region(t, r, b, l);
|
||||
};
|
||||
|
||||
YAHOO.util.Region.prototype.toString = function() {
|
||||
return ( "Region {" +
|
||||
"top: " + this.top +
|
||||
", right: " + this.right +
|
||||
", bottom: " + this.bottom +
|
||||
", left: " + this.left +
|
||||
"}" );
|
||||
};
|
||||
|
||||
YAHOO.util.Region.getRegion = function(el) {
|
||||
return YUI.DOM.region(el);
|
||||
};
|
||||
|
||||
YAHOO.util.Point = function(x, y) {
|
||||
if (YAHOO.lang.isArray(x)) { // accept input from Dom.getXY, Event.getXY, etc.
|
||||
y = x[1]; // dont blow away x yet
|
||||
x = x[0];
|
||||
}
|
||||
|
||||
this.x = this.right = this.left = this[0] = x;
|
||||
this.y = this.top = this.bottom = this[1] = y;
|
||||
};
|
||||
|
||||
YAHOO.util.Point.prototype = new YAHOO.util.Region();
|
||||
|
||||
|
||||
|
||||
}, '3.0.0' ,{requires:['dom','event']});
|
||||
YUI._setup(); YUI.use('dom', 'event', 'compat');
|
||||
@@ -0,0 +1,896 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add('compat', function(Y) {
|
||||
|
||||
|
||||
var COMPAT_ARG = '~yui|2|compat~';
|
||||
|
||||
|
||||
if (window.YAHOO != YUI) {
|
||||
|
||||
// get any existing YAHOO obj props
|
||||
var o = (window.YAHOO) ? YUI.merge(window.YAHOO) : null;
|
||||
|
||||
// Make the YUI global the YAHOO global
|
||||
window.YAHOO = YUI;
|
||||
|
||||
// augment old YAHOO props
|
||||
if (o) {
|
||||
Y.mix(Y, o);
|
||||
}
|
||||
}
|
||||
|
||||
// add old namespaces
|
||||
Y.namespace("util", "widget", "example");
|
||||
|
||||
// case/location change
|
||||
Y.env = (Y.env) ? Y.mix(Y.env, Y.Env) : Y.Env;
|
||||
Y.lang = (Y.lang) ? Y.mix(Y.lang, Y.Lang) : Y.Lang;
|
||||
Y.env.ua = Y.UA;
|
||||
|
||||
// support Y.register
|
||||
Y.mix(Y.env, {
|
||||
modules: [],
|
||||
listeners: [],
|
||||
getVersion: function(name) {
|
||||
return this.Env.modules[name] || null;
|
||||
}
|
||||
});
|
||||
|
||||
var L = Y.lang;
|
||||
|
||||
// add old lang properties
|
||||
Y.mix(L, {
|
||||
|
||||
augmentObject: function(r, s) {
|
||||
var a = arguments, wl = (a.length > 2) ? Y.Array(a, 2, true) : null;
|
||||
return Y.mix(r, s, (wl), wl);
|
||||
},
|
||||
|
||||
augmentProto: function(r, s) {
|
||||
var a = arguments, wl = (a.length > 2) ? Y.Array(a, 2, true) : null;
|
||||
return Y.mix(r, s, (wl), wl, 1);
|
||||
},
|
||||
|
||||
// extend: Y.bind(Y.extend, Y),
|
||||
extend: Y.extend,
|
||||
// merge: Y.bind(Y.merge, Y)
|
||||
merge: Y.merge
|
||||
}, true);
|
||||
|
||||
L.augment = L.augmentProto;
|
||||
|
||||
L.hasOwnProperty = function(o, k) {
|
||||
return (o.hasOwnProperty(k));
|
||||
};
|
||||
|
||||
Y.augmentProto = L.augmentProto;
|
||||
|
||||
// add register function
|
||||
Y.mix(Y, {
|
||||
register: function(name, mainClass, data) {
|
||||
var mods = Y.Env.modules;
|
||||
if (!mods[name]) {
|
||||
mods[name] = { versions:[], builds:[] };
|
||||
}
|
||||
var m=mods[name],v=data.version,b=data.build,ls=Y.Env.listeners;
|
||||
m.name = name;
|
||||
m.version = v;
|
||||
m.build = b;
|
||||
m.versions.push(v);
|
||||
m.builds.push(b);
|
||||
m.mainClass = mainClass;
|
||||
// fire the module load listeners
|
||||
for (var i=0;i<ls.length;i=i+1) {
|
||||
ls[i](m);
|
||||
}
|
||||
// label the main class
|
||||
if (mainClass) {
|
||||
mainClass.VERSION = v;
|
||||
mainClass.BUILD = b;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// add old load listeners
|
||||
if ("undefined" !== typeof YAHOO_config) {
|
||||
var l=YAHOO_config.listener,ls=Y.Env.listeners,unique=true,i;
|
||||
if (l) {
|
||||
// if YAHOO is loaded multiple times we need to check to see if
|
||||
// this is a new config object. If it is, add the new component
|
||||
// load listener to the stack
|
||||
for (i=0;i<ls.length;i=i+1) {
|
||||
if (ls[i]==l) {
|
||||
unique=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (unique) {
|
||||
ls.push(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add old registration for yahoo
|
||||
Y.register("yahoo", Y, {version: "3.0.0", build: "1549"});
|
||||
|
||||
if (Y.Event) {
|
||||
|
||||
var o = {
|
||||
|
||||
/**
|
||||
* Safari detection
|
||||
* @property isSafari
|
||||
* @private
|
||||
* @static
|
||||
* @deprecated use Y.Env.UA.webkit
|
||||
*/
|
||||
isSafari: Y.UA.webkit,
|
||||
|
||||
/**
|
||||
* webkit version
|
||||
* @property webkit
|
||||
* @type string
|
||||
* @private
|
||||
* @static
|
||||
* @deprecated use Y.Env.UA.webkit
|
||||
*/
|
||||
webkit: Y.UA.webkit,
|
||||
|
||||
/**
|
||||
* Normalized keycodes for webkit/safari
|
||||
* @property webkitKeymap
|
||||
* @type {int: int}
|
||||
* @private
|
||||
* @static
|
||||
* @final
|
||||
*/
|
||||
webkitKeymap: {
|
||||
63232: 38, // up
|
||||
63233: 40, // down
|
||||
63234: 37, // left
|
||||
63235: 39, // right
|
||||
63276: 33, // page up
|
||||
63277: 34, // page down
|
||||
25: 9 // SHIFT-TAB (Safari provides a different key code in
|
||||
// this case, even though the shiftKey modifier is set)
|
||||
},
|
||||
|
||||
/**
|
||||
* IE detection
|
||||
* @property isIE
|
||||
* @private
|
||||
* @static
|
||||
* @deprecated use Y.Env.UA.ie
|
||||
*/
|
||||
isIE: Y.UA.ie,
|
||||
|
||||
/**
|
||||
* Returns scrollLeft
|
||||
* @method _getScrollLeft
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
_getScrollLeft: function() {
|
||||
return this._getScroll()[1];
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns scrollTop
|
||||
* @method _getScrollTop
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
_getScrollTop: function() {
|
||||
return this._getScroll()[0];
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the scrollTop and scrollLeft. Used to calculate the
|
||||
* pageX and pageY in Internet Explorer
|
||||
* @method _getScroll
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
_getScroll: function() {
|
||||
var d = Y.config.doc, dd = d.documentElement, db = d.body;
|
||||
if (dd && (dd.scrollTop || dd.scrollLeft)) {
|
||||
return [dd.scrollTop, dd.scrollLeft];
|
||||
} else if (db) {
|
||||
return [db.scrollTop, db.scrollLeft];
|
||||
} else {
|
||||
return [0, 0];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the event's pageX
|
||||
* @method getPageX
|
||||
* @param {Event} ev the event
|
||||
* @return {int} the event's pageX
|
||||
* @static
|
||||
*/
|
||||
getPageX: function(ev) {
|
||||
var x = ev.pageX;
|
||||
if (!x && 0 !== x) {
|
||||
x = ev.clientX || 0;
|
||||
|
||||
if ( Y.UA.ie ) {
|
||||
x += this._getScrollLeft();
|
||||
}
|
||||
}
|
||||
|
||||
return x;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the charcode for an event
|
||||
* @method getCharCode
|
||||
* @param {Event} ev the event
|
||||
* @return {int} the event's charCode
|
||||
* @static
|
||||
*/
|
||||
getCharCode: function(ev) {
|
||||
var code = ev.keyCode || ev.charCode || 0;
|
||||
|
||||
// webkit normalization
|
||||
if (Y.UA.webkit && (code in Y.Event.webkitKeymap)) {
|
||||
code = Y.Event.webkitKeymap[code];
|
||||
}
|
||||
return code;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the event's pageY
|
||||
* @method getPageY
|
||||
* @param {Event} ev the event
|
||||
* @return {int} the event's pageY
|
||||
* @static
|
||||
*/
|
||||
getPageY: function(ev) {
|
||||
var y = ev.pageY;
|
||||
if (!y && 0 !== y) {
|
||||
y = ev.clientY || 0;
|
||||
|
||||
if ( Y.UA.ie ) {
|
||||
y += this._getScrollTop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return y;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the pageX and pageY properties as an indexed array.
|
||||
* @method getXY
|
||||
* @param {Event} ev the event
|
||||
* @return {[x, y]} the pageX and pageY properties of the event
|
||||
* @static
|
||||
*/
|
||||
getXY: function(ev) {
|
||||
return [this.getPageX(ev), this.getPageY(ev)];
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the event's related target
|
||||
* @method getRelatedTarget
|
||||
* @param {Event} ev the event
|
||||
* @return {HTMLElement} the event's relatedTarget
|
||||
* @static
|
||||
*/
|
||||
getRelatedTarget: function(ev) {
|
||||
var t = ev.relatedTarget;
|
||||
if (!t) {
|
||||
if (ev.type == "mouseout") {
|
||||
t = ev.toElement;
|
||||
} else if (ev.type == "mouseover") {
|
||||
t = ev.fromElement;
|
||||
}
|
||||
}
|
||||
|
||||
return this.resolveTextNode(t);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the time of the event. If the time is not included, the
|
||||
* event is modified using the current time.
|
||||
* @method getTime
|
||||
* @param {Event} ev the event
|
||||
* @return {Date} the time of the event
|
||||
* @static
|
||||
*/
|
||||
getTime: function(ev) {
|
||||
if (!ev.time) {
|
||||
var t = new Date().getTime();
|
||||
try {
|
||||
ev.time = t;
|
||||
} catch(ex) {
|
||||
this.lastError = ex;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
return ev.time;
|
||||
},
|
||||
|
||||
/**
|
||||
* Convenience method for stopPropagation + preventDefault
|
||||
* @method stopEvent
|
||||
* @param {Event} ev the event
|
||||
* @static
|
||||
*/
|
||||
stopEvent: function(ev) {
|
||||
this.stopPropagation(ev);
|
||||
this.preventDefault(ev);
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops event propagation
|
||||
* @method stopPropagation
|
||||
* @param {Event} ev the event
|
||||
* @static
|
||||
*/
|
||||
stopPropagation: function(ev) {
|
||||
if (ev.stopPropagation) {
|
||||
ev.stopPropagation();
|
||||
} else {
|
||||
ev.cancelBubble = true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Prevents the default behavior of the event
|
||||
* @method preventDefault
|
||||
* @param {Event} ev the event
|
||||
* @static
|
||||
*/
|
||||
preventDefault: function(ev) {
|
||||
if (ev.preventDefault) {
|
||||
ev.preventDefault();
|
||||
} else {
|
||||
ev.returnValue = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the event's target element. Safari sometimes provides
|
||||
* a text node, and this is automatically resolved to the text
|
||||
* node's parent so that it behaves like other browsers.
|
||||
* @method getTarget
|
||||
* @param {Event} ev the event
|
||||
* @param {boolean} resolveTextNode when set to true the target's
|
||||
* parent will be returned if the target is a
|
||||
* text node. @deprecated, the text node is
|
||||
* now resolved automatically
|
||||
* @return {HTMLElement} the event's target
|
||||
* @static
|
||||
*/
|
||||
getTarget: function(ev, resolveTextNode) {
|
||||
var t = ev.target || ev.srcElement;
|
||||
return this.resolveTextNode(t);
|
||||
},
|
||||
|
||||
/**
|
||||
* In some cases, some browsers will return a text node inside
|
||||
* the actual element that was targeted. This normalizes the
|
||||
* return value for getTarget and getRelatedTarget.
|
||||
* @method resolveTextNode
|
||||
* @param {HTMLElement} node node to resolve
|
||||
* @return {HTMLElement} the normized node
|
||||
* @static
|
||||
*/
|
||||
resolveTextNode: function(node) {
|
||||
if (node && 3 == node.nodeType) {
|
||||
return node.parentNode;
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* We cache elements bound by id because when the unload event
|
||||
* fires, we can no longer use document.getElementById
|
||||
* @method getEl
|
||||
* @static
|
||||
* @private
|
||||
* @deprecated Elements are not cached any longer
|
||||
*/
|
||||
getEl: function(id) {
|
||||
return Y.get(id);
|
||||
}
|
||||
};
|
||||
|
||||
Y.mix(Y.Event, o);
|
||||
|
||||
/**
|
||||
* Calls Y.Event.attach with the correct argument order
|
||||
* @method removeListener
|
||||
*/
|
||||
Y.Event.removeListener = function(el, type, fn, data, override) {
|
||||
|
||||
var context, a=[type, fn, el];
|
||||
|
||||
if (data) {
|
||||
|
||||
if (override) {
|
||||
context = (override === true) ? data : override;
|
||||
}
|
||||
|
||||
a.push(context);
|
||||
a.push(data);
|
||||
}
|
||||
|
||||
a.push(COMPAT_ARG);
|
||||
|
||||
return Y.Event.detach.apply(Y.Event, a);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calls Y.Event.detach with the correct argument order
|
||||
* @method addListener
|
||||
*/
|
||||
Y.Event.addListener = function(el, type, fn, data, override) {
|
||||
|
||||
|
||||
// var a = Y.Array(arguments, 0, true), el = a.shift();
|
||||
// a.splice(2, 0, el);
|
||||
// return Y.Event.attach.apply(Y.Event, a);
|
||||
var context, a=[type, fn, el];
|
||||
|
||||
if (data) {
|
||||
|
||||
if (override) {
|
||||
context = (override === true) ? data : override;
|
||||
}
|
||||
|
||||
a.push(context);
|
||||
a.push(data);
|
||||
}
|
||||
|
||||
a.push(COMPAT_ARG);
|
||||
|
||||
return Y.Event.attach.apply(Y.Event, a);
|
||||
};
|
||||
|
||||
Y.Event.on = Y.Event.addListener;
|
||||
|
||||
var newOnavail = Y.Event.onAvailable;
|
||||
|
||||
Y.Event.onAvailable = function(id, fn, p_obj, p_override) {
|
||||
return newOnavail(id, fn, p_obj, p_override, false, true);
|
||||
};
|
||||
|
||||
Y.Event.onContentReady = function(id, fn, p_obj, p_override) {
|
||||
return newOnavail(id, fn, p_obj, p_override, true, true);
|
||||
};
|
||||
|
||||
Y.Event.onDOMReady = function(fn) {
|
||||
var a = Y.Array(arguments, 0, true);
|
||||
a.unshift('event:ready');
|
||||
return Y.on.apply(Y, a);
|
||||
};
|
||||
|
||||
Y.util.Event = Y.Event;
|
||||
|
||||
var CE = function(type, oScope, silent, signature) {
|
||||
//debugger;
|
||||
|
||||
var o = {
|
||||
context: oScope,
|
||||
silent: silent || false
|
||||
// signature: signature || CE.LIST
|
||||
};
|
||||
|
||||
CE.superclass.constructor.call(this, type, o);
|
||||
|
||||
this.signature = signature || CE.LIST;
|
||||
};
|
||||
|
||||
Y.extend(CE, Y.CustomEvent, {
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Subscriber listener sigature constant. The LIST type returns three
|
||||
* parameters: the event type, the array of args passed to fire, and
|
||||
* the optional custom object
|
||||
* @property YAHOO.util.CustomEvent.LIST
|
||||
* @static
|
||||
* @type int
|
||||
*/
|
||||
CE.LIST = 0;
|
||||
|
||||
/**
|
||||
* Subscriber listener sigature constant. The FLAT type returns two
|
||||
* parameters: the first argument passed to fire and the optional
|
||||
* custom object
|
||||
* @property YAHOO.util.CustomEvent.FLAT
|
||||
* @static
|
||||
* @type int
|
||||
*/
|
||||
CE.FLAT = 1;
|
||||
|
||||
Y.util.CustomEvent = CE;
|
||||
|
||||
var EP = function() {
|
||||
//console.log('Compat CustomEvent constructor executed: ' + this._yuid);
|
||||
if (!this._yuievt) {
|
||||
var sub = this.subscribe;
|
||||
Y.EventTarget.apply(this, arguments);
|
||||
this.subscribe = sub;
|
||||
this.__yuiepinit = function() {};
|
||||
}
|
||||
};
|
||||
|
||||
Y.extend(EP, Y.EventTarget, {
|
||||
|
||||
createEvent: function(type, o) {
|
||||
o = o || {};
|
||||
o.signature = o.signature || CE.FLAT;
|
||||
return this.publish(type, o);
|
||||
},
|
||||
|
||||
subscribe: function(type, fn, obj, override) {
|
||||
var ce = this._yuievt.events[type] || this.createEvent(type),
|
||||
a = Y.Array(arguments);
|
||||
|
||||
if (override && true !== override) {
|
||||
// a[2] = override;
|
||||
// a[1] = obj;
|
||||
}
|
||||
|
||||
Y.EventTarget.prototype.subscribe.apply(this, a);
|
||||
},
|
||||
|
||||
fireEvent: function(type) {
|
||||
return this.fire.apply(this, arguments);
|
||||
},
|
||||
|
||||
hasEvent: function(type) {
|
||||
return this.getEvent(type);
|
||||
}
|
||||
});
|
||||
|
||||
Y.util.EventProvider = EP;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Y.register("event", Y, {version: "3.0.0", build: "1549"});
|
||||
|
||||
|
||||
var propertyCache = {};
|
||||
var patterns = {
|
||||
HYPHEN: /(-[a-z])/i, // to normalize get/setStyle
|
||||
ROOT_TAG: /^body|html$/i, // body for quirks mode, html for standards,
|
||||
OP_SCROLL:/^(?:inline|table-row)$/i
|
||||
};
|
||||
|
||||
var hyphenToCamel = function(property) {
|
||||
if ( !patterns.HYPHEN.test(property) ) {
|
||||
return property; // no hyphens
|
||||
}
|
||||
|
||||
if (propertyCache[property]) { // already converted
|
||||
return propertyCache[property];
|
||||
}
|
||||
|
||||
var converted = property;
|
||||
|
||||
while( patterns.HYPHEN.exec(converted) ) {
|
||||
converted = converted.replace(RegExp.$1,
|
||||
RegExp.$1.substr(1).toUpperCase());
|
||||
}
|
||||
|
||||
propertyCache[property] = converted;
|
||||
return converted;
|
||||
//return property.replace(/-([a-z])/gi, function(m0, m1) {return m1.toUpperCase()}) // cant use function as 2nd arg yet due to safari bug
|
||||
};
|
||||
|
||||
var Dom = {
|
||||
get: function(el) {
|
||||
if (el) {
|
||||
if (el.nodeType || el.item) { // Node, or NodeList
|
||||
return el;
|
||||
}
|
||||
|
||||
if (typeof el === 'string') { // id
|
||||
return document.getElementById(el);
|
||||
}
|
||||
|
||||
if ('length' in el) { // array-like
|
||||
var c = [];
|
||||
for (var i = 0, len = el.length; i < len; ++i) {
|
||||
c[c.length] = Dom.get(el[i]);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
return el; // some other object, just pass it back
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
isAncestor: function(haystack, needle) {
|
||||
return YUI.DOM.contains(Dom.get(haystack), Dom.get(needle));
|
||||
},
|
||||
|
||||
inDocument: function(el) {
|
||||
return Dom.isAncestor(Y.config.doc.documentElement, el);
|
||||
},
|
||||
|
||||
batch: function(el, method, o, override, args) {
|
||||
el = (el && (el.tagName || el.item)) ? el : Dom.get(el); // skip get() when possible
|
||||
|
||||
if (!el || !method) {
|
||||
return false;
|
||||
}
|
||||
if (args) {
|
||||
args = Y.Array(args);
|
||||
}
|
||||
var scope = (override) ? o : window;
|
||||
|
||||
var apply = function(el) {
|
||||
if (args) {
|
||||
var tmp = slice.call(args);
|
||||
tmp.unshift(el);
|
||||
return method.apply(scope, tmp);
|
||||
} else {
|
||||
return method.call(scope, el, o);
|
||||
}
|
||||
};
|
||||
|
||||
if (el.tagName || el.length === undefined) { // element or not array-like
|
||||
return apply(el);
|
||||
}
|
||||
|
||||
var collection = [];
|
||||
|
||||
for (var i = 0, len = el.length; i < len; ++i) {
|
||||
collection[collection.length] = apply(el[i]);
|
||||
}
|
||||
|
||||
return collection;
|
||||
},
|
||||
|
||||
// 2.x returns false if already present
|
||||
_addClass: function(el, className) {
|
||||
if ( YUI.DOM.hasClass(el, className) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
YUI.DOM.addClass(el, className);
|
||||
return true;
|
||||
},
|
||||
|
||||
// 2.x returns false if not present
|
||||
_removeClass: function(el, className) {
|
||||
if ( !YUI.DOM.hasClass(el, className) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
YUI.DOM.removeClass(el, className);
|
||||
return true;
|
||||
},
|
||||
|
||||
// 2.x returns false if no newClass or same as oldClass
|
||||
_replaceClass: function(el, oldClass, newClass) {
|
||||
if (!newClass || oldClass === newClass) {
|
||||
return false;
|
||||
}
|
||||
|
||||
YUI.DOM.replaceClass(el, oldClass, newClass);
|
||||
return true;
|
||||
},
|
||||
|
||||
getElementsByClassName: function(className, tag, root) {
|
||||
tag = tag || '*';
|
||||
root = (root) ? Dom.get(root) : Y.config.doc;
|
||||
var nodes = [];
|
||||
if (root) {
|
||||
nodes = Y.Selector.query(tag + '.' + className, root);
|
||||
}
|
||||
return nodes;
|
||||
},
|
||||
|
||||
getElementsBy: function(method, tag, root) {
|
||||
tag = tag || '*';
|
||||
root = (root) ? Dom.get(root) : null || document;
|
||||
|
||||
var nodes = [];
|
||||
if (root) {
|
||||
nodes = YUI.DOM.byTag(tag, root, method);
|
||||
}
|
||||
return nodes;
|
||||
},
|
||||
|
||||
getViewportWidth: YUI.DOM.winWidth,
|
||||
getViewportHeight: YUI.DOM.winHeight,
|
||||
getDocumentWidth: YUI.DOM.docWidth,
|
||||
getDocumentHeight: YUI.DOM.docHeight,
|
||||
getDocumentScrollTop: YUI.DOM.docScrollY,
|
||||
getDocumentScrollLeft: YUI.DOM.docScrollX,
|
||||
getDocumentHeight: YUI.DOM.docHeight,
|
||||
|
||||
_guid: function(el, prefix) {
|
||||
prefix = prefix || 'yui-gen';
|
||||
Dom._id_counter = Dom._id_counter || 0;
|
||||
|
||||
if (el && el.id) { // do not override existing ID
|
||||
return el.id;
|
||||
}
|
||||
|
||||
var id = prefix + Dom._id_counter++;
|
||||
|
||||
if (el) {
|
||||
el.id = id;
|
||||
}
|
||||
|
||||
return id;
|
||||
},
|
||||
|
||||
_region: function(el) {
|
||||
if ( (el.parentNode === null || el.offsetParent === null ||
|
||||
YUI.DOM.getStyle(el, 'display') == 'none') && el != el.ownerDocument.body) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return YUI.DOM.region(el);
|
||||
|
||||
},
|
||||
|
||||
_ancestorByClass: function(element, className) {
|
||||
return YUI.DOM.ancestor(element, function(el) {
|
||||
return YUI.DOM.hasClass(el, className);
|
||||
});
|
||||
},
|
||||
|
||||
_ancestorByTag: function(element, tag) {
|
||||
tag = tag.toUpperCase();
|
||||
return YUI.DOM.ancestor(element, function(el) {
|
||||
return el.tagName.toUpperCase() === tag;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var slice = [].slice;
|
||||
|
||||
var wrap = function(fn, name) {
|
||||
Dom[name] = function() {
|
||||
var args = slice.call(arguments);
|
||||
args[0] = Dom.get(args[0]);
|
||||
return fn.apply(Dom, args);
|
||||
};
|
||||
};
|
||||
|
||||
var wrapped = {
|
||||
getAncestorBy: YUI.DOM.ancestor,
|
||||
getAncestorByClassName: Dom._ancestorByClass,
|
||||
getAncestorByTagName: Dom._ancestorByTag,
|
||||
getPreviousSiblingBy: YUI.DOM.previous,
|
||||
getPreviousSibling: YUI.DOM.previous,
|
||||
getNextSiblingBy: YUI.DOM.next,
|
||||
getNextSibling: YUI.DOM.next,
|
||||
getFirstChildBy: YUI.DOM.firstChild,
|
||||
getFirstChild: YUI.DOM.firstChild,
|
||||
getLastChildBy: YUI.DOM.lastChild,
|
||||
getLastChild: YUI.DOM.lastChild,
|
||||
getChildrenBy: YUI.DOM.children,
|
||||
getChildren: YUI.DOM.children,
|
||||
insertBefore: function(newNode, refNode) {
|
||||
YUI.DOM.insertBefore(Dom.get(newNode), Dom.get(refNode));
|
||||
},
|
||||
insertAfter: function(newNode, refNode) {
|
||||
YUI.DOM.insertAfter(Dom.get(newNode), Dom.get(refNode));
|
||||
}
|
||||
};
|
||||
|
||||
Y.each(wrapped, wrap);
|
||||
|
||||
var batched = {
|
||||
getStyle: YUI.DOM.getStyle,
|
||||
setStyle: YUI.DOM.setStyle,
|
||||
getXY: YUI.DOM.getXY,
|
||||
setXY: YUI.DOM.setXY,
|
||||
getX: YUI.DOM.getX,
|
||||
getY: YUI.DOM.getY,
|
||||
setX: YUI.DOM.setX,
|
||||
setY: YUI.DOM.setY,
|
||||
getRegion: Dom._region,
|
||||
hasClass: YUI.DOM.hasClass,
|
||||
addClass: Dom._addClass,
|
||||
removeClass: Dom._removeClass,
|
||||
replaceClass: Dom._replaceClass,
|
||||
generateId: Dom._guid
|
||||
};
|
||||
|
||||
Y.each(batched, function(v, n) {
|
||||
Dom[n] = function(el) {
|
||||
var args = slice.call(arguments, 1);
|
||||
return Dom.batch(el, v, null, null, args);
|
||||
};
|
||||
});
|
||||
|
||||
Y.util.Dom = Dom;
|
||||
|
||||
YAHOO.util.Region = function(t, r, b, l) {
|
||||
this.top = t;
|
||||
this[1] = t;
|
||||
this.right = r;
|
||||
this.bottom = b;
|
||||
this.left = l;
|
||||
this[0] = l;
|
||||
};
|
||||
|
||||
YAHOO.util.Region.prototype.contains = function(region) {
|
||||
return ( region.left >= this.left &&
|
||||
region.right <= this.right &&
|
||||
region.top >= this.top &&
|
||||
region.bottom <= this.bottom );
|
||||
|
||||
};
|
||||
|
||||
YAHOO.util.Region.prototype.getArea = function() {
|
||||
return ( (this.bottom - this.top) * (this.right - this.left) );
|
||||
};
|
||||
|
||||
YAHOO.util.Region.prototype.intersect = function(region) {
|
||||
var t = Math.max( this.top, region.top );
|
||||
var r = Math.min( this.right, region.right );
|
||||
var b = Math.min( this.bottom, region.bottom );
|
||||
var l = Math.max( this.left, region.left );
|
||||
|
||||
if (b >= t && r >= l) {
|
||||
return new YAHOO.util.Region(t, r, b, l);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
YAHOO.util.Region.prototype.union = function(region) {
|
||||
var t = Math.min( this.top, region.top );
|
||||
var r = Math.max( this.right, region.right );
|
||||
var b = Math.max( this.bottom, region.bottom );
|
||||
var l = Math.min( this.left, region.left );
|
||||
|
||||
return new YAHOO.util.Region(t, r, b, l);
|
||||
};
|
||||
|
||||
YAHOO.util.Region.prototype.toString = function() {
|
||||
return ( "Region {" +
|
||||
"top: " + this.top +
|
||||
", right: " + this.right +
|
||||
", bottom: " + this.bottom +
|
||||
", left: " + this.left +
|
||||
"}" );
|
||||
};
|
||||
|
||||
YAHOO.util.Region.getRegion = function(el) {
|
||||
return YUI.DOM.region(el);
|
||||
};
|
||||
|
||||
YAHOO.util.Point = function(x, y) {
|
||||
if (YAHOO.lang.isArray(x)) { // accept input from Dom.getXY, Event.getXY, etc.
|
||||
y = x[1]; // dont blow away x yet
|
||||
x = x[0];
|
||||
}
|
||||
|
||||
this.x = this.right = this.left = this[0] = x;
|
||||
this.y = this.top = this.bottom = this[1] = y;
|
||||
};
|
||||
|
||||
YAHOO.util.Point.prototype = new YAHOO.util.Region();
|
||||
|
||||
|
||||
|
||||
}, '3.0.0' ,{requires:['dom','event']});
|
||||
YUI._setup(); YUI.use('dom', 'event', 'compat');
|
||||
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
|
After Width: | Height: | Size: 219 B |
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
.yui-skin-sam .yui-console-ft .yui-console-filters-categories,
|
||||
.yui-skin-sam .yui-console-ft .yui-console-filters-sources {
|
||||
text-align: left;
|
||||
padding: 5px 0;
|
||||
border: 1px inset;
|
||||
margin: 0 2px;
|
||||
}
|
||||
.yui-skin-sam .yui-console-ft .yui-console-filters-categories {
|
||||
background: #fff;
|
||||
border-bottom: 2px ridge;
|
||||
}
|
||||
.yui-skin-sam .yui-console-ft .yui-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;
|
||||
}
|
||||
.yui-skin-sam .yui-console-filter-label {
|
||||
white-space: nowrap;
|
||||
margin-left: 1ex;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
.yui-skin-sam .yui-console-ft .yui-console-filters-categories,.yui-skin-sam .yui-console-ft .yui-console-filters-sources{text-align:left;padding:5px 0;border:1px inset;margin:0 2px;}.yui-skin-sam .yui-console-ft .yui-console-filters-categories{background:#fff;border-bottom:2px ridge;}.yui-skin-sam .yui-console-ft .yui-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;}.yui-skin-sam .yui-console-filter-label{white-space:nowrap;margin-left:1ex;}
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
.yui-skin-sam .yui-separate-console {
|
||||
position:absolute;
|
||||
right:1em;
|
||||
top:1em;
|
||||
z-index:999;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-inline-console {
|
||||
/* xbrowser inline-block styles */
|
||||
display: -moz-inline-stack; /* FF2 */
|
||||
display: inline-block;
|
||||
*display: inline; /* IE 7- (with zoom) */
|
||||
zoom: 1;
|
||||
vertical-align: top;
|
||||
}
|
||||
.yui-skin-sam .yui-inline-console .yui-console-content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-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;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-console-hd,
|
||||
.yui-skin-sam .yui-console-bd,
|
||||
.yui-skin-sam .yui-console-ft {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-console-hd,
|
||||
.yui-skin-sam .yui-console-ft .yui-console-controls {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-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;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-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%;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-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;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-console-controls {
|
||||
padding: 4px 1ex;
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-console-title {
|
||||
color: #000;
|
||||
display: inline;
|
||||
float: left;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
margin: 0;
|
||||
padding-left: 1ex;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-console-pause-label {
|
||||
float: left;
|
||||
}
|
||||
.yui-skin-sam .yui-console-button {
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-console-collapsed .yui-console-bd,
|
||||
.yui-skin-sam .yui-console-collapsed .yui-console-ft {
|
||||
display: none;
|
||||
}
|
||||
.yui-skin-sam .yui-console-content.yui-console-collapsed {
|
||||
-webkit-border-radius: 0;
|
||||
}
|
||||
.yui-skin-sam .yui-console-collapsed .yui-console-hd {
|
||||
border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 0;
|
||||
}
|
||||
|
||||
/* Log entries */
|
||||
.yui-skin-sam .yui-console-entry {
|
||||
border-bottom: 1px solid #aaa;
|
||||
min-height: 32px;
|
||||
_height: 32px;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-console-entry-meta {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-console-entry-content {
|
||||
margin: 0;
|
||||
padding: 0 1ex;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-console-entry-meta .yui-console-entry-src {
|
||||
color: #000;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
float: right;
|
||||
margin: 2px 5px 0 0;
|
||||
}
|
||||
.yui-skin-sam .yui-console-entry-meta .yui-console-entry-time {
|
||||
color: #777;
|
||||
padding-left: 1ex;
|
||||
}
|
||||
.yui-skin-sam .yui-console-entry-warn .yui-console-entry-meta .yui-console-entry-time {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-console-entry-info .yui-console-entry-meta .yui-console-entry-cat,
|
||||
.yui-skin-sam .yui-console-entry-warn .yui-console-entry-meta .yui-console-entry-cat,
|
||||
.yui-skin-sam .yui-console-entry-error .yui-console-entry-meta .yui-console-entry-cat {
|
||||
display: none;
|
||||
}
|
||||
.yui-skin-sam .yui-console-entry-warn {
|
||||
background: #aee url(warn_error.png) no-repeat -15px 15px;
|
||||
}
|
||||
.yui-skin-sam .yui-console-entry-error {
|
||||
background: #ffa url(warn_error.png) no-repeat 5px -24px;
|
||||
color: #900;
|
||||
}
|
||||
.yui-skin-sam .yui-console-entry-warn .yui-console-entry-content,
|
||||
.yui-skin-sam .yui-console-entry-error .yui-console-entry-content {
|
||||
padding-left: 24px;
|
||||
}
|
||||
.yui-skin-sam .yui-console-entry-cat {
|
||||
text-transform: uppercase;
|
||||
padding: 1px 4px;
|
||||
background-color: #ccc;
|
||||
}
|
||||
.yui-skin-sam .yui-console-entry-info .yui-console-entry-cat {
|
||||
background-color: #ac2;
|
||||
}
|
||||
.yui-skin-sam .yui-console-entry-warn .yui-console-entry-cat {
|
||||
background-color: #e81;
|
||||
}
|
||||
.yui-skin-sam .yui-console-entry-error .yui-console-entry-cat {
|
||||
background-color: #b00;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.yui-skin-sam .yui-console-hidden { display: none; }
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
.yui-skin-sam .yui-separate-console{position:absolute;right:1em;top:1em;z-index:999;}.yui-skin-sam .yui-inline-console{display:-moz-inline-stack;display:inline-block;*display:inline;zoom:1;vertical-align:top;}.yui-skin-sam .yui-inline-console .yui-console-content{position:relative;}.yui-skin-sam .yui-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;}.yui-skin-sam .yui-console-hd,.yui-skin-sam .yui-console-bd,.yui-skin-sam .yui-console-ft{position:relative;}.yui-skin-sam .yui-console-hd,.yui-skin-sam .yui-console-ft .yui-console-controls{text-align:right;}.yui-skin-sam .yui-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;}.yui-skin-sam .yui-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%;}.yui-skin-sam .yui-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;}.yui-skin-sam .yui-console-controls{padding:4px 1ex;zoom:1;}.yui-skin-sam .yui-console-title{color:#000;display:inline;float:left;font-weight:bold;font-size:13px;height:24px;line-height:24px;margin:0;padding-left:1ex;}.yui-skin-sam .yui-console-pause-label{float:left;}.yui-skin-sam .yui-console-button{line-height:1.3;}.yui-skin-sam .yui-console-collapsed .yui-console-bd,.yui-skin-sam .yui-console-collapsed .yui-console-ft{display:none;}.yui-skin-sam .yui-console-content.yui-console-collapsed{-webkit-border-radius:0;}.yui-skin-sam .yui-console-collapsed .yui-console-hd{border-radius:10px;-moz-border-radius:10px;-webkit-border-radius:0;}.yui-skin-sam .yui-console-entry{border-bottom:1px solid #aaa;min-height:32px;_height:32px;}.yui-skin-sam .yui-console-entry-meta{margin:0;overflow:hidden;}.yui-skin-sam .yui-console-entry-content{margin:0;padding:0 1ex;white-space:pre-wrap;word-wrap:break-word;}.yui-skin-sam .yui-console-entry-meta .yui-console-entry-src{color:#000;font-style:italic;font-weight:bold;float:right;margin:2px 5px 0 0;}.yui-skin-sam .yui-console-entry-meta .yui-console-entry-time{color:#777;padding-left:1ex;}.yui-skin-sam .yui-console-entry-warn .yui-console-entry-meta .yui-console-entry-time{color:#555;}.yui-skin-sam .yui-console-entry-info .yui-console-entry-meta .yui-console-entry-cat,.yui-skin-sam .yui-console-entry-warn .yui-console-entry-meta .yui-console-entry-cat,.yui-skin-sam .yui-console-entry-error .yui-console-entry-meta .yui-console-entry-cat{display:none;}.yui-skin-sam .yui-console-entry-warn{background:#aee url(warn_error.png) no-repeat -15px 15px;}.yui-skin-sam .yui-console-entry-error{background:#ffa url(warn_error.png) no-repeat 5px -24px;color:#900;}.yui-skin-sam .yui-console-entry-warn .yui-console-entry-content,.yui-skin-sam .yui-console-entry-error .yui-console-entry-content{padding-left:24px;}.yui-skin-sam .yui-console-entry-cat{text-transform:uppercase;padding:1px 4px;background-color:#ccc;}.yui-skin-sam .yui-console-entry-info .yui-console-entry-cat{background-color:#ac2;}.yui-skin-sam .yui-console-entry-warn .yui-console-entry-cat{background-color:#e81;}.yui-skin-sam .yui-console-entry-error .yui-console-entry-cat{background-color:#b00;color:#fff;}.yui-skin-sam .yui-console-hidden{display:none;}
|
||||
|
After Width: | Height: | Size: 703 B |
|
After Width: | Height: | Size: 703 B |
@@ -0,0 +1,710 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add('console-filters', function(Y) {
|
||||
|
||||
/**
|
||||
* <p>Provides Plugin.ConsoleFilters plugin class.</p>
|
||||
*
|
||||
* <p>This plugin adds the ability to control which Console entries display by filtering on category and source. Two groups of checkboxes are added to the Console footer, one for categories and the other for sources. Only those messages that match a checked category or source are displayed.</p>
|
||||
*
|
||||
* @module console-filters
|
||||
* @namespace Plugin
|
||||
* @class ConsoleFilters
|
||||
*/
|
||||
|
||||
// Some common strings and functions
|
||||
var getCN = Y.ClassNameManager.getClassName,
|
||||
CONSOLE = 'console',
|
||||
FILTERS = 'filters',
|
||||
FILTER = 'filter',
|
||||
CATEGORY = 'category',
|
||||
SOURCE = 'source',
|
||||
CATEGORY_DOT = 'category.',
|
||||
SOURCE_DOT = 'source.',
|
||||
|
||||
HOST = 'host',
|
||||
PARENT_NODE = 'parentNode',
|
||||
CHECKED = 'checked',
|
||||
DEF_VISIBILITY = 'defaultVisibility',
|
||||
|
||||
DOT = '.',
|
||||
EMPTY = '',
|
||||
|
||||
C_BODY = DOT + Y.Console.CHROME_CLASSES.console_bd_class,
|
||||
C_FOOT = DOT + Y.Console.CHROME_CLASSES.console_ft_class,
|
||||
|
||||
SEL_CHECK = 'input[type=checkbox].',
|
||||
|
||||
isString = Y.Lang.isString;
|
||||
|
||||
function ConsoleFilters() {
|
||||
ConsoleFilters.superclass.constructor.apply(this,arguments);
|
||||
}
|
||||
|
||||
Y.mix(ConsoleFilters,{
|
||||
/**
|
||||
* Plugin name.
|
||||
*
|
||||
* @property ConsoleFilters.NAME
|
||||
* @type String
|
||||
* @static
|
||||
* @default 'consoleFilters'
|
||||
*/
|
||||
NAME : 'consoleFilters',
|
||||
|
||||
/**
|
||||
* The namespace hung off the host object that this plugin will inhabit.
|
||||
*
|
||||
* @property ConsoleFilters.NS
|
||||
* @type String
|
||||
* @static
|
||||
* @default 'filter'
|
||||
*/
|
||||
NS : FILTER,
|
||||
|
||||
/**
|
||||
* Markup template used to create the container for the category filters.
|
||||
*
|
||||
* @property ConsoleFilters.CATEGORIES_TEMPLATE
|
||||
* @type String
|
||||
* @static
|
||||
*/
|
||||
CATEGORIES_TEMPLATE :
|
||||
'<div class="{categories}"></div>',
|
||||
|
||||
/**
|
||||
* Markup template used to create the container for the source filters.
|
||||
*
|
||||
* @property ConsoleFilters.SOURCES_TEMPLATE
|
||||
* @type String
|
||||
* @static
|
||||
*/
|
||||
SOURCES_TEMPLATE :
|
||||
'<div class="{sources}"></div>',
|
||||
|
||||
/**
|
||||
* Markup template used to create the category and source filter checkboxes.
|
||||
*
|
||||
* @property ConsoleFilters.FILTER_TEMPLATE
|
||||
* @type String
|
||||
* @static
|
||||
*/
|
||||
FILTER_TEMPLATE :
|
||||
// IE8 and FF3 don't permit breaking _between_ nowrap elements. IE8
|
||||
// doesn't understand (non spec) wbr tag, nor does it create text nodes
|
||||
// for spaces in innerHTML strings. The thin-space entity suffices to
|
||||
// create a breakable point.
|
||||
'<label class="{filter_label}">'+
|
||||
'<input type="checkbox" value="{filter_name}" '+
|
||||
'class="{filter} {filter_class}"> {filter_name}'+
|
||||
'</label> ',
|
||||
|
||||
/**
|
||||
* Classnames used by the templates when creating nodes.
|
||||
*
|
||||
* @property ConsoleFilters.CHROME_CLASSES
|
||||
* @type Object
|
||||
* @static
|
||||
* @protected
|
||||
*/
|
||||
CHROME_CLASSES : {
|
||||
categories : getCN(CONSOLE,FILTERS,'categories'),
|
||||
sources : getCN(CONSOLE,FILTERS,'sources'),
|
||||
category : getCN(CONSOLE,FILTER,CATEGORY),
|
||||
source : getCN(CONSOLE,FILTER,SOURCE),
|
||||
filter : getCN(CONSOLE,FILTER),
|
||||
filter_label : getCN(CONSOLE,FILTER,'label')
|
||||
},
|
||||
|
||||
ATTRS : {
|
||||
/**
|
||||
* Default visibility applied to new categories and sources.
|
||||
*
|
||||
* @attribute defaultVisibility
|
||||
* @type {Boolean}
|
||||
* @default true
|
||||
*/
|
||||
defaultVisibility : {
|
||||
value : true,
|
||||
validator : Y.Lang.isBoolean
|
||||
},
|
||||
|
||||
/**
|
||||
* <p>Map of entry categories to their visibility status. Update a
|
||||
* particular category's visibility by setting the subattribute to true
|
||||
* (visible) or false (hidden).</p>
|
||||
*
|
||||
* <p>For example, yconsole.filter.set('category.info', false) to hide
|
||||
* log entries with the category/logLevel of 'info'.</p>
|
||||
*
|
||||
* <p>Similarly, yconsole.filter.get('category.warn') will return a
|
||||
* boolean indicating whether that category is currently being included
|
||||
* in the UI.</p>
|
||||
*
|
||||
* <p>Unlike the YUI instance configuration's logInclude and logExclude
|
||||
* properties, filtered entries are only hidden from the UI, but
|
||||
* can be made visible again.</p>
|
||||
*
|
||||
* @attribute category
|
||||
* @type Object
|
||||
*/
|
||||
category : {
|
||||
value : {},
|
||||
validator : function (v,k) {
|
||||
return this._validateCategory(k,v);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* <p>Map of entry sources to their visibility status. Update a
|
||||
* particular sources's visibility by setting the subattribute to true
|
||||
* (visible) or false (hidden).</p>
|
||||
*
|
||||
* <p>For example, yconsole.filter.set('sources.slider', false) to hide
|
||||
* log entries originating from Y.Slider.</p>
|
||||
*
|
||||
* @attribute source
|
||||
* @type Object
|
||||
*/
|
||||
source : {
|
||||
value : {},
|
||||
validator : function (v,k) {
|
||||
return this._validateSource(k,v);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Maximum number of entries to store in the message cache. Use this to
|
||||
* limit the memory footprint in environments with heavy log usage.
|
||||
* By default, there is no limit (Number.POSITIVE_INFINITY).
|
||||
*
|
||||
* @attribute cacheLimit
|
||||
* @type {Number}
|
||||
* @default Number.POSITIVE_INFINITY
|
||||
*/
|
||||
cacheLimit : {
|
||||
value : Number.POSITIVE_INFINITY,
|
||||
setter : function (v) {
|
||||
if (Y.Lang.isNumber(v)) {
|
||||
this._cacheLimit = v;
|
||||
return v;
|
||||
} else {
|
||||
return Y.Attribute.INVALID_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Y.extend(ConsoleFilters, Y.Plugin.Base, {
|
||||
|
||||
/**
|
||||
* Collection of all log messages passed through since the plugin's
|
||||
* instantiation. This holds all messages regardless of filter status.
|
||||
* Used as a single source of truth for repopulating the Console body when
|
||||
* filters are changed.
|
||||
*
|
||||
* @property _entries
|
||||
* @type Array
|
||||
* @protected
|
||||
*/
|
||||
_entries : null,
|
||||
|
||||
_cacheLimit : Number.POSITIVE_INFINITY,
|
||||
|
||||
/**
|
||||
* The container node created to house the category filters.
|
||||
*
|
||||
* @property _categories
|
||||
* @type Node
|
||||
* @protected
|
||||
*/
|
||||
_categories : null,
|
||||
|
||||
/**
|
||||
* The container node created to house the source filters.
|
||||
*
|
||||
* @property _sources
|
||||
* @type Node
|
||||
* @protected
|
||||
*/
|
||||
_sources : null,
|
||||
|
||||
/**
|
||||
* Initialize entries collection and attach listeners to host events and
|
||||
* methods.
|
||||
*
|
||||
* @method initializer
|
||||
* @protected
|
||||
*/
|
||||
initializer : function () {
|
||||
this._entries = [];
|
||||
|
||||
this.get(HOST).on("entry", this._onEntry, this);
|
||||
|
||||
this.doAfter("renderUI", this.renderUI);
|
||||
this.doAfter("syncUI", this.syncUI);
|
||||
this.doAfter("bindUI", this.bindUI);
|
||||
|
||||
this.doAfter("clearConsole", this._afterClearConsole);
|
||||
|
||||
if (this.get(HOST).get('rendered')) {
|
||||
this.renderUI();
|
||||
this.syncUI();
|
||||
this.bindUI();
|
||||
}
|
||||
|
||||
this.after("cacheLimitChange", this._afterCacheLimitChange);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the plugin UI and unwires events.
|
||||
*
|
||||
* @method destructor
|
||||
* @protected
|
||||
*/
|
||||
destructor : function () {
|
||||
//TODO: grab last {consoleLimit} entries and update the console with
|
||||
//them (no filtering)
|
||||
this._entries = [];
|
||||
|
||||
if (this._categories) {
|
||||
this._categories.get(PARENT_NODE).removeChild(this._categories);
|
||||
}
|
||||
if (this._sources) {
|
||||
this._sources.get(PARENT_NODE).removeChild(this._sources);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the category and source filter sections to the Console footer.
|
||||
*
|
||||
* @method renderUI
|
||||
* @protected
|
||||
*/
|
||||
renderUI : function () {
|
||||
var foot = this.get(HOST).get('contentBox').query(C_FOOT),
|
||||
html;
|
||||
|
||||
if (foot) {
|
||||
html = Y.substitute(
|
||||
ConsoleFilters.CATEGORIES_TEMPLATE,
|
||||
ConsoleFilters.CHROME_CLASSES);
|
||||
|
||||
this._categories = foot.appendChild(Y.Node.create(html));
|
||||
|
||||
html = Y.substitute(
|
||||
ConsoleFilters.SOURCES_TEMPLATE,
|
||||
ConsoleFilters.CHROME_CLASSES);
|
||||
|
||||
this._sources = foot.appendChild(Y.Node.create(html));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Binds to checkbox click events and internal attribute change events to
|
||||
* maintain the UI state.
|
||||
*
|
||||
* @method bindUI
|
||||
* @protected
|
||||
*/
|
||||
bindUI : function () {
|
||||
this._categories.on('click', Y.bind(this._onCategoryCheckboxClick, this));
|
||||
|
||||
this._sources.on('click', Y.bind(this._onSourceCheckboxClick, this));
|
||||
|
||||
this.after('categoryChange',this._afterCategoryChange);
|
||||
this.after('sourceChange', this._afterSourceChange);
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the UI to be in accordance with the current state of the plugin.
|
||||
*
|
||||
* @method syncUI
|
||||
*/
|
||||
syncUI : function () {
|
||||
Y.each(this.get(CATEGORY), function (v, k) {
|
||||
this._uiSetCheckbox(CATEGORY, k, v);
|
||||
}, this);
|
||||
|
||||
Y.each(this.get(SOURCE), function (v, k) {
|
||||
this._uiSetCheckbox(SOURCE, k, v);
|
||||
}, this);
|
||||
|
||||
this.refreshConsole();
|
||||
},
|
||||
|
||||
/**
|
||||
* Ensures a filter is set up for any new categories or sources and
|
||||
* collects the messages in _entries. If the message is stamped with a
|
||||
* category or source that is currently being filtered out, the message
|
||||
* will not pass to the Console's print buffer.
|
||||
*
|
||||
* @method _onEntry
|
||||
* @param e {Event} the custom event object
|
||||
* @protected
|
||||
*/
|
||||
_onEntry : function (e) {
|
||||
this._entries.push(e.message);
|
||||
|
||||
var cat = CATEGORY_DOT + e.message.category,
|
||||
src = SOURCE_DOT + e.message.source,
|
||||
cat_filter = this.get(cat),
|
||||
src_filter = this.get(src),
|
||||
overLimit = this._entries.length - this._cacheLimit,
|
||||
visible;
|
||||
|
||||
if (overLimit > 0) {
|
||||
this._entries.splice(0, overLimit);
|
||||
}
|
||||
|
||||
if (cat_filter === undefined) {
|
||||
visible = this.get(DEF_VISIBILITY);
|
||||
this.set(cat, visible);
|
||||
cat_filter = visible;
|
||||
}
|
||||
|
||||
if (src_filter === undefined) {
|
||||
visible = this.get(DEF_VISIBILITY);
|
||||
this.set(src, visible);
|
||||
src_filter = visible;
|
||||
}
|
||||
|
||||
if (!cat_filter || !src_filter) {
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Flushes the cached entries after a call to the Console's clearConsole().
|
||||
*
|
||||
* @method _afterClearConsole
|
||||
* @protected
|
||||
*/
|
||||
_afterClearConsole : function () {
|
||||
this._entries = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Triggers the Console to update if a known category filter
|
||||
* changes value (e.g. visible => hidden). Updates the appropriate
|
||||
* checkbox's checked state if necessary.
|
||||
*
|
||||
* @method _afterCategoryChange
|
||||
* @param e {Event} the attribute change event object
|
||||
* @protected
|
||||
*/
|
||||
_afterCategoryChange : function (e) {
|
||||
var cat = e.subAttrName.replace(/category\./, EMPTY),
|
||||
before = e.prevVal,
|
||||
after = e.newVal;
|
||||
|
||||
// Don't update the console for new categories
|
||||
if (!cat || before[cat] !== undefined) {
|
||||
this.refreshConsole();
|
||||
|
||||
this._filterBuffer();
|
||||
}
|
||||
|
||||
if (cat && !e.fromUI) {
|
||||
this._uiSetCheckbox(CATEGORY, cat, after[cat]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Triggers the Console to update if a known source filter
|
||||
* changes value (e.g. visible => hidden). Updates the appropriate
|
||||
* checkbox's checked state if necessary.
|
||||
*
|
||||
* @method _afterSourceChange
|
||||
* @param e {Event} the attribute change event object
|
||||
* @protected
|
||||
*/
|
||||
_afterSourceChange : function (e) {
|
||||
var src = e.subAttrName.replace(/source\./, EMPTY),
|
||||
before = e.prevVal,
|
||||
after = e.newVal;
|
||||
|
||||
// Don't update the console for new sources
|
||||
if (!src || before[src] !== undefined) {
|
||||
this.refreshConsole();
|
||||
|
||||
this._filterBuffer();
|
||||
}
|
||||
|
||||
if (src && !e.fromUI) {
|
||||
this._uiSetCheckbox(SOURCE, src, after[src]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Flushes the Console's print buffer of any entries that have a category
|
||||
* or source that is currently being excluded.
|
||||
*
|
||||
* @method _filterBuffer
|
||||
* @protected
|
||||
*/
|
||||
_filterBuffer : function () {
|
||||
var cats = this.get(CATEGORY),
|
||||
srcs = this.get(SOURCE),
|
||||
buffer = this.get(HOST).buffer,
|
||||
start = null,
|
||||
i;
|
||||
|
||||
for (i = buffer.length - 1; i >= 0; --i) {
|
||||
if (!cats[buffer[i].category] || !srcs[buffer[i].source]) {
|
||||
start = start || i;
|
||||
} else if (start) {
|
||||
buffer.splice(i,(start - i));
|
||||
start = null;
|
||||
}
|
||||
}
|
||||
if (start) {
|
||||
buffer.splice(0,start + 1);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Trims the cache of entries to the appropriate new length.
|
||||
*
|
||||
* @method _afterCacheLimitChange
|
||||
* @param e {Event} the attribute change event object
|
||||
* @protected
|
||||
*/
|
||||
_afterCacheLimitChange : function (e) {
|
||||
if (isFinite(e.newVal)) {
|
||||
var delta = this._entries.length - e.newVal;
|
||||
|
||||
if (delta > 0) {
|
||||
this._entries.splice(0,delta);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Repopulates the Console with entries appropriate to the current filter
|
||||
* settings.
|
||||
*
|
||||
* @method refreshConsole
|
||||
*/
|
||||
refreshConsole : function () {
|
||||
var entries = this._entries,
|
||||
host = this.get(HOST),
|
||||
body = host.get('contentBox').query(C_BODY),
|
||||
remaining = host.get('consoleLimit'),
|
||||
cats = this.get(CATEGORY),
|
||||
srcs = this.get(SOURCE),
|
||||
buffer = [],
|
||||
i,e;
|
||||
|
||||
if (body) {
|
||||
host._cancelPrintLoop();
|
||||
|
||||
// Evaluate all entries from latest to oldest
|
||||
for (i = entries.length - 1; i >= 0 && remaining >= 0; --i) {
|
||||
e = entries[i];
|
||||
if (cats[e.category] && srcs[e.source]) {
|
||||
buffer.unshift(e);
|
||||
--remaining;
|
||||
}
|
||||
}
|
||||
|
||||
body.set('innerHTML',EMPTY);
|
||||
host.buffer = buffer;
|
||||
host.printBuffer();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the checked property of a filter checkbox of the specified type.
|
||||
* If no checkbox is found for the input params, one is created.
|
||||
*
|
||||
* @method _uiSetCheckbox
|
||||
* @param type {String} 'category' or 'source'
|
||||
* @param item {String} the name of the filter (e.g. 'info', 'event')
|
||||
* @param checked {Boolean} value to set the checkbox's checked property
|
||||
* @protected
|
||||
*/
|
||||
_uiSetCheckbox : function (type, item, checked) {
|
||||
if (type && item) {
|
||||
var container = type === CATEGORY ?
|
||||
this._categories :
|
||||
this._sources,
|
||||
sel = SEL_CHECK + getCN(CONSOLE,FILTER,item),
|
||||
checkbox = container.query(sel),
|
||||
host;
|
||||
|
||||
if (!checkbox) {
|
||||
host = this.get(HOST);
|
||||
|
||||
this._createCheckbox(container, item);
|
||||
|
||||
checkbox = container.query(sel);
|
||||
|
||||
host._uiSetHeight(host.get('height'));
|
||||
}
|
||||
|
||||
checkbox.set(CHECKED, checked);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Passes checkbox clicks on to the category attribute.
|
||||
*
|
||||
* @method _onCategoryCheckboxClick
|
||||
* @param e {Event} the DOM event
|
||||
* @protected
|
||||
*/
|
||||
_onCategoryCheckboxClick : function (e) {
|
||||
var t = e.target, cat;
|
||||
|
||||
if (t.hasClass(ConsoleFilters.CHROME_CLASSES.filter)) {
|
||||
cat = t.get('value');
|
||||
if (cat && cat in this.get(CATEGORY)) {
|
||||
this.set(CATEGORY_DOT + cat, t.get(CHECKED), { fromUI: true });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Passes checkbox clicks on to the source attribute.
|
||||
*
|
||||
* @method _onSourceCheckboxClick
|
||||
* @param e {Event} the DOM event
|
||||
* @protected
|
||||
*/
|
||||
_onSourceCheckboxClick : function (e) {
|
||||
var t = e.target, src;
|
||||
|
||||
if (t.hasClass(ConsoleFilters.CHROME_CLASSES.filter)) {
|
||||
src = t.get('value');
|
||||
if (src && src in this.get(SOURCE)) {
|
||||
this.set(SOURCE_DOT + src, t.get(CHECKED), { fromUI: true });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hides any number of categories from the UI. Convenience method for
|
||||
* myConsole.filter.set('category.foo', false); set('category.bar', false);
|
||||
* and so on.
|
||||
*
|
||||
* @method hideCategory
|
||||
* @param cat* {String} 1..n categories to filter out of the UI
|
||||
*/
|
||||
hideCategory : function (cat, multiple) {
|
||||
if (isString(multiple)) {
|
||||
Y.Array.each(arguments, arguments.callee, this);
|
||||
} else {
|
||||
this.set(CATEGORY_DOT + cat, false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows any number of categories in the UI. Convenience method for
|
||||
* myConsole.filter.set('category.foo', true); set('category.bar', true);
|
||||
* and so on.
|
||||
*
|
||||
* @method showCategory
|
||||
* @param cat* {String} 1..n categories to allow to display in the UI
|
||||
*/
|
||||
showCategory : function (cat, multiple) {
|
||||
if (isString(multiple)) {
|
||||
Y.Array.each(arguments, arguments.callee, this);
|
||||
} else {
|
||||
this.set(CATEGORY_DOT + cat, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hides any number of sources from the UI. Convenience method for
|
||||
* myConsole.filter.set('source.foo', false); set('source.bar', false);
|
||||
* and so on.
|
||||
*
|
||||
* @method hideSource
|
||||
* @param src* {String} 1..n sources to filter out of the UI
|
||||
*/
|
||||
hideSource : function (src, multiple) {
|
||||
if (isString(multiple)) {
|
||||
Y.Array.each(arguments, arguments.callee, this);
|
||||
} else {
|
||||
this.set(SOURCE_DOT + src, false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows any number of sources in the UI. Convenience method for
|
||||
* myConsole.filter.set('source.foo', true); set('source.bar', true);
|
||||
* and so on.
|
||||
*
|
||||
* @method showSource
|
||||
* @param src* {String} 1..n sources to allow to display in the UI
|
||||
*/
|
||||
showSource : function (src, multiple) {
|
||||
if (isString(multiple)) {
|
||||
Y.Array.each(arguments, arguments.callee, this);
|
||||
} else {
|
||||
this.set(SOURCE_DOT + src, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a checkbox and label from the ConsoleFilters.FILTER_TEMPLATE for
|
||||
* the provided type and name. The checkbox and label are appended to the
|
||||
* container node passes as the first arg.
|
||||
*
|
||||
* @method _createCheckbox
|
||||
* @param container {Node} the parentNode of the new checkbox and label
|
||||
* @param name {String} the identifier of the filter
|
||||
* @protected
|
||||
*/
|
||||
_createCheckbox : function (container, name) {
|
||||
var info = Y.merge(ConsoleFilters.CHROME_CLASSES, {
|
||||
filter_name : name,
|
||||
filter_class : getCN(CONSOLE, FILTER, name)
|
||||
}),
|
||||
node = Y.Node.create(
|
||||
Y.substitute(ConsoleFilters.FILTER_TEMPLATE, info));
|
||||
|
||||
container.appendChild(node);
|
||||
},
|
||||
|
||||
/**
|
||||
* Validates category updates are objects and the subattribute is not too
|
||||
* deep.
|
||||
*
|
||||
* @method _validateCategory
|
||||
* @param cat {String} the new category:visibility map
|
||||
* @param v {String} the subattribute path updated
|
||||
* @return Boolean
|
||||
* @protected
|
||||
*/
|
||||
_validateCategory : function (cat, v) {
|
||||
return Y.Lang.isObject(v,true) && cat.split(/\./).length < 3;
|
||||
},
|
||||
|
||||
/**
|
||||
* Validates source updates are objects and the subattribute is not too
|
||||
* deep.
|
||||
*
|
||||
* @method _validateSource
|
||||
* @param cat {String} the new source:visibility map
|
||||
* @param v {String} the subattribute path updated
|
||||
* @return Boolean
|
||||
* @protected
|
||||
*/
|
||||
_validateSource : function (src, v) {
|
||||
return Y.Lang.isObject(v,true) && src.split(/\./).length < 3;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Y.namespace('Plugin').ConsoleFilters = ConsoleFilters;
|
||||
|
||||
|
||||
}, '3.0.0' ,{requires:['console','plugin']});
|
||||
@@ -0,0 +1,710 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add('console-filters', function(Y) {
|
||||
|
||||
/**
|
||||
* <p>Provides Plugin.ConsoleFilters plugin class.</p>
|
||||
*
|
||||
* <p>This plugin adds the ability to control which Console entries display by filtering on category and source. Two groups of checkboxes are added to the Console footer, one for categories and the other for sources. Only those messages that match a checked category or source are displayed.</p>
|
||||
*
|
||||
* @module console-filters
|
||||
* @namespace Plugin
|
||||
* @class ConsoleFilters
|
||||
*/
|
||||
|
||||
// Some common strings and functions
|
||||
var getCN = Y.ClassNameManager.getClassName,
|
||||
CONSOLE = 'console',
|
||||
FILTERS = 'filters',
|
||||
FILTER = 'filter',
|
||||
CATEGORY = 'category',
|
||||
SOURCE = 'source',
|
||||
CATEGORY_DOT = 'category.',
|
||||
SOURCE_DOT = 'source.',
|
||||
|
||||
HOST = 'host',
|
||||
PARENT_NODE = 'parentNode',
|
||||
CHECKED = 'checked',
|
||||
DEF_VISIBILITY = 'defaultVisibility',
|
||||
|
||||
DOT = '.',
|
||||
EMPTY = '',
|
||||
|
||||
C_BODY = DOT + Y.Console.CHROME_CLASSES.console_bd_class,
|
||||
C_FOOT = DOT + Y.Console.CHROME_CLASSES.console_ft_class,
|
||||
|
||||
SEL_CHECK = 'input[type=checkbox].',
|
||||
|
||||
isString = Y.Lang.isString;
|
||||
|
||||
function ConsoleFilters() {
|
||||
ConsoleFilters.superclass.constructor.apply(this,arguments);
|
||||
}
|
||||
|
||||
Y.mix(ConsoleFilters,{
|
||||
/**
|
||||
* Plugin name.
|
||||
*
|
||||
* @property ConsoleFilters.NAME
|
||||
* @type String
|
||||
* @static
|
||||
* @default 'consoleFilters'
|
||||
*/
|
||||
NAME : 'consoleFilters',
|
||||
|
||||
/**
|
||||
* The namespace hung off the host object that this plugin will inhabit.
|
||||
*
|
||||
* @property ConsoleFilters.NS
|
||||
* @type String
|
||||
* @static
|
||||
* @default 'filter'
|
||||
*/
|
||||
NS : FILTER,
|
||||
|
||||
/**
|
||||
* Markup template used to create the container for the category filters.
|
||||
*
|
||||
* @property ConsoleFilters.CATEGORIES_TEMPLATE
|
||||
* @type String
|
||||
* @static
|
||||
*/
|
||||
CATEGORIES_TEMPLATE :
|
||||
'<div class="{categories}"></div>',
|
||||
|
||||
/**
|
||||
* Markup template used to create the container for the source filters.
|
||||
*
|
||||
* @property ConsoleFilters.SOURCES_TEMPLATE
|
||||
* @type String
|
||||
* @static
|
||||
*/
|
||||
SOURCES_TEMPLATE :
|
||||
'<div class="{sources}"></div>',
|
||||
|
||||
/**
|
||||
* Markup template used to create the category and source filter checkboxes.
|
||||
*
|
||||
* @property ConsoleFilters.FILTER_TEMPLATE
|
||||
* @type String
|
||||
* @static
|
||||
*/
|
||||
FILTER_TEMPLATE :
|
||||
// IE8 and FF3 don't permit breaking _between_ nowrap elements. IE8
|
||||
// doesn't understand (non spec) wbr tag, nor does it create text nodes
|
||||
// for spaces in innerHTML strings. The thin-space entity suffices to
|
||||
// create a breakable point.
|
||||
'<label class="{filter_label}">'+
|
||||
'<input type="checkbox" value="{filter_name}" '+
|
||||
'class="{filter} {filter_class}"> {filter_name}'+
|
||||
'</label> ',
|
||||
|
||||
/**
|
||||
* Classnames used by the templates when creating nodes.
|
||||
*
|
||||
* @property ConsoleFilters.CHROME_CLASSES
|
||||
* @type Object
|
||||
* @static
|
||||
* @protected
|
||||
*/
|
||||
CHROME_CLASSES : {
|
||||
categories : getCN(CONSOLE,FILTERS,'categories'),
|
||||
sources : getCN(CONSOLE,FILTERS,'sources'),
|
||||
category : getCN(CONSOLE,FILTER,CATEGORY),
|
||||
source : getCN(CONSOLE,FILTER,SOURCE),
|
||||
filter : getCN(CONSOLE,FILTER),
|
||||
filter_label : getCN(CONSOLE,FILTER,'label')
|
||||
},
|
||||
|
||||
ATTRS : {
|
||||
/**
|
||||
* Default visibility applied to new categories and sources.
|
||||
*
|
||||
* @attribute defaultVisibility
|
||||
* @type {Boolean}
|
||||
* @default true
|
||||
*/
|
||||
defaultVisibility : {
|
||||
value : true,
|
||||
validator : Y.Lang.isBoolean
|
||||
},
|
||||
|
||||
/**
|
||||
* <p>Map of entry categories to their visibility status. Update a
|
||||
* particular category's visibility by setting the subattribute to true
|
||||
* (visible) or false (hidden).</p>
|
||||
*
|
||||
* <p>For example, yconsole.filter.set('category.info', false) to hide
|
||||
* log entries with the category/logLevel of 'info'.</p>
|
||||
*
|
||||
* <p>Similarly, yconsole.filter.get('category.warn') will return a
|
||||
* boolean indicating whether that category is currently being included
|
||||
* in the UI.</p>
|
||||
*
|
||||
* <p>Unlike the YUI instance configuration's logInclude and logExclude
|
||||
* properties, filtered entries are only hidden from the UI, but
|
||||
* can be made visible again.</p>
|
||||
*
|
||||
* @attribute category
|
||||
* @type Object
|
||||
*/
|
||||
category : {
|
||||
value : {},
|
||||
validator : function (v,k) {
|
||||
return this._validateCategory(k,v);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* <p>Map of entry sources to their visibility status. Update a
|
||||
* particular sources's visibility by setting the subattribute to true
|
||||
* (visible) or false (hidden).</p>
|
||||
*
|
||||
* <p>For example, yconsole.filter.set('sources.slider', false) to hide
|
||||
* log entries originating from Y.Slider.</p>
|
||||
*
|
||||
* @attribute source
|
||||
* @type Object
|
||||
*/
|
||||
source : {
|
||||
value : {},
|
||||
validator : function (v,k) {
|
||||
return this._validateSource(k,v);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Maximum number of entries to store in the message cache. Use this to
|
||||
* limit the memory footprint in environments with heavy log usage.
|
||||
* By default, there is no limit (Number.POSITIVE_INFINITY).
|
||||
*
|
||||
* @attribute cacheLimit
|
||||
* @type {Number}
|
||||
* @default Number.POSITIVE_INFINITY
|
||||
*/
|
||||
cacheLimit : {
|
||||
value : Number.POSITIVE_INFINITY,
|
||||
setter : function (v) {
|
||||
if (Y.Lang.isNumber(v)) {
|
||||
this._cacheLimit = v;
|
||||
return v;
|
||||
} else {
|
||||
return Y.Attribute.INVALID_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Y.extend(ConsoleFilters, Y.Plugin.Base, {
|
||||
|
||||
/**
|
||||
* Collection of all log messages passed through since the plugin's
|
||||
* instantiation. This holds all messages regardless of filter status.
|
||||
* Used as a single source of truth for repopulating the Console body when
|
||||
* filters are changed.
|
||||
*
|
||||
* @property _entries
|
||||
* @type Array
|
||||
* @protected
|
||||
*/
|
||||
_entries : null,
|
||||
|
||||
_cacheLimit : Number.POSITIVE_INFINITY,
|
||||
|
||||
/**
|
||||
* The container node created to house the category filters.
|
||||
*
|
||||
* @property _categories
|
||||
* @type Node
|
||||
* @protected
|
||||
*/
|
||||
_categories : null,
|
||||
|
||||
/**
|
||||
* The container node created to house the source filters.
|
||||
*
|
||||
* @property _sources
|
||||
* @type Node
|
||||
* @protected
|
||||
*/
|
||||
_sources : null,
|
||||
|
||||
/**
|
||||
* Initialize entries collection and attach listeners to host events and
|
||||
* methods.
|
||||
*
|
||||
* @method initializer
|
||||
* @protected
|
||||
*/
|
||||
initializer : function () {
|
||||
this._entries = [];
|
||||
|
||||
this.get(HOST).on("entry", this._onEntry, this);
|
||||
|
||||
this.doAfter("renderUI", this.renderUI);
|
||||
this.doAfter("syncUI", this.syncUI);
|
||||
this.doAfter("bindUI", this.bindUI);
|
||||
|
||||
this.doAfter("clearConsole", this._afterClearConsole);
|
||||
|
||||
if (this.get(HOST).get('rendered')) {
|
||||
this.renderUI();
|
||||
this.syncUI();
|
||||
this.bindUI();
|
||||
}
|
||||
|
||||
this.after("cacheLimitChange", this._afterCacheLimitChange);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the plugin UI and unwires events.
|
||||
*
|
||||
* @method destructor
|
||||
* @protected
|
||||
*/
|
||||
destructor : function () {
|
||||
//TODO: grab last {consoleLimit} entries and update the console with
|
||||
//them (no filtering)
|
||||
this._entries = [];
|
||||
|
||||
if (this._categories) {
|
||||
this._categories.get(PARENT_NODE).removeChild(this._categories);
|
||||
}
|
||||
if (this._sources) {
|
||||
this._sources.get(PARENT_NODE).removeChild(this._sources);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the category and source filter sections to the Console footer.
|
||||
*
|
||||
* @method renderUI
|
||||
* @protected
|
||||
*/
|
||||
renderUI : function () {
|
||||
var foot = this.get(HOST).get('contentBox').query(C_FOOT),
|
||||
html;
|
||||
|
||||
if (foot) {
|
||||
html = Y.substitute(
|
||||
ConsoleFilters.CATEGORIES_TEMPLATE,
|
||||
ConsoleFilters.CHROME_CLASSES);
|
||||
|
||||
this._categories = foot.appendChild(Y.Node.create(html));
|
||||
|
||||
html = Y.substitute(
|
||||
ConsoleFilters.SOURCES_TEMPLATE,
|
||||
ConsoleFilters.CHROME_CLASSES);
|
||||
|
||||
this._sources = foot.appendChild(Y.Node.create(html));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Binds to checkbox click events and internal attribute change events to
|
||||
* maintain the UI state.
|
||||
*
|
||||
* @method bindUI
|
||||
* @protected
|
||||
*/
|
||||
bindUI : function () {
|
||||
this._categories.on('click', Y.bind(this._onCategoryCheckboxClick, this));
|
||||
|
||||
this._sources.on('click', Y.bind(this._onSourceCheckboxClick, this));
|
||||
|
||||
this.after('categoryChange',this._afterCategoryChange);
|
||||
this.after('sourceChange', this._afterSourceChange);
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the UI to be in accordance with the current state of the plugin.
|
||||
*
|
||||
* @method syncUI
|
||||
*/
|
||||
syncUI : function () {
|
||||
Y.each(this.get(CATEGORY), function (v, k) {
|
||||
this._uiSetCheckbox(CATEGORY, k, v);
|
||||
}, this);
|
||||
|
||||
Y.each(this.get(SOURCE), function (v, k) {
|
||||
this._uiSetCheckbox(SOURCE, k, v);
|
||||
}, this);
|
||||
|
||||
this.refreshConsole();
|
||||
},
|
||||
|
||||
/**
|
||||
* Ensures a filter is set up for any new categories or sources and
|
||||
* collects the messages in _entries. If the message is stamped with a
|
||||
* category or source that is currently being filtered out, the message
|
||||
* will not pass to the Console's print buffer.
|
||||
*
|
||||
* @method _onEntry
|
||||
* @param e {Event} the custom event object
|
||||
* @protected
|
||||
*/
|
||||
_onEntry : function (e) {
|
||||
this._entries.push(e.message);
|
||||
|
||||
var cat = CATEGORY_DOT + e.message.category,
|
||||
src = SOURCE_DOT + e.message.source,
|
||||
cat_filter = this.get(cat),
|
||||
src_filter = this.get(src),
|
||||
overLimit = this._entries.length - this._cacheLimit,
|
||||
visible;
|
||||
|
||||
if (overLimit > 0) {
|
||||
this._entries.splice(0, overLimit);
|
||||
}
|
||||
|
||||
if (cat_filter === undefined) {
|
||||
visible = this.get(DEF_VISIBILITY);
|
||||
this.set(cat, visible);
|
||||
cat_filter = visible;
|
||||
}
|
||||
|
||||
if (src_filter === undefined) {
|
||||
visible = this.get(DEF_VISIBILITY);
|
||||
this.set(src, visible);
|
||||
src_filter = visible;
|
||||
}
|
||||
|
||||
if (!cat_filter || !src_filter) {
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Flushes the cached entries after a call to the Console's clearConsole().
|
||||
*
|
||||
* @method _afterClearConsole
|
||||
* @protected
|
||||
*/
|
||||
_afterClearConsole : function () {
|
||||
this._entries = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Triggers the Console to update if a known category filter
|
||||
* changes value (e.g. visible => hidden). Updates the appropriate
|
||||
* checkbox's checked state if necessary.
|
||||
*
|
||||
* @method _afterCategoryChange
|
||||
* @param e {Event} the attribute change event object
|
||||
* @protected
|
||||
*/
|
||||
_afterCategoryChange : function (e) {
|
||||
var cat = e.subAttrName.replace(/category\./, EMPTY),
|
||||
before = e.prevVal,
|
||||
after = e.newVal;
|
||||
|
||||
// Don't update the console for new categories
|
||||
if (!cat || before[cat] !== undefined) {
|
||||
this.refreshConsole();
|
||||
|
||||
this._filterBuffer();
|
||||
}
|
||||
|
||||
if (cat && !e.fromUI) {
|
||||
this._uiSetCheckbox(CATEGORY, cat, after[cat]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Triggers the Console to update if a known source filter
|
||||
* changes value (e.g. visible => hidden). Updates the appropriate
|
||||
* checkbox's checked state if necessary.
|
||||
*
|
||||
* @method _afterSourceChange
|
||||
* @param e {Event} the attribute change event object
|
||||
* @protected
|
||||
*/
|
||||
_afterSourceChange : function (e) {
|
||||
var src = e.subAttrName.replace(/source\./, EMPTY),
|
||||
before = e.prevVal,
|
||||
after = e.newVal;
|
||||
|
||||
// Don't update the console for new sources
|
||||
if (!src || before[src] !== undefined) {
|
||||
this.refreshConsole();
|
||||
|
||||
this._filterBuffer();
|
||||
}
|
||||
|
||||
if (src && !e.fromUI) {
|
||||
this._uiSetCheckbox(SOURCE, src, after[src]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Flushes the Console's print buffer of any entries that have a category
|
||||
* or source that is currently being excluded.
|
||||
*
|
||||
* @method _filterBuffer
|
||||
* @protected
|
||||
*/
|
||||
_filterBuffer : function () {
|
||||
var cats = this.get(CATEGORY),
|
||||
srcs = this.get(SOURCE),
|
||||
buffer = this.get(HOST).buffer,
|
||||
start = null,
|
||||
i;
|
||||
|
||||
for (i = buffer.length - 1; i >= 0; --i) {
|
||||
if (!cats[buffer[i].category] || !srcs[buffer[i].source]) {
|
||||
start = start || i;
|
||||
} else if (start) {
|
||||
buffer.splice(i,(start - i));
|
||||
start = null;
|
||||
}
|
||||
}
|
||||
if (start) {
|
||||
buffer.splice(0,start + 1);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Trims the cache of entries to the appropriate new length.
|
||||
*
|
||||
* @method _afterCacheLimitChange
|
||||
* @param e {Event} the attribute change event object
|
||||
* @protected
|
||||
*/
|
||||
_afterCacheLimitChange : function (e) {
|
||||
if (isFinite(e.newVal)) {
|
||||
var delta = this._entries.length - e.newVal;
|
||||
|
||||
if (delta > 0) {
|
||||
this._entries.splice(0,delta);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Repopulates the Console with entries appropriate to the current filter
|
||||
* settings.
|
||||
*
|
||||
* @method refreshConsole
|
||||
*/
|
||||
refreshConsole : function () {
|
||||
var entries = this._entries,
|
||||
host = this.get(HOST),
|
||||
body = host.get('contentBox').query(C_BODY),
|
||||
remaining = host.get('consoleLimit'),
|
||||
cats = this.get(CATEGORY),
|
||||
srcs = this.get(SOURCE),
|
||||
buffer = [],
|
||||
i,e;
|
||||
|
||||
if (body) {
|
||||
host._cancelPrintLoop();
|
||||
|
||||
// Evaluate all entries from latest to oldest
|
||||
for (i = entries.length - 1; i >= 0 && remaining >= 0; --i) {
|
||||
e = entries[i];
|
||||
if (cats[e.category] && srcs[e.source]) {
|
||||
buffer.unshift(e);
|
||||
--remaining;
|
||||
}
|
||||
}
|
||||
|
||||
body.set('innerHTML',EMPTY);
|
||||
host.buffer = buffer;
|
||||
host.printBuffer();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the checked property of a filter checkbox of the specified type.
|
||||
* If no checkbox is found for the input params, one is created.
|
||||
*
|
||||
* @method _uiSetCheckbox
|
||||
* @param type {String} 'category' or 'source'
|
||||
* @param item {String} the name of the filter (e.g. 'info', 'event')
|
||||
* @param checked {Boolean} value to set the checkbox's checked property
|
||||
* @protected
|
||||
*/
|
||||
_uiSetCheckbox : function (type, item, checked) {
|
||||
if (type && item) {
|
||||
var container = type === CATEGORY ?
|
||||
this._categories :
|
||||
this._sources,
|
||||
sel = SEL_CHECK + getCN(CONSOLE,FILTER,item),
|
||||
checkbox = container.query(sel),
|
||||
host;
|
||||
|
||||
if (!checkbox) {
|
||||
host = this.get(HOST);
|
||||
|
||||
this._createCheckbox(container, item);
|
||||
|
||||
checkbox = container.query(sel);
|
||||
|
||||
host._uiSetHeight(host.get('height'));
|
||||
}
|
||||
|
||||
checkbox.set(CHECKED, checked);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Passes checkbox clicks on to the category attribute.
|
||||
*
|
||||
* @method _onCategoryCheckboxClick
|
||||
* @param e {Event} the DOM event
|
||||
* @protected
|
||||
*/
|
||||
_onCategoryCheckboxClick : function (e) {
|
||||
var t = e.target, cat;
|
||||
|
||||
if (t.hasClass(ConsoleFilters.CHROME_CLASSES.filter)) {
|
||||
cat = t.get('value');
|
||||
if (cat && cat in this.get(CATEGORY)) {
|
||||
this.set(CATEGORY_DOT + cat, t.get(CHECKED), { fromUI: true });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Passes checkbox clicks on to the source attribute.
|
||||
*
|
||||
* @method _onSourceCheckboxClick
|
||||
* @param e {Event} the DOM event
|
||||
* @protected
|
||||
*/
|
||||
_onSourceCheckboxClick : function (e) {
|
||||
var t = e.target, src;
|
||||
|
||||
if (t.hasClass(ConsoleFilters.CHROME_CLASSES.filter)) {
|
||||
src = t.get('value');
|
||||
if (src && src in this.get(SOURCE)) {
|
||||
this.set(SOURCE_DOT + src, t.get(CHECKED), { fromUI: true });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hides any number of categories from the UI. Convenience method for
|
||||
* myConsole.filter.set('category.foo', false); set('category.bar', false);
|
||||
* and so on.
|
||||
*
|
||||
* @method hideCategory
|
||||
* @param cat* {String} 1..n categories to filter out of the UI
|
||||
*/
|
||||
hideCategory : function (cat, multiple) {
|
||||
if (isString(multiple)) {
|
||||
Y.Array.each(arguments, arguments.callee, this);
|
||||
} else {
|
||||
this.set(CATEGORY_DOT + cat, false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows any number of categories in the UI. Convenience method for
|
||||
* myConsole.filter.set('category.foo', true); set('category.bar', true);
|
||||
* and so on.
|
||||
*
|
||||
* @method showCategory
|
||||
* @param cat* {String} 1..n categories to allow to display in the UI
|
||||
*/
|
||||
showCategory : function (cat, multiple) {
|
||||
if (isString(multiple)) {
|
||||
Y.Array.each(arguments, arguments.callee, this);
|
||||
} else {
|
||||
this.set(CATEGORY_DOT + cat, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hides any number of sources from the UI. Convenience method for
|
||||
* myConsole.filter.set('source.foo', false); set('source.bar', false);
|
||||
* and so on.
|
||||
*
|
||||
* @method hideSource
|
||||
* @param src* {String} 1..n sources to filter out of the UI
|
||||
*/
|
||||
hideSource : function (src, multiple) {
|
||||
if (isString(multiple)) {
|
||||
Y.Array.each(arguments, arguments.callee, this);
|
||||
} else {
|
||||
this.set(SOURCE_DOT + src, false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows any number of sources in the UI. Convenience method for
|
||||
* myConsole.filter.set('source.foo', true); set('source.bar', true);
|
||||
* and so on.
|
||||
*
|
||||
* @method showSource
|
||||
* @param src* {String} 1..n sources to allow to display in the UI
|
||||
*/
|
||||
showSource : function (src, multiple) {
|
||||
if (isString(multiple)) {
|
||||
Y.Array.each(arguments, arguments.callee, this);
|
||||
} else {
|
||||
this.set(SOURCE_DOT + src, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a checkbox and label from the ConsoleFilters.FILTER_TEMPLATE for
|
||||
* the provided type and name. The checkbox and label are appended to the
|
||||
* container node passes as the first arg.
|
||||
*
|
||||
* @method _createCheckbox
|
||||
* @param container {Node} the parentNode of the new checkbox and label
|
||||
* @param name {String} the identifier of the filter
|
||||
* @protected
|
||||
*/
|
||||
_createCheckbox : function (container, name) {
|
||||
var info = Y.merge(ConsoleFilters.CHROME_CLASSES, {
|
||||
filter_name : name,
|
||||
filter_class : getCN(CONSOLE, FILTER, name)
|
||||
}),
|
||||
node = Y.Node.create(
|
||||
Y.substitute(ConsoleFilters.FILTER_TEMPLATE, info));
|
||||
|
||||
container.appendChild(node);
|
||||
},
|
||||
|
||||
/**
|
||||
* Validates category updates are objects and the subattribute is not too
|
||||
* deep.
|
||||
*
|
||||
* @method _validateCategory
|
||||
* @param cat {String} the new category:visibility map
|
||||
* @param v {String} the subattribute path updated
|
||||
* @return Boolean
|
||||
* @protected
|
||||
*/
|
||||
_validateCategory : function (cat, v) {
|
||||
return Y.Lang.isObject(v,true) && cat.split(/\./).length < 3;
|
||||
},
|
||||
|
||||
/**
|
||||
* Validates source updates are objects and the subattribute is not too
|
||||
* deep.
|
||||
*
|
||||
* @method _validateSource
|
||||
* @param cat {String} the new source:visibility map
|
||||
* @param v {String} the subattribute path updated
|
||||
* @return Boolean
|
||||
* @protected
|
||||
*/
|
||||
_validateSource : function (src, v) {
|
||||
return Y.Lang.isObject(v,true) && src.split(/\./).length < 3;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Y.namespace('Plugin').ConsoleFilters = ConsoleFilters;
|
||||
|
||||
|
||||
}, '3.0.0' ,{requires:['console','plugin']});
|
||||
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add('cookie', function(Y) {
|
||||
|
||||
/**
|
||||
* Utilities for cookie management
|
||||
* @module cookie
|
||||
*/
|
||||
|
||||
//shortcuts
|
||||
var L = Y.Lang,
|
||||
O = Y.Object,
|
||||
NULL = null,
|
||||
|
||||
//shortcuts to functions
|
||||
isString = L.isString,
|
||||
isObject = L.isObject,
|
||||
isUndefined = L.isUndefined,
|
||||
isFunction = L.isFunction,
|
||||
encode = encodeURIComponent,
|
||||
decode = decodeURIComponent,
|
||||
|
||||
//shortcut to document
|
||||
doc = Y.config.doc;
|
||||
|
||||
/*
|
||||
* Throws an error message.
|
||||
*/
|
||||
function error(message){
|
||||
throw new TypeError(message);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks the validity of a cookie name.
|
||||
*/
|
||||
function validateCookieName(name){
|
||||
if (!isString(name) || name === ""){
|
||||
error("Cookie name must be a non-empty string.");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks the validity of a subcookie name.
|
||||
*/
|
||||
function validateSubcookieName(subName){
|
||||
if (!isString(subName) || subName === ""){
|
||||
error("Subcookie name must be a non-empty string.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cookie utility.
|
||||
* @class Cookie
|
||||
* @static
|
||||
*/
|
||||
Y.Cookie = {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Private Methods
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates a cookie string that can be assigned into document.cookie.
|
||||
* @param {String} name The name of the cookie.
|
||||
* @param {String} value The value of the cookie.
|
||||
* @param {Boolean} encodeValue True to encode the value, false to leave as-is.
|
||||
* @param {Object} options (Optional) Options for the cookie.
|
||||
* @return {String} The formatted cookie string.
|
||||
* @method _createCookieString
|
||||
* @private
|
||||
* @static
|
||||
*/
|
||||
_createCookieString : function (name /*:String*/, value /*:Variant*/, encodeValue /*:Boolean*/, options /*:Object*/) /*:String*/ {
|
||||
|
||||
options = options || {};
|
||||
|
||||
var text /*:String*/ = encode(name) + "=" + (encodeValue ? encode(value) : value),
|
||||
expires = options.expires,
|
||||
path = options.path,
|
||||
domain = options.domain;
|
||||
|
||||
|
||||
if (isObject(options)){
|
||||
//expiration date
|
||||
if (expires instanceof Date){
|
||||
text += "; expires=" + expires.toUTCString();
|
||||
}
|
||||
|
||||
//path
|
||||
if (isString(path) && path !== ""){
|
||||
text += "; path=" + path;
|
||||
}
|
||||
|
||||
//domain
|
||||
if (isString(domain) && domain !== ""){
|
||||
text += "; domain=" + domain;
|
||||
}
|
||||
|
||||
//secure
|
||||
if (options.secure === true){
|
||||
text += "; secure";
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
},
|
||||
|
||||
/**
|
||||
* Formats a cookie value for an object containing multiple values.
|
||||
* @param {Object} hash An object of key-value pairs to create a string for.
|
||||
* @return {String} A string suitable for use as a cookie value.
|
||||
* @method _createCookieHashString
|
||||
* @private
|
||||
* @static
|
||||
*/
|
||||
_createCookieHashString : function (hash /*:Object*/) /*:String*/ {
|
||||
if (!isObject(hash)){
|
||||
error("Cookie._createCookieHashString(): Argument must be an object.");
|
||||
}
|
||||
|
||||
var text /*:Array*/ = [];
|
||||
|
||||
O.each(hash, function(value, key){
|
||||
if (!isFunction(value) && !isUndefined(value)){
|
||||
text.push(encode(key) + "=" + encode(String(value)));
|
||||
}
|
||||
});
|
||||
|
||||
return text.join("&");
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses a cookie hash string into an object.
|
||||
* @param {String} text The cookie hash string to parse (format: n1=v1&n2=v2).
|
||||
* @return {Object} An object containing entries for each cookie value.
|
||||
* @method _parseCookieHash
|
||||
* @private
|
||||
* @static
|
||||
*/
|
||||
_parseCookieHash : function (text) {
|
||||
|
||||
var hashParts = text.split("&"),
|
||||
hashPart = NULL,
|
||||
hash = {};
|
||||
|
||||
if (text.length){
|
||||
for (var i=0, len=hashParts.length; i < len; i++){
|
||||
hashPart = hashParts[i].split("=");
|
||||
hash[decode(hashPart[0])] = decode(hashPart[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return hash;
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses a cookie string into an object representing all accessible cookies.
|
||||
* @param {String} text The cookie string to parse.
|
||||
* @param {Boolean} shouldDecode (Optional) Indicates if the cookie values should be decoded or not. Default is true.
|
||||
* @return {Object} An object containing entries for each accessible cookie.
|
||||
* @method _parseCookieString
|
||||
* @private
|
||||
* @static
|
||||
*/
|
||||
_parseCookieString : function (text /*:String*/, shouldDecode /*:Boolean*/) /*:Object*/ {
|
||||
|
||||
var cookies /*:Object*/ = {};
|
||||
|
||||
if (isString(text) && text.length > 0) {
|
||||
|
||||
var decodeValue = (shouldDecode === false ? function(s){return s;} : decode),
|
||||
cookieParts = text.split(/;\s/g),
|
||||
cookieName = NULL,
|
||||
cookieValue = NULL,
|
||||
cookieNameValue = NULL;
|
||||
|
||||
for (var i=0, len=cookieParts.length; i < len; i++){
|
||||
|
||||
//check for normally-formatted cookie (name-value)
|
||||
cookieNameValue = cookieParts[i].match(/([^=]+)=/i);
|
||||
if (cookieNameValue instanceof Array){
|
||||
try {
|
||||
cookieName = decode(cookieNameValue[1]);
|
||||
cookieValue = decodeValue(cookieParts[i].substring(cookieNameValue[1].length+1));
|
||||
} catch (ex){
|
||||
//intentionally ignore the cookie - the encoding is wrong
|
||||
}
|
||||
} else {
|
||||
//means the cookie does not have an "=", so treat it as a boolean flag
|
||||
cookieName = decode(cookieParts[i]);
|
||||
cookieValue = "";
|
||||
}
|
||||
cookies[cookieName] = cookieValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return cookies;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Determines if the cookie with the given name exists. This is useful for
|
||||
* Boolean cookies (those that do not follow the name=value convention).
|
||||
* @param {String} name The name of the cookie to check.
|
||||
* @return {Boolean} True if the cookie exists, false if not.
|
||||
* @method exists
|
||||
* @static
|
||||
*/
|
||||
exists: function(name) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
var cookies = this._parseCookieString(doc.cookie, true);
|
||||
|
||||
return cookies.hasOwnProperty(name);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the cookie value for the given name.
|
||||
* @param {String} name The name of the cookie to retrieve.
|
||||
* @param {Function|Object} options (Optional) An object containing one or more
|
||||
* cookie options: raw (true/false) and converter (a function).
|
||||
* The converter function is run on the value before returning it. The
|
||||
* function is not used if the cookie doesn't exist. The function can be
|
||||
* passed instead of the options object for backwards compatibility. When
|
||||
* raw is set to true, the cookie value is not URI decoded.
|
||||
* @return {Variant} If no converter is specified, returns a string or null if
|
||||
* the cookie doesn't exist. If the converter is specified, returns the value
|
||||
* returned from the converter or null if the cookie doesn't exist.
|
||||
* @method get
|
||||
* @static
|
||||
*/
|
||||
get : function (name, options) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
var cookies,
|
||||
cookie,
|
||||
converter;
|
||||
|
||||
//if options is a function, then it's the converter
|
||||
if (isFunction(options)) {
|
||||
converter = options;
|
||||
options = {};
|
||||
} else if (isObject(options)) {
|
||||
converter = options.converter;
|
||||
} else {
|
||||
options = {};
|
||||
}
|
||||
|
||||
cookies = this._parseCookieString(doc.cookie, !options.raw);
|
||||
cookie = cookies[name];
|
||||
|
||||
//should return null, not undefined if the cookie doesn't exist
|
||||
if (isUndefined(cookie)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!isFunction(converter)){
|
||||
return cookie;
|
||||
} else {
|
||||
return converter(cookie);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the value of a subcookie.
|
||||
* @param {String} name The name of the cookie to retrieve.
|
||||
* @param {String} subName The name of the subcookie to retrieve.
|
||||
* @param {Function} converter (Optional) A function to run on the value before returning
|
||||
* it. The function is not used if the cookie doesn't exist.
|
||||
* @return {Variant} If the cookie doesn't exist, null is returned. If the subcookie
|
||||
* doesn't exist, null if also returned. If no converter is specified and the
|
||||
* subcookie exists, a string is returned. If a converter is specified and the
|
||||
* subcookie exists, the value returned from the converter is returned.
|
||||
* @method getSub
|
||||
* @static
|
||||
*/
|
||||
getSub : function (name /*:String*/, subName /*:String*/, converter /*:Function*/) /*:Variant*/ {
|
||||
|
||||
var hash /*:Variant*/ = this.getSubs(name);
|
||||
|
||||
if (hash !== NULL) {
|
||||
|
||||
validateSubcookieName(subName); //throws error
|
||||
|
||||
if (isUndefined(hash[subName])){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!isFunction(converter)){
|
||||
return hash[subName];
|
||||
} else {
|
||||
return converter(hash[subName]);
|
||||
}
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an object containing name-value pairs stored in the cookie with the given name.
|
||||
* @param {String} name The name of the cookie to retrieve.
|
||||
* @return {Object} An object of name-value pairs if the cookie with the given name
|
||||
* exists, null if it does not.
|
||||
* @method getSubs
|
||||
* @static
|
||||
*/
|
||||
getSubs : function (name) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
var cookies = this._parseCookieString(doc.cookie, false);
|
||||
if (isString(cookies[name])){
|
||||
return this._parseCookieHash(cookies[name]);
|
||||
}
|
||||
return NULL;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a cookie from the machine by setting its expiration date to
|
||||
* sometime in the past.
|
||||
* @param {String} name The name of the cookie to remove.
|
||||
* @param {Object} options (Optional) An object containing one or more
|
||||
* cookie options: path (a string), domain (a string),
|
||||
* and secure (true/false). The expires option will be overwritten
|
||||
* by the method.
|
||||
* @return {String} The created cookie string.
|
||||
* @method remove
|
||||
* @static
|
||||
*/
|
||||
remove : function (name, options) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
//set options
|
||||
options = Y.merge(options || {}, {
|
||||
expires: new Date(0)
|
||||
});
|
||||
|
||||
//set cookie
|
||||
return this.set(name, "", options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a sub cookie with a given name.
|
||||
* @param {String} name The name of the cookie in which the subcookie exists.
|
||||
* @param {String} subName The name of the subcookie to remove.
|
||||
* @param {Object} options (Optional) An object containing one or more
|
||||
* cookie options: path (a string), domain (a string), expires (a Date object),
|
||||
* removeIfEmpty (true/false), and secure (true/false). This must be the same
|
||||
* settings as the original subcookie.
|
||||
* @return {String} The created cookie string.
|
||||
* @method removeSub
|
||||
* @static
|
||||
*/
|
||||
removeSub : function(name, subName, options) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
validateSubcookieName(subName); //throws error
|
||||
|
||||
options = options || {};
|
||||
|
||||
//get all subcookies for this cookie
|
||||
var subs = this.getSubs(name);
|
||||
|
||||
//delete the indicated subcookie
|
||||
if (isObject(subs) && subs.hasOwnProperty(subName)){
|
||||
delete subs[subName];
|
||||
|
||||
if (!options.removeIfEmpty) {
|
||||
//reset the cookie
|
||||
|
||||
return this.setSubs(name, subs, options);
|
||||
} else {
|
||||
//reset the cookie if there are subcookies left, else remove
|
||||
for (var key in subs){
|
||||
if (subs.hasOwnProperty(key) && !isFunction(subs[key]) && !isUndefined(subs[key])){
|
||||
return this.setSubs(name, subs, options);
|
||||
}
|
||||
}
|
||||
|
||||
return this.remove(name, options);
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a cookie with a given name and value.
|
||||
* @param {String} name The name of the cookie to set.
|
||||
* @param {Variant} value The value to set for the cookie.
|
||||
* @param {Object} options (Optional) An object containing one or more
|
||||
* cookie options: path (a string), domain (a string), expires (a Date object),
|
||||
* secure (true/false), and raw (true/false). Setting raw to true indicates
|
||||
* that the cookie should not be URI encoded before being set.
|
||||
* @return {String} The created cookie string.
|
||||
* @method set
|
||||
* @static
|
||||
*/
|
||||
set : function (name, value, options) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
if (isUndefined(value)){
|
||||
error("Cookie.set(): Value cannot be undefined.");
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
|
||||
var text = this._createCookieString(name, value, !options.raw, options);
|
||||
doc.cookie = text;
|
||||
return text;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a sub cookie with a given name to a particular value.
|
||||
* @param {String} name The name of the cookie to set.
|
||||
* @param {String} subName The name of the subcookie to set.
|
||||
* @param {Variant} value The value to set.
|
||||
* @param {Object} options (Optional) An object containing one or more
|
||||
* cookie options: path (a string), domain (a string), expires (a Date object),
|
||||
* and secure (true/false).
|
||||
* @return {String} The created cookie string.
|
||||
* @method setSub
|
||||
* @static
|
||||
*/
|
||||
setSub : function (name, subName, value, options) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
validateSubcookieName(subName); //throws error
|
||||
|
||||
if (isUndefined(value)){
|
||||
error("Cookie.setSub(): Subcookie value cannot be undefined.");
|
||||
}
|
||||
|
||||
var hash = this.getSubs(name);
|
||||
|
||||
if (!isObject(hash)){
|
||||
hash = {};
|
||||
}
|
||||
|
||||
hash[subName] = value;
|
||||
|
||||
return this.setSubs(name, hash, options);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a cookie with a given name to contain a hash of name-value pairs.
|
||||
* @param {String} name The name of the cookie to set.
|
||||
* @param {Object} value An object containing name-value pairs.
|
||||
* @param {Object} options (Optional) An object containing one or more
|
||||
* cookie options: path (a string), domain (a string), expires (a Date object),
|
||||
* and secure (true/false).
|
||||
* @return {String} The created cookie string.
|
||||
* @method setSubs
|
||||
* @static
|
||||
*/
|
||||
setSubs : function (name, value, options) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
if (!isObject(value)){
|
||||
error("Cookie.setSubs(): Cookie value must be an object.");
|
||||
}
|
||||
|
||||
var text /*:String*/ = this._createCookieString(name, this._createCookieHashString(value), false, options);
|
||||
doc.cookie = text;
|
||||
return text;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
}, '3.0.0' ,{requires:['yui-base']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add("cookie",function(C){var K=C.Lang,I=C.Object,G=null,D=K.isString,P=K.isObject,F=K.isUndefined,E=K.isFunction,H=encodeURIComponent,B=decodeURIComponent,N=C.config.doc;function J(L){throw new TypeError(L);}function M(L){if(!D(L)||L===""){J("Cookie name must be a non-empty string.");}}function A(L){if(!D(L)||L===""){J("Subcookie name must be a non-empty string.");}}C.Cookie={_createCookieString:function(Q,T,R,O){O=O||{};var V=H(Q)+"="+(R?H(T):T),L=O.expires,U=O.path,S=O.domain;if(P(O)){if(L instanceof Date){V+="; expires="+L.toUTCString();}if(D(U)&&U!==""){V+="; path="+U;}if(D(S)&&S!==""){V+="; domain="+S;}if(O.secure===true){V+="; secure";}}return V;},_createCookieHashString:function(L){if(!P(L)){J("Cookie._createCookieHashString(): Argument must be an object.");}var O=[];I.each(L,function(R,Q){if(!E(R)&&!F(R)){O.push(H(Q)+"="+H(String(R)));}});return O.join("&");},_parseCookieHash:function(S){var R=S.split("&"),T=G,Q={};if(S.length){for(var O=0,L=R.length;O<L;O++){T=R[O].split("=");Q[B(T[0])]=B(T[1]);}}return Q;},_parseCookieString:function(W,Y){var X={};if(D(W)&&W.length>0){var L=(Y===false?function(Z){return Z;}:B),U=W.split(/;\s/g),V=G,O=G,R=G;for(var Q=0,S=U.length;Q<S;Q++){R=U[Q].match(/([^=]+)=/i);if(R instanceof Array){try{V=B(R[1]);O=L(U[Q].substring(R[1].length+1));}catch(T){}}else{V=B(U[Q]);O="";}X[V]=O;}}return X;},exists:function(L){M(L);var O=this._parseCookieString(N.cookie,true);return O.hasOwnProperty(L);},get:function(O,L){M(O);var S,Q,R;if(E(L)){R=L;L={};}else{if(P(L)){R=L.converter;}else{L={};}}S=this._parseCookieString(N.cookie,!L.raw);Q=S[O];if(F(Q)){return G;}if(!E(R)){return Q;}else{return R(Q);}},getSub:function(L,Q,O){var R=this.getSubs(L);if(R!==G){A(Q);if(F(R[Q])){return G;}if(!E(O)){return R[Q];}else{return O(R[Q]);}}else{return G;}},getSubs:function(L){M(L);var O=this._parseCookieString(N.cookie,false);if(D(O[L])){return this._parseCookieHash(O[L]);}return G;},remove:function(O,L){M(O);L=C.merge(L||{},{expires:new Date(0)});return this.set(O,"",L);},removeSub:function(O,S,L){M(O);A(S);L=L||{};var R=this.getSubs(O);if(P(R)&&R.hasOwnProperty(S)){delete R[S];if(!L.removeIfEmpty){return this.setSubs(O,R,L);}else{for(var Q in R){if(R.hasOwnProperty(Q)&&!E(R[Q])&&!F(R[Q])){return this.setSubs(O,R,L);}}return this.remove(O,L);}}else{return"";}},set:function(O,Q,L){M(O);if(F(Q)){J("Cookie.set(): Value cannot be undefined.");}L=L||{};var R=this._createCookieString(O,Q,!L.raw,L);N.cookie=R;return R;},setSub:function(O,R,Q,L){M(O);A(R);if(F(Q)){J("Cookie.setSub(): Subcookie value cannot be undefined.");}var S=this.getSubs(O);if(!P(S)){S={};}S[R]=Q;return this.setSubs(O,S,L);},setSubs:function(O,Q,L){M(O);if(!P(Q)){J("Cookie.setSubs(): Cookie value must be an object.");}var R=this._createCookieString(O,this._createCookieHashString(Q),false,L);N.cookie=R;return R;}};},"3.0.0",{requires:["yui-base"]});
|
||||
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
YUI.add('cookie', function(Y) {
|
||||
|
||||
/**
|
||||
* Utilities for cookie management
|
||||
* @module cookie
|
||||
*/
|
||||
|
||||
//shortcuts
|
||||
var L = Y.Lang,
|
||||
O = Y.Object,
|
||||
NULL = null,
|
||||
|
||||
//shortcuts to functions
|
||||
isString = L.isString,
|
||||
isObject = L.isObject,
|
||||
isUndefined = L.isUndefined,
|
||||
isFunction = L.isFunction,
|
||||
encode = encodeURIComponent,
|
||||
decode = decodeURIComponent,
|
||||
|
||||
//shortcut to document
|
||||
doc = Y.config.doc;
|
||||
|
||||
/*
|
||||
* Throws an error message.
|
||||
*/
|
||||
function error(message){
|
||||
throw new TypeError(message);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks the validity of a cookie name.
|
||||
*/
|
||||
function validateCookieName(name){
|
||||
if (!isString(name) || name === ""){
|
||||
error("Cookie name must be a non-empty string.");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks the validity of a subcookie name.
|
||||
*/
|
||||
function validateSubcookieName(subName){
|
||||
if (!isString(subName) || subName === ""){
|
||||
error("Subcookie name must be a non-empty string.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cookie utility.
|
||||
* @class Cookie
|
||||
* @static
|
||||
*/
|
||||
Y.Cookie = {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Private Methods
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates a cookie string that can be assigned into document.cookie.
|
||||
* @param {String} name The name of the cookie.
|
||||
* @param {String} value The value of the cookie.
|
||||
* @param {Boolean} encodeValue True to encode the value, false to leave as-is.
|
||||
* @param {Object} options (Optional) Options for the cookie.
|
||||
* @return {String} The formatted cookie string.
|
||||
* @method _createCookieString
|
||||
* @private
|
||||
* @static
|
||||
*/
|
||||
_createCookieString : function (name /*:String*/, value /*:Variant*/, encodeValue /*:Boolean*/, options /*:Object*/) /*:String*/ {
|
||||
|
||||
options = options || {};
|
||||
|
||||
var text /*:String*/ = encode(name) + "=" + (encodeValue ? encode(value) : value),
|
||||
expires = options.expires,
|
||||
path = options.path,
|
||||
domain = options.domain;
|
||||
|
||||
|
||||
if (isObject(options)){
|
||||
//expiration date
|
||||
if (expires instanceof Date){
|
||||
text += "; expires=" + expires.toUTCString();
|
||||
}
|
||||
|
||||
//path
|
||||
if (isString(path) && path !== ""){
|
||||
text += "; path=" + path;
|
||||
}
|
||||
|
||||
//domain
|
||||
if (isString(domain) && domain !== ""){
|
||||
text += "; domain=" + domain;
|
||||
}
|
||||
|
||||
//secure
|
||||
if (options.secure === true){
|
||||
text += "; secure";
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
},
|
||||
|
||||
/**
|
||||
* Formats a cookie value for an object containing multiple values.
|
||||
* @param {Object} hash An object of key-value pairs to create a string for.
|
||||
* @return {String} A string suitable for use as a cookie value.
|
||||
* @method _createCookieHashString
|
||||
* @private
|
||||
* @static
|
||||
*/
|
||||
_createCookieHashString : function (hash /*:Object*/) /*:String*/ {
|
||||
if (!isObject(hash)){
|
||||
error("Cookie._createCookieHashString(): Argument must be an object.");
|
||||
}
|
||||
|
||||
var text /*:Array*/ = [];
|
||||
|
||||
O.each(hash, function(value, key){
|
||||
if (!isFunction(value) && !isUndefined(value)){
|
||||
text.push(encode(key) + "=" + encode(String(value)));
|
||||
}
|
||||
});
|
||||
|
||||
return text.join("&");
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses a cookie hash string into an object.
|
||||
* @param {String} text The cookie hash string to parse (format: n1=v1&n2=v2).
|
||||
* @return {Object} An object containing entries for each cookie value.
|
||||
* @method _parseCookieHash
|
||||
* @private
|
||||
* @static
|
||||
*/
|
||||
_parseCookieHash : function (text) {
|
||||
|
||||
var hashParts = text.split("&"),
|
||||
hashPart = NULL,
|
||||
hash = {};
|
||||
|
||||
if (text.length){
|
||||
for (var i=0, len=hashParts.length; i < len; i++){
|
||||
hashPart = hashParts[i].split("=");
|
||||
hash[decode(hashPart[0])] = decode(hashPart[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return hash;
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses a cookie string into an object representing all accessible cookies.
|
||||
* @param {String} text The cookie string to parse.
|
||||
* @param {Boolean} shouldDecode (Optional) Indicates if the cookie values should be decoded or not. Default is true.
|
||||
* @return {Object} An object containing entries for each accessible cookie.
|
||||
* @method _parseCookieString
|
||||
* @private
|
||||
* @static
|
||||
*/
|
||||
_parseCookieString : function (text /*:String*/, shouldDecode /*:Boolean*/) /*:Object*/ {
|
||||
|
||||
var cookies /*:Object*/ = {};
|
||||
|
||||
if (isString(text) && text.length > 0) {
|
||||
|
||||
var decodeValue = (shouldDecode === false ? function(s){return s;} : decode),
|
||||
cookieParts = text.split(/;\s/g),
|
||||
cookieName = NULL,
|
||||
cookieValue = NULL,
|
||||
cookieNameValue = NULL;
|
||||
|
||||
for (var i=0, len=cookieParts.length; i < len; i++){
|
||||
|
||||
//check for normally-formatted cookie (name-value)
|
||||
cookieNameValue = cookieParts[i].match(/([^=]+)=/i);
|
||||
if (cookieNameValue instanceof Array){
|
||||
try {
|
||||
cookieName = decode(cookieNameValue[1]);
|
||||
cookieValue = decodeValue(cookieParts[i].substring(cookieNameValue[1].length+1));
|
||||
} catch (ex){
|
||||
//intentionally ignore the cookie - the encoding is wrong
|
||||
}
|
||||
} else {
|
||||
//means the cookie does not have an "=", so treat it as a boolean flag
|
||||
cookieName = decode(cookieParts[i]);
|
||||
cookieValue = "";
|
||||
}
|
||||
cookies[cookieName] = cookieValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return cookies;
|
||||
},
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Determines if the cookie with the given name exists. This is useful for
|
||||
* Boolean cookies (those that do not follow the name=value convention).
|
||||
* @param {String} name The name of the cookie to check.
|
||||
* @return {Boolean} True if the cookie exists, false if not.
|
||||
* @method exists
|
||||
* @static
|
||||
*/
|
||||
exists: function(name) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
var cookies = this._parseCookieString(doc.cookie, true);
|
||||
|
||||
return cookies.hasOwnProperty(name);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the cookie value for the given name.
|
||||
* @param {String} name The name of the cookie to retrieve.
|
||||
* @param {Function|Object} options (Optional) An object containing one or more
|
||||
* cookie options: raw (true/false) and converter (a function).
|
||||
* The converter function is run on the value before returning it. The
|
||||
* function is not used if the cookie doesn't exist. The function can be
|
||||
* passed instead of the options object for backwards compatibility. When
|
||||
* raw is set to true, the cookie value is not URI decoded.
|
||||
* @return {Variant} If no converter is specified, returns a string or null if
|
||||
* the cookie doesn't exist. If the converter is specified, returns the value
|
||||
* returned from the converter or null if the cookie doesn't exist.
|
||||
* @method get
|
||||
* @static
|
||||
*/
|
||||
get : function (name, options) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
var cookies,
|
||||
cookie,
|
||||
converter;
|
||||
|
||||
//if options is a function, then it's the converter
|
||||
if (isFunction(options)) {
|
||||
converter = options;
|
||||
options = {};
|
||||
} else if (isObject(options)) {
|
||||
converter = options.converter;
|
||||
} else {
|
||||
options = {};
|
||||
}
|
||||
|
||||
cookies = this._parseCookieString(doc.cookie, !options.raw);
|
||||
cookie = cookies[name];
|
||||
|
||||
//should return null, not undefined if the cookie doesn't exist
|
||||
if (isUndefined(cookie)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!isFunction(converter)){
|
||||
return cookie;
|
||||
} else {
|
||||
return converter(cookie);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the value of a subcookie.
|
||||
* @param {String} name The name of the cookie to retrieve.
|
||||
* @param {String} subName The name of the subcookie to retrieve.
|
||||
* @param {Function} converter (Optional) A function to run on the value before returning
|
||||
* it. The function is not used if the cookie doesn't exist.
|
||||
* @return {Variant} If the cookie doesn't exist, null is returned. If the subcookie
|
||||
* doesn't exist, null if also returned. If no converter is specified and the
|
||||
* subcookie exists, a string is returned. If a converter is specified and the
|
||||
* subcookie exists, the value returned from the converter is returned.
|
||||
* @method getSub
|
||||
* @static
|
||||
*/
|
||||
getSub : function (name /*:String*/, subName /*:String*/, converter /*:Function*/) /*:Variant*/ {
|
||||
|
||||
var hash /*:Variant*/ = this.getSubs(name);
|
||||
|
||||
if (hash !== NULL) {
|
||||
|
||||
validateSubcookieName(subName); //throws error
|
||||
|
||||
if (isUndefined(hash[subName])){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!isFunction(converter)){
|
||||
return hash[subName];
|
||||
} else {
|
||||
return converter(hash[subName]);
|
||||
}
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an object containing name-value pairs stored in the cookie with the given name.
|
||||
* @param {String} name The name of the cookie to retrieve.
|
||||
* @return {Object} An object of name-value pairs if the cookie with the given name
|
||||
* exists, null if it does not.
|
||||
* @method getSubs
|
||||
* @static
|
||||
*/
|
||||
getSubs : function (name) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
var cookies = this._parseCookieString(doc.cookie, false);
|
||||
if (isString(cookies[name])){
|
||||
return this._parseCookieHash(cookies[name]);
|
||||
}
|
||||
return NULL;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a cookie from the machine by setting its expiration date to
|
||||
* sometime in the past.
|
||||
* @param {String} name The name of the cookie to remove.
|
||||
* @param {Object} options (Optional) An object containing one or more
|
||||
* cookie options: path (a string), domain (a string),
|
||||
* and secure (true/false). The expires option will be overwritten
|
||||
* by the method.
|
||||
* @return {String} The created cookie string.
|
||||
* @method remove
|
||||
* @static
|
||||
*/
|
||||
remove : function (name, options) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
//set options
|
||||
options = Y.merge(options || {}, {
|
||||
expires: new Date(0)
|
||||
});
|
||||
|
||||
//set cookie
|
||||
return this.set(name, "", options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a sub cookie with a given name.
|
||||
* @param {String} name The name of the cookie in which the subcookie exists.
|
||||
* @param {String} subName The name of the subcookie to remove.
|
||||
* @param {Object} options (Optional) An object containing one or more
|
||||
* cookie options: path (a string), domain (a string), expires (a Date object),
|
||||
* removeIfEmpty (true/false), and secure (true/false). This must be the same
|
||||
* settings as the original subcookie.
|
||||
* @return {String} The created cookie string.
|
||||
* @method removeSub
|
||||
* @static
|
||||
*/
|
||||
removeSub : function(name, subName, options) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
validateSubcookieName(subName); //throws error
|
||||
|
||||
options = options || {};
|
||||
|
||||
//get all subcookies for this cookie
|
||||
var subs = this.getSubs(name);
|
||||
|
||||
//delete the indicated subcookie
|
||||
if (isObject(subs) && subs.hasOwnProperty(subName)){
|
||||
delete subs[subName];
|
||||
|
||||
if (!options.removeIfEmpty) {
|
||||
//reset the cookie
|
||||
|
||||
return this.setSubs(name, subs, options);
|
||||
} else {
|
||||
//reset the cookie if there are subcookies left, else remove
|
||||
for (var key in subs){
|
||||
if (subs.hasOwnProperty(key) && !isFunction(subs[key]) && !isUndefined(subs[key])){
|
||||
return this.setSubs(name, subs, options);
|
||||
}
|
||||
}
|
||||
|
||||
return this.remove(name, options);
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a cookie with a given name and value.
|
||||
* @param {String} name The name of the cookie to set.
|
||||
* @param {Variant} value The value to set for the cookie.
|
||||
* @param {Object} options (Optional) An object containing one or more
|
||||
* cookie options: path (a string), domain (a string), expires (a Date object),
|
||||
* secure (true/false), and raw (true/false). Setting raw to true indicates
|
||||
* that the cookie should not be URI encoded before being set.
|
||||
* @return {String} The created cookie string.
|
||||
* @method set
|
||||
* @static
|
||||
*/
|
||||
set : function (name, value, options) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
if (isUndefined(value)){
|
||||
error("Cookie.set(): Value cannot be undefined.");
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
|
||||
var text = this._createCookieString(name, value, !options.raw, options);
|
||||
doc.cookie = text;
|
||||
return text;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a sub cookie with a given name to a particular value.
|
||||
* @param {String} name The name of the cookie to set.
|
||||
* @param {String} subName The name of the subcookie to set.
|
||||
* @param {Variant} value The value to set.
|
||||
* @param {Object} options (Optional) An object containing one or more
|
||||
* cookie options: path (a string), domain (a string), expires (a Date object),
|
||||
* and secure (true/false).
|
||||
* @return {String} The created cookie string.
|
||||
* @method setSub
|
||||
* @static
|
||||
*/
|
||||
setSub : function (name, subName, value, options) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
validateSubcookieName(subName); //throws error
|
||||
|
||||
if (isUndefined(value)){
|
||||
error("Cookie.setSub(): Subcookie value cannot be undefined.");
|
||||
}
|
||||
|
||||
var hash = this.getSubs(name);
|
||||
|
||||
if (!isObject(hash)){
|
||||
hash = {};
|
||||
}
|
||||
|
||||
hash[subName] = value;
|
||||
|
||||
return this.setSubs(name, hash, options);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a cookie with a given name to contain a hash of name-value pairs.
|
||||
* @param {String} name The name of the cookie to set.
|
||||
* @param {Object} value An object containing name-value pairs.
|
||||
* @param {Object} options (Optional) An object containing one or more
|
||||
* cookie options: path (a string), domain (a string), expires (a Date object),
|
||||
* and secure (true/false).
|
||||
* @return {String} The created cookie string.
|
||||
* @method setSubs
|
||||
* @static
|
||||
*/
|
||||
setSubs : function (name, value, options) {
|
||||
|
||||
validateCookieName(name); //throws error
|
||||
|
||||
if (!isObject(value)){
|
||||
error("Cookie.setSubs(): Cookie value must be an object.");
|
||||
}
|
||||
|
||||
var text /*:String*/ = this._createCookieString(name, this._createCookieHashString(value), false, options);
|
||||
doc.cookie = text;
|
||||
return text;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
}, '3.0.0' ,{requires:['yui-base']});
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
.yui-cssbase h1{font-size:138.5%;}.yui-cssbase h2{font-size:123.1%;}.yui-cssbase h3{font-size:108%;}.yui-cssbase h1,.yui-cssbase h2,.yui-cssbase h3{margin:1em 0;}.yui-cssbase h1,.yui-cssbase h2,.yui-cssbase h3,.yui-cssbase h4,.yui-cssbase h5,.yui-cssbase h6,.yui-cssbase strong{font-weight:bold;}.yui-cssbase abbr,.yui-cssbase acronym{border-bottom:1px dotted #000;cursor:help;}.yui-cssbase em{font-style:italic;}.yui-cssbase blockquote,.yui-cssbase ul,.yui-cssbase ol,.yui-cssbase dl{margin:1em;}.yui-cssbase ol,.yui-cssbase ul,.yui-cssbase dl{margin-left:2em;}.yui-cssbase ol li{list-style:decimal outside;}.yui-cssbase ul li{list-style:disc outside;}.yui-cssbase dl dd{margin-left:1em;}.yui-cssbase th,.yui-cssbase td{border:1px solid #000;padding:.5em;}.yui-cssbase th{font-weight:bold;text-align:center;}.yui-cssbase caption{margin-bottom:.5em;text-align:center;}.yui-cssbase p,.yui-cssbase fieldset,.yui-cssbase table,.yui-cssbase pre{margin-bottom:1em;}.yui-cssbase input[type=text],.yui-cssbase input[type=password],.yui-cssbase textarea{width:12.25em;*width:11.9em;}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
/* base.css, part of YUI's CSS Foundation */
|
||||
.yui-cssbase h1 {
|
||||
/*18px via YUI Fonts CSS foundation*/
|
||||
font-size:138.5%;
|
||||
}
|
||||
.yui-cssbase h2 {
|
||||
/*16px via YUI Fonts CSS foundation*/
|
||||
font-size:123.1%;
|
||||
}
|
||||
.yui-cssbase h3 {
|
||||
/*14px via YUI Fonts CSS foundation*/
|
||||
font-size:108%;
|
||||
}
|
||||
.yui-cssbase h1,.yui-cssbase h2,.yui-cssbase h3 {
|
||||
/* top & bottom margin based on font size */
|
||||
margin:1em 0;
|
||||
}
|
||||
.yui-cssbase h1,.yui-cssbase h2,.yui-cssbase h3,.yui-cssbase h4,.yui-cssbase h5,.yui-cssbase h6,.yui-cssbase strong {
|
||||
/*bringing boldness back to headers and the strong element*/
|
||||
font-weight:bold;
|
||||
}
|
||||
.yui-cssbase abbr,.yui-cssbase acronym {
|
||||
/*indicating to users that more info is available */
|
||||
border-bottom:1px dotted #000;
|
||||
cursor:help;
|
||||
}
|
||||
.yui-cssbase em {
|
||||
/*bringing italics back to the em element*/
|
||||
font-style:italic;
|
||||
}
|
||||
.yui-cssbase blockquote,.yui-cssbase ul,.yui-cssbase ol,.yui-cssbase dl {
|
||||
/*giving blockquotes and lists room to breath*/
|
||||
margin:1em;
|
||||
}
|
||||
.yui-cssbase ol,.yui-cssbase ul,.yui-cssbase dl {
|
||||
/*bringing lists on to the page with breathing room */
|
||||
margin-left:2em;
|
||||
}
|
||||
.yui-cssbase ol li {
|
||||
/*giving OL's LIs generated numbers*/
|
||||
list-style: decimal outside;
|
||||
}
|
||||
.yui-cssbase ul li {
|
||||
/*giving UL's LIs generated disc markers*/
|
||||
list-style: disc outside;
|
||||
}
|
||||
.yui-cssbase dl dd {
|
||||
/*providing spacing for definition terms*/
|
||||
margin-left:1em;
|
||||
}
|
||||
.yui-cssbase th,.yui-cssbase td {
|
||||
/*borders and padding to make the table readable*/
|
||||
border:1px solid #000;
|
||||
padding:.5em;
|
||||
}
|
||||
.yui-cssbase th {
|
||||
/*distinguishing table headers from data cells*/
|
||||
font-weight:bold;
|
||||
text-align:center;
|
||||
}
|
||||
.yui-cssbase caption {
|
||||
/*coordinated margin to match cell's padding*/
|
||||
margin-bottom:.5em;
|
||||
/*centered so it doesn't blend in to other content*/
|
||||
text-align:center;
|
||||
}
|
||||
.yui-cssbase p,.yui-cssbase fieldset,.yui-cssbase table,.yui-cssbase pre {
|
||||
/*so things don't run into each other*/
|
||||
margin-bottom:1em;
|
||||
}
|
||||
/* setting a consistent width, 160px;
|
||||
control of type=file still not possible */
|
||||
.yui-cssbase input[type=text],.yui-cssbase input[type=password],.yui-cssbase textarea{width:12.25em;*width:11.9em;}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.net/yui/license.txt
|
||||
version: 3.0.0
|
||||
build: 1549
|
||||
*/
|
||||
h1{font-size:138.5%;}h2{font-size:123.1%;}h3{font-size:108%;}h1,h2,h3{margin:1em 0;}h1,h2,h3,h4,h5,h6,strong{font-weight:bold;}abbr,acronym{border-bottom:1px dotted #000;cursor:help;}em{font-style:italic;}blockquote,ul,ol,dl{margin:1em;}ol,ul,dl{margin-left:2em;}ol li{list-style:decimal outside;}ul li{list-style:disc outside;}dl dd{margin-left:1em;}th,td{border:1px solid #000;padding:.5em;}th{font-weight:bold;text-align:center;}caption{margin-bottom:.5em;text-align:center;}p,fieldset,table,pre{margin-bottom:1em;}input[type=text],input[type=password],textarea{width:12.25em;*width:11.9em;}
|
||||