first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,193 @@
YUI.add('align-plugin', function (Y, NAME) {
/**
* Provides advanced positioning support for Node via a Plugin
* for centering and alignment.
* @module align-plugin
*/
var OFFSET_WIDTH = 'offsetWidth',
OFFSET_HEIGHT = 'offsetHeight',
undefined = undefined;
/**
* Node plugin which can be used to align a node with another node,
* region, or the viewport.
*
* @class Plugin.Align
* @param {Object} User configuration object
*/
function Align(config) {
if (config.host) {
this._host = config.host;
}
}
Align.prototype = {
/**
* Aligns node with a point on another node or region.
* Possible alignment points are:
* <dl>
* <dt>tl</dt>
* <dd>top left</dd>
* <dt>tr</dt>
* <dd>top right</dd>
* <dt>bl</dt>
* <dd>bottom left</dd>
* <dt>br</dt>
* <dd>bottom right</dd>
* <dt>tc</dt>
* <dd>top center</dd>
* <dt>bc</dt>
* <dd>bottom center</dd>
* <dt>rc</dt>
* <dd>right center</dd>
* <dt>lc</dt>
* <dd>left center</dd>
* <dt>cc</dt>
* <dd>center center</dd>
* </dl>
* @method to
* @param region {String|Node|HTMLElement|Object} The node or
* region to align with. Defaults to the viewport region.
* @param regionPoint {String} The point of the region to align with.
* @param point {String} The point of the node aligned to the region.
* @param resize {Boolean} Whether or not the node should re-align when
* the window is resized. Defaults to false.
*/
to: function(region, regionPoint, point, syncOnResize) {
// cache original args for syncing
this._syncArgs = Y.Array(arguments);
if (region.top === undefined) {
region = Y.one(region).get('region');
}
if (region) {
var xy = [region.left, region.top],
offxy = [region.width, region.height],
points = Align.points,
node = this._host,
NULL = null,
size = node.getAttrs([OFFSET_HEIGHT, OFFSET_WIDTH]),
nodeoff = [0 - size[OFFSET_WIDTH], 0 - size[OFFSET_HEIGHT]], // reverse offsets
regionFn0 = regionPoint ? points[regionPoint.charAt(0)]: NULL,
regionFn1 = (regionPoint && regionPoint !== 'cc') ? points[regionPoint.charAt(1)] : NULL,
nodeFn0 = point ? points[point.charAt(0)] : NULL,
nodeFn1 = (point && point !== 'cc') ? points[point.charAt(1)] : NULL;
if (regionFn0) {
xy = regionFn0(xy, offxy, regionPoint);
}
if (regionFn1) {
xy = regionFn1(xy, offxy, regionPoint);
}
if (nodeFn0) {
xy = nodeFn0(xy, nodeoff, point);
}
if (nodeFn1) {
xy = nodeFn1(xy, nodeoff, point);
}
if (xy && node) {
node.setXY(xy);
}
this._resize(syncOnResize);
}
return this;
},
sync: function() {
this.to.apply(this, this._syncArgs);
return this;
},
_resize: function(add) {
var handle = this._handle;
if (add && !handle) {
this._handle = Y.on('resize', this._onresize, window, this);
} else if (!add && handle) {
handle.detach();
}
},
_onresize: function() {
var self = this;
setTimeout(function() { // for performance
self.sync();
});
},
/**
* Aligns the center of a node to the center of another node or region.
* @method center
* @param region {Node|HTMLElement|Object} optional The node or
* region to align with. Defaults to the viewport region.
* the window is resized. If centering to viewport, this defaults
* to true, otherwise default is false.
*/
center: function(region, resize) {
this.to(region, 'cc', 'cc', resize);
return this;
},
/**
* Removes the resize handler, if any. This is called automatically
* when unplugged from the host node.
* @method destroy
*/
destroy: function() {
var handle = this._handle;
if (handle) {
handle.detach();
}
}
};
Align.points = {
't': function(xy, off) {
return xy;
},
'r': function(xy, off) {
return [xy[0] + off[0], xy[1]];
},
'b': function(xy, off) {
return [xy[0], xy[1] + off[1]];
},
'l': function(xy, off) {
return xy;
},
'c': function(xy, off, point) {
var axis = (point[0] === 't' || point[0] === 'b') ? 0 : 1,
ret, val;
if (point === 'cc') {
ret = [xy[0] + off[0] / 2, xy[1] + off[1] / 2];
} else {
val = xy[axis] + off[axis] / 2;
ret = (axis) ? [xy[0], val] : [val, xy[1]];
}
return ret;
}
};
Align.NAME = 'Align';
Align.NS = 'align';
Align.prototype.constructor = Align;
Y.namespace('Plugin');
Y.Plugin.Align = Align;
}, '3.18.1', {"requires": ["node-screen", "node-pluginhost"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("align-plugin",function(e,t){function s(e){e.host&&(this._host=e.host)}var n="offsetWidth",r="offsetHeight",i=i;s.prototype={to:function(t,o,u,a){this._syncArgs=e.Array(arguments),t.top===i&&(t=e.one(t).get("region"));if(t){var f=[t.left,t.top],l=[t.width,t.height],c=s.points,h=this._host,p=null,d=h.getAttrs([r,n]),v=[0-d[n],0-d[r]],m=o?c[o.charAt(0)]:p,g=o&&o!=="cc"?c[o.charAt(1)]:p,y=u?c[u.charAt(0)]:p,b=u&&u!=="cc"?c[u.charAt(1)]:p;m&&(f=m(f,l,o)),g&&(f=g(f,l,o)),y&&(f=y(f,v,u)),b&&(f=b(f,v,u)),f&&h&&h.setXY(f),this._resize(a)}return this},sync:function(){return this.to.apply(this,this._syncArgs),this},_resize:function(t){var n=this._handle;t&&!n?this._handle=e.on("resize",this._onresize,window,this):!t&&n&&n.detach()},_onresize:function(){var e=this;setTimeout(function(){e.sync()})},center:function(e,t){return this.to(e,"cc","cc",t),this},destroy:function(){var e=this._handle;e&&e.detach()}},s.points={t:function(e,t){return e},r:function(e,t){return[e[0]+t[0],e[1]]},b:function(e,t){return[e[0],e[1]+t[1]]},l:function(e,t){return e},c:function(e,t,n){var r=n[0]==="t"||n[0]==="b"?0:1,i,s;return n==="cc"?i=[e[0]+t[0]/2,e[1]+t[1]/2]:(s=e[r]+t[r]/2,i=r?[e[0],s]:[s,e[1]]),i}},s.NAME="Align",s.NS="align",s.prototype.constructor=s,e.namespace("Plugin"),e.Plugin.Align=s},"3.18.1",{requires:["node-screen","node-pluginhost"]});
@@ -0,0 +1,193 @@
YUI.add('align-plugin', function (Y, NAME) {
/**
* Provides advanced positioning support for Node via a Plugin
* for centering and alignment.
* @module align-plugin
*/
var OFFSET_WIDTH = 'offsetWidth',
OFFSET_HEIGHT = 'offsetHeight',
undefined = undefined;
/**
* Node plugin which can be used to align a node with another node,
* region, or the viewport.
*
* @class Plugin.Align
* @param {Object} User configuration object
*/
function Align(config) {
if (config.host) {
this._host = config.host;
}
}
Align.prototype = {
/**
* Aligns node with a point on another node or region.
* Possible alignment points are:
* <dl>
* <dt>tl</dt>
* <dd>top left</dd>
* <dt>tr</dt>
* <dd>top right</dd>
* <dt>bl</dt>
* <dd>bottom left</dd>
* <dt>br</dt>
* <dd>bottom right</dd>
* <dt>tc</dt>
* <dd>top center</dd>
* <dt>bc</dt>
* <dd>bottom center</dd>
* <dt>rc</dt>
* <dd>right center</dd>
* <dt>lc</dt>
* <dd>left center</dd>
* <dt>cc</dt>
* <dd>center center</dd>
* </dl>
* @method to
* @param region {String|Node|HTMLElement|Object} The node or
* region to align with. Defaults to the viewport region.
* @param regionPoint {String} The point of the region to align with.
* @param point {String} The point of the node aligned to the region.
* @param resize {Boolean} Whether or not the node should re-align when
* the window is resized. Defaults to false.
*/
to: function(region, regionPoint, point, syncOnResize) {
// cache original args for syncing
this._syncArgs = Y.Array(arguments);
if (region.top === undefined) {
region = Y.one(region).get('region');
}
if (region) {
var xy = [region.left, region.top],
offxy = [region.width, region.height],
points = Align.points,
node = this._host,
NULL = null,
size = node.getAttrs([OFFSET_HEIGHT, OFFSET_WIDTH]),
nodeoff = [0 - size[OFFSET_WIDTH], 0 - size[OFFSET_HEIGHT]], // reverse offsets
regionFn0 = regionPoint ? points[regionPoint.charAt(0)]: NULL,
regionFn1 = (regionPoint && regionPoint !== 'cc') ? points[regionPoint.charAt(1)] : NULL,
nodeFn0 = point ? points[point.charAt(0)] : NULL,
nodeFn1 = (point && point !== 'cc') ? points[point.charAt(1)] : NULL;
if (regionFn0) {
xy = regionFn0(xy, offxy, regionPoint);
}
if (regionFn1) {
xy = regionFn1(xy, offxy, regionPoint);
}
if (nodeFn0) {
xy = nodeFn0(xy, nodeoff, point);
}
if (nodeFn1) {
xy = nodeFn1(xy, nodeoff, point);
}
if (xy && node) {
node.setXY(xy);
}
this._resize(syncOnResize);
}
return this;
},
sync: function() {
this.to.apply(this, this._syncArgs);
return this;
},
_resize: function(add) {
var handle = this._handle;
if (add && !handle) {
this._handle = Y.on('resize', this._onresize, window, this);
} else if (!add && handle) {
handle.detach();
}
},
_onresize: function() {
var self = this;
setTimeout(function() { // for performance
self.sync();
});
},
/**
* Aligns the center of a node to the center of another node or region.
* @method center
* @param region {Node|HTMLElement|Object} optional The node or
* region to align with. Defaults to the viewport region.
* the window is resized. If centering to viewport, this defaults
* to true, otherwise default is false.
*/
center: function(region, resize) {
this.to(region, 'cc', 'cc', resize);
return this;
},
/**
* Removes the resize handler, if any. This is called automatically
* when unplugged from the host node.
* @method destroy
*/
destroy: function() {
var handle = this._handle;
if (handle) {
handle.detach();
}
}
};
Align.points = {
't': function(xy, off) {
return xy;
},
'r': function(xy, off) {
return [xy[0] + off[0], xy[1]];
},
'b': function(xy, off) {
return [xy[0], xy[1] + off[1]];
},
'l': function(xy, off) {
return xy;
},
'c': function(xy, off, point) {
var axis = (point[0] === 't' || point[0] === 'b') ? 0 : 1,
ret, val;
if (point === 'cc') {
ret = [xy[0] + off[0] / 2, xy[1] + off[1] / 2];
} else {
val = xy[axis] + off[axis] / 2;
ret = (axis) ? [xy[0], val] : [val, xy[1]];
}
return ret;
}
};
Align.NAME = 'Align';
Align.NS = 'align';
Align.prototype.constructor = Align;
Y.namespace('Plugin');
Y.Plugin.Align = Align;
}, '3.18.1', {"requires": ["node-screen", "node-pluginhost"]});
@@ -0,0 +1,686 @@
YUI.add('anim-base', function (Y, NAME) {
/**
* 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 = {},
_timer;
Y.Anim = function() {
Y.Anim.superclass.constructor.apply(this, arguments);
Y.Anim._instances[Y.stamp(this)] = this;
};
Y.Anim.NAME = 'anim';
Y.Anim._instances = {};
/**
* Regex of properties that should use the default unit.
*
* @property RE_DEFAULT_UNIT
* @static
*/
Y.Anim.RE_DEFAULT_UNIT = /^width|height|top|right|bottom|left|margin.*|padding.*|border.*$/i;
/**
* The default unit to use with properties that pass the RE_DEFAULT_UNIT test.
*
* @property DEFAULT_UNIT
* @static
*/
Y.Anim.DEFAULT_UNIT = 'px';
Y.Anim.DEFAULT_EASING = function (t, b, c, d) {
return c * t / d + b; // linear easing
};
/**
* Time in milliseconds passed to setInterval for frame processing
*
* @property intervalTime
* @default 20
* @static
*/
Y.Anim._intervalTime = 20;
/**
* Bucket for custom getters and setters
*
* @property behaviors
* @static
*/
Y.Anim.behaviors = {
left: {
get: function(anim, attr) {
return anim._getOffset(attr);
}
}
};
Y.Anim.behaviors.top = Y.Anim.behaviors.left;
/**
* The default setter to use when setting object properties.
*
* @property DEFAULT_SETTER
* @static
*/
Y.Anim.DEFAULT_SETTER = function(anim, att, from, to, elapsed, duration, fn, unit) {
var node = anim._node,
domNode = node._node,
val = fn(elapsed, NUM(from), NUM(to) - NUM(from), duration);
if (domNode) {
if ('style' in domNode && (att in domNode.style || att in Y.DOM.CUSTOM_STYLES)) {
unit = unit || '';
node.setStyle(att, val + unit);
} else if ('attributes' in domNode && att in domNode.attributes) {
node.setAttribute(att, val);
} else if (att in domNode) {
domNode[att] = val;
}
} else if (node.set) {
node.set(att, val);
} else if (att in node) {
node[att] = val;
}
};
/**
* The default getter to use when getting object properties.
*
* @property DEFAULT_GETTER
* @static
*/
Y.Anim.DEFAULT_GETTER = function(anim, att) {
var node = anim._node,
domNode = node._node,
val = '';
if (domNode) {
if ('style' in domNode && (att in domNode.style || att in Y.DOM.CUSTOM_STYLES)) {
val = node.getComputedStyle(att);
} else if ('attributes' in domNode && att in domNode.attributes) {
val = node.getAttribute(att);
} else if (att in domNode) {
val = domNode[att];
}
} else if (node.get) {
val = node.get(att);
} else if (att in node) {
val = node[att];
}
return val;
};
Y.Anim.ATTRS = {
/**
* The object to be animated.
* @attribute node
* @type Node
*/
node: {
setter: function(node) {
if (node) {
if (typeof node === 'string' || node.nodeType) {
node = Y.one(node);
}
}
this._node = node;
if (!node) {
Y.log(node + ' is not a valid node', 'warn', 'Anim');
}
return node;
}
},
/**
* The length of the animation. Defaults to "1" (second).
* @attribute duration
* @type NUM
*/
duration: {
value: 1
},
/**
* The method that will provide values to the attribute(s) during the animation.
* Defaults to "Easing.easeNone".
* @attribute easing
* @type Function
*/
easing: {
value: Y.Anim.DEFAULT_EASING,
setter: function(val) {
if (typeof val === 'string' && Y.Easing) {
return Y.Easing[val];
}
}
},
/**
* The starting values for the animated properties.
*
* Fields may be strings, numbers, or functions.
* If a function is used, the return value becomes the from value.
* If no from value is specified, the DEFAULT_GETTER will be used.
* Supports any unit, provided it matches the "to" (or default)
* unit (e.g. `{width: '10em', color: 'rgb(0, 0, 0)', borderColor: '#ccc'}`).
*
* If using the default ('px' for length-based units), the unit may be omitted
* (e.g. `{width: 100}, borderColor: 'ccc'}`, which defaults to pixels
* and hex, respectively).
*
* @attribute from
* @type Object
*/
from: {},
/**
* The ending values for the animated properties.
*
* Fields may be strings, numbers, or functions.
* Supports any unit, provided it matches the "from" (or default)
* unit (e.g. `{width: '50%', color: 'red', borderColor: '#ccc'}`).
*
* If using the default ('px' for length-based units), the unit may be omitted
* (e.g. `{width: 100, borderColor: 'ccc'}`, which defaults to pixels
* and hex, respectively).
*
* @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, the `from` and `to` attributes are swapped,
* and the animation is then run starting from `from`.
* @attribute reverse
* @type Boolean
* @default false
*/
reverse: {
value: false
}
};
/**
* Runs all animation instances.
* @method run
* @static
*/
Y.Anim.run = function() {
var instances = Y.Anim._instances,
i;
for (i in instances) {
if (instances[i].run) {
instances[i].run();
}
}
};
/**
* Pauses all animation instances.
* @method pause
* @static
*/
Y.Anim.pause = function() {
for (var i in _running) { // stop timer if nothing running
if (_running[i].pause) {
_running[i].pause();
}
}
Y.Anim._stopTimer();
};
/**
* Stops all animation instances.
* @method stop
* @static
*/
Y.Anim.stop = function() {
for (var i in _running) { // stop timer if nothing running
if (_running[i].stop) {
_running[i].stop();
}
}
Y.Anim._stopTimer();
};
Y.Anim._startTimer = function() {
if (!_timer) {
_timer = setInterval(Y.Anim._runFrame, Y.Anim._intervalTime);
}
};
Y.Anim._stopTimer = function() {
clearInterval(_timer);
_timer = 0;
};
/**
* Called per Interval to handle each animation frame.
* @method _runFrame
* @private
* @static
*/
Y.Anim._runFrame = function() {
var done = true,
anim;
for (anim in _running) {
if (_running[anim]._runFrame) {
done = false;
_running[anim]._runFrame();
}
}
if (done) {
Y.Anim._stopTimer();
}
};
Y.Anim.RE_UNITS = /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/;
var proto = {
/**
* Starts or resumes an animation.
* @method run
* @chainable
*/
run: function() {
if (this.get(PAUSED)) {
this._resume();
} else if (!this.get(RUNNING)) {
this._start();
}
return this;
},
/**
* Pauses the animation and
* freezes it in its current state and time.
* Calling run() will continue where it left off.
* @method pause
* @chainable
*/
pause: function() {
if (this.get(RUNNING)) {
this._pause();
}
return this;
},
/**
* Stops the animation and resets its time.
* @method stop
* @param {Boolean} finish If true, the animation will move to the last frame
* @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;
this._set(START_TIME, new Date() - this.get(ELAPSED_TIME));
Y.Anim._startTimer();
/**
* @event resume
* @description fires when an animation is resumed (run from pause).
* @param {Event} ev The pause event.
* @type Event.Custom
*/
this.fire('resume');
},
_end: function(finish) {
var duration = this.get('duration') * 1000;
if (finish) { // jump to last frame
this._runAttrs(duration, duration, this.get(REVERSE));
}
this._set(START_TIME, null);
this._set(ELAPSED_TIME, 0);
this._set(PAUSED, false);
delete _running[Y.stamp(this)];
this.fire(END, {elapsed: this.get(ELAPSED_TIME)});
},
_runFrame: function() {
var d = this._runtimeAttr.duration,
t = new Date() - this.get(START_TIME),
reverse = this.get(REVERSE),
done = (t >= d);
this._runAttrs(t, d, reverse);
this._actualFrames += 1;
this._set(ELAPSED_TIME, t);
this.fire(TWEEN);
if (done) {
this._lastFrame();
}
},
_runAttrs: function(t, d, reverse) {
var attr = this._runtimeAttr,
customAttr = Y.Anim.behaviors,
easing = attr.easing,
lastFrame = d,
done = false,
attribute,
setter,
i;
if (t >= d) {
done = true;
}
if (reverse) {
t = d - t;
lastFrame = 0;
}
for (i in attr) {
if (attr[i].to) {
attribute = attr[i];
setter = (i in customAttr && 'set' in customAttr[i]) ?
customAttr[i].set : Y.Anim.DEFAULT_SETTER;
if (!done) {
setter(this, i, attribute.from, attribute.to, t, d, easing, attribute.unit);
} else {
setter(this, i, attribute.from, attribute.to, lastFrame, d, easing, attribute.unit);
}
}
}
},
_lastFrame: function() {
var iter = this.get('iterations'),
iterCount = this.get(ITERATION_COUNT);
iterCount += 1;
if (iter === 'infinite' || iterCount < iter) {
if (this.get('direction') === 'alternate') {
this.set(REVERSE, !this.get(REVERSE)); // flip it
}
/**
* @event iteration
* @description fires when an animation begins an iteration.
* @param {Event} ev The iteration event.
* @type Event.Custom
*/
this.fire('iteration');
} else {
iterCount = 0;
this._end();
}
this._set(START_TIME, new Date());
this._set(ITERATION_COUNT, iterCount);
},
_initAnimAttr: function() {
var from = this.get('from') || {},
to = this.get('to') || {},
attr = {
duration: this.get('duration') * 1000,
easing: this.get('easing')
},
customAttr = Y.Anim.behaviors,
node = this.get(NODE), // implicit attr init
unit, begin, end;
Y.each(to, function(val, name) {
if (typeof val === 'function') {
val = val.call(this, node);
}
begin = from[name];
if (begin === undefined) {
begin = (name in customAttr && 'get' in customAttr[name]) ?
customAttr[name].get(this, name) : Y.Anim.DEFAULT_GETTER(this, name);
} else if (typeof begin === 'function') {
begin = begin.call(this, node);
}
var mFrom = Y.Anim.RE_UNITS.exec(begin),
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: Y.Lang.isObject(begin) ? Y.clone(begin) : begin,
to: end,
unit: unit
};
}, this);
this._runtimeAttr = attr;
},
// TODO: move to computedStyle? (browsers dont agree on default computed offsets)
_getOffset: function(attr) {
var node = this._node,
val = node.getComputedStyle(attr),
get = (attr === 'left') ? 'getX': 'getY',
set = (attr === 'left') ? 'setX': 'setY',
position;
if (val === 'auto') {
position = node.getStyle('position');
if (position === 'absolute' || position === 'fixed') {
val = node[get]();
node[set](val);
} else {
val = 0;
}
}
return val;
},
destructor: function() {
delete Y.Anim._instances[Y.stamp(this)];
}
};
Y.extend(Y.Anim, Y.Base, proto);
}, '3.18.1', {"requires": ["base-base", "node-style", "color-base"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("anim-base",function(e,t){var n="running",r="startTime",i="elapsedTime",s="start",o="tween",u="end",a="node",f="paused",l="reverse",c="iterationCount",h=Number,p={},d;e.Anim=function(){e.Anim.superclass.constructor.apply(this,arguments),e.Anim._instances[e.stamp(this)]=this},e.Anim.NAME="anim",e.Anim._instances={},e.Anim.RE_DEFAULT_UNIT=/^width|height|top|right|bottom|left|margin.*|padding.*|border.*$/i,e.Anim.DEFAULT_UNIT="px",e.Anim.DEFAULT_EASING=function(e,t,n,r){return n*e/r+t},e.Anim._intervalTime=20,e.Anim.behaviors={left:{get:function(e,t){return e._getOffset(t)}}},e.Anim.behaviors.top=e.Anim.behaviors.left,e.Anim.DEFAULT_SETTER=function(t,n,r,i,s,o,u,a){var f=t._node,l=f._node,c=u(s,h(r),h(i)-h(r),o);l?"style"in l&&(n in l.style||n in e.DOM.CUSTOM_STYLES)?(a=a||"",f.setStyle(n,c+a)):"attributes"in l&&n in l.attributes?f.setAttribute(n,c):n in l&&(l[n]=c):f.set?f.set(n,c):n in f&&(f[n]=c)},e.Anim.DEFAULT_GETTER=function(t,n){var r=t._node,i=r._node,s="";return i?"style"in i&&(n in i.style||n in e.DOM.CUSTOM_STYLES)?s=r.getComputedStyle(n):"attributes"in i&&n in i.attributes?s=r.getAttribute(n):n in i&&(s=i[n]):r.get?s=r.get(n):n in r&&(s=r[n]),s},e.Anim.ATTRS={node:{setter:function(t){return t&&(typeof t=="string"||t.nodeType)&&(t=e.one(t)),this._node=t,!t,t}},duration:{value:1},easing:{value:e.Anim.DEFAULT_EASING,setter:function(t){if(typeof t=="string"&&e.Easing)return e.Easing[t]}},from:{},to:{},startTime:{value:0,readOnly:!0},elapsedTime:{value:0,readOnly:!0},running:{getter:function(){return!!p[e.stamp(this)]},value:!1,readOnly:!0},iterations:{value:1},iterationCount:{value:0,readOnly:!0},direction:{value:"normal"},paused:{readOnly:!0,value:!1},reverse:{value:!1}},e.Anim.run=function(){var t=e.Anim._instances,n;for(n in t)t[n].run&&t[n].run()},e.Anim.pause=function(){for(var t in p)p[t].pause&&p[t].pause();e.Anim._stopTimer()},e.Anim.stop=function(){for(var t in p)p[t].stop&&p[t].stop();e.Anim._stopTimer()},e.Anim._startTimer=function(){d||(d=setInterval(e.Anim._runFrame,e.Anim._intervalTime))},e.Anim._stopTimer=function(){clearInterval(d),d=0},e.Anim._runFrame=function(){var t=!0,n;for(n in p)p[n]._runFrame&&(t=!1,p[n]._runFrame());t&&e.Anim._stopTimer()},e.Anim.RE_UNITS=/^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/;var v={run:function(){return this.get(f)?this._resume():this.get(n)||this._start(),this},pause:function(){return this.get(n)&&this._pause(),this},stop:function(e){return(this.get(n)||this.get(f))&&this._end(e),this},_added:!1,_start:function(){this._set(r,new Date-this.get(i)),this._actualFrames=0,this.get(f)||this._initAnimAttr(),p[e.stamp(this)]=this,e.Anim._startTimer(),this.fire(s)},_pause:function(){this._set(r,null),this._set(f,!0),delete p[e.stamp(this)],this.fire("pause")},_resume:function(){this._set(f,!1),p[e.stamp(this)]=this,this._set(r,new Date-this.get(i)),e.Anim._startTimer(),this.fire("resume")},_end:function(t){var n=this.get("duration")*1e3;t&&this._runAttrs(n,n,this.get(l)),this._set(r,null),this._set(i,0),this._set(f,!1),delete p[e.stamp(this)],this.fire(u,{elapsed:this.get(i)})},_runFrame:function(){var e=this._runtimeAttr.duration,t=new Date-this.get(r),n=this.get(l),s=t>=e;this._runAttrs(t,e,n),this._actualFrames+=1,this._set(i,t),this.fire(o),s&&this._lastFrame()},_runAttrs:function(t,n,r){var i=this._runtimeAttr,s=e.Anim.behaviors,o=i.easing,u=n,a=!1,f,l,c;t>=n&&(a=!0),r&&(t=n-t,u=0);for(c in i)i[c].to&&(f=i[c],l=c in s&&"set"in s[c]?s[c].set:e.Anim.DEFAULT_SETTER,a?l(this,c,f.from,f.to,u,n,o,f.unit):l(this,c,f.from,f.to,t,n,o,f.unit))},_lastFrame:function(){var e=this.get("iterations"),t=this.get(c);t+=1,e==="infinite"||t<e?(this.get("direction")==="alternate"&&this.set(l,!this.get(l)),this.fire("iteration")):(t=0,this._end()),this._set(r,new Date),this._set(c,t)},_initAnimAttr:function(){var t=this.get("from")||{},n=this.get("to")||{},r={duration:this.get("duration")*1e3,easing:this.get("easing")},i=e.Anim.behaviors,s=this.get(a),o,u,f;e.each(n,function(n,a){typeof n=="function"&&(n=n.call(this,s)),u=t[a],u===undefined?u=a in i&&"get"in i[a]?i[a].get(this,a):e.Anim.DEFAULT_GETTER(this,a):typeof u=="function"&&(u=u.call(this,s));var l=e.Anim.RE_UNITS.exec(u),c=e.Anim.RE_UNITS.exec(n);u=l?l[1]:u,f=c?c[1]:n,o=c?c[2]:l?l[2]:"",!o&&e.Anim.RE_DEFAULT_UNIT.test(a)&&(o=e.Anim.DEFAULT_UNIT);if(!u||!f){e.error('invalid "from" or "to" for "'+a+'"',"Anim");return}r[a]={from:e.Lang.isObject(u)?e.clone(u):u,to:f,unit:o}},this),this._runtimeAttr=r},_getOffset:function(e){var t=this._node,n=t.getComputedStyle(e),r=e==="left"?"getX":"getY",i=e==="left"?"setX":"setY",s;return n==="auto"&&(s=t.getStyle("position"),s==="absolute"||s==="fixed"?(n=t[r](),t[i](n)):n=0),n},destructor:function(){delete e.Anim._instances[e.stamp(this)]}};e.extend(e.Anim,e.Base,v)},"3.18.1",{requires:["base-base","node-style","color-base"]});
+685
View File
@@ -0,0 +1,685 @@
YUI.add('anim-base', function (Y, NAME) {
/**
* 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 = {},
_timer;
Y.Anim = function() {
Y.Anim.superclass.constructor.apply(this, arguments);
Y.Anim._instances[Y.stamp(this)] = this;
};
Y.Anim.NAME = 'anim';
Y.Anim._instances = {};
/**
* Regex of properties that should use the default unit.
*
* @property RE_DEFAULT_UNIT
* @static
*/
Y.Anim.RE_DEFAULT_UNIT = /^width|height|top|right|bottom|left|margin.*|padding.*|border.*$/i;
/**
* The default unit to use with properties that pass the RE_DEFAULT_UNIT test.
*
* @property DEFAULT_UNIT
* @static
*/
Y.Anim.DEFAULT_UNIT = 'px';
Y.Anim.DEFAULT_EASING = function (t, b, c, d) {
return c * t / d + b; // linear easing
};
/**
* Time in milliseconds passed to setInterval for frame processing
*
* @property intervalTime
* @default 20
* @static
*/
Y.Anim._intervalTime = 20;
/**
* Bucket for custom getters and setters
*
* @property behaviors
* @static
*/
Y.Anim.behaviors = {
left: {
get: function(anim, attr) {
return anim._getOffset(attr);
}
}
};
Y.Anim.behaviors.top = Y.Anim.behaviors.left;
/**
* The default setter to use when setting object properties.
*
* @property DEFAULT_SETTER
* @static
*/
Y.Anim.DEFAULT_SETTER = function(anim, att, from, to, elapsed, duration, fn, unit) {
var node = anim._node,
domNode = node._node,
val = fn(elapsed, NUM(from), NUM(to) - NUM(from), duration);
if (domNode) {
if ('style' in domNode && (att in domNode.style || att in Y.DOM.CUSTOM_STYLES)) {
unit = unit || '';
node.setStyle(att, val + unit);
} else if ('attributes' in domNode && att in domNode.attributes) {
node.setAttribute(att, val);
} else if (att in domNode) {
domNode[att] = val;
}
} else if (node.set) {
node.set(att, val);
} else if (att in node) {
node[att] = val;
}
};
/**
* The default getter to use when getting object properties.
*
* @property DEFAULT_GETTER
* @static
*/
Y.Anim.DEFAULT_GETTER = function(anim, att) {
var node = anim._node,
domNode = node._node,
val = '';
if (domNode) {
if ('style' in domNode && (att in domNode.style || att in Y.DOM.CUSTOM_STYLES)) {
val = node.getComputedStyle(att);
} else if ('attributes' in domNode && att in domNode.attributes) {
val = node.getAttribute(att);
} else if (att in domNode) {
val = domNode[att];
}
} else if (node.get) {
val = node.get(att);
} else if (att in node) {
val = node[att];
}
return val;
};
Y.Anim.ATTRS = {
/**
* The object to be animated.
* @attribute node
* @type Node
*/
node: {
setter: function(node) {
if (node) {
if (typeof node === 'string' || node.nodeType) {
node = Y.one(node);
}
}
this._node = node;
if (!node) {
}
return node;
}
},
/**
* The length of the animation. Defaults to "1" (second).
* @attribute duration
* @type NUM
*/
duration: {
value: 1
},
/**
* The method that will provide values to the attribute(s) during the animation.
* Defaults to "Easing.easeNone".
* @attribute easing
* @type Function
*/
easing: {
value: Y.Anim.DEFAULT_EASING,
setter: function(val) {
if (typeof val === 'string' && Y.Easing) {
return Y.Easing[val];
}
}
},
/**
* The starting values for the animated properties.
*
* Fields may be strings, numbers, or functions.
* If a function is used, the return value becomes the from value.
* If no from value is specified, the DEFAULT_GETTER will be used.
* Supports any unit, provided it matches the "to" (or default)
* unit (e.g. `{width: '10em', color: 'rgb(0, 0, 0)', borderColor: '#ccc'}`).
*
* If using the default ('px' for length-based units), the unit may be omitted
* (e.g. `{width: 100}, borderColor: 'ccc'}`, which defaults to pixels
* and hex, respectively).
*
* @attribute from
* @type Object
*/
from: {},
/**
* The ending values for the animated properties.
*
* Fields may be strings, numbers, or functions.
* Supports any unit, provided it matches the "from" (or default)
* unit (e.g. `{width: '50%', color: 'red', borderColor: '#ccc'}`).
*
* If using the default ('px' for length-based units), the unit may be omitted
* (e.g. `{width: 100, borderColor: 'ccc'}`, which defaults to pixels
* and hex, respectively).
*
* @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, the `from` and `to` attributes are swapped,
* and the animation is then run starting from `from`.
* @attribute reverse
* @type Boolean
* @default false
*/
reverse: {
value: false
}
};
/**
* Runs all animation instances.
* @method run
* @static
*/
Y.Anim.run = function() {
var instances = Y.Anim._instances,
i;
for (i in instances) {
if (instances[i].run) {
instances[i].run();
}
}
};
/**
* Pauses all animation instances.
* @method pause
* @static
*/
Y.Anim.pause = function() {
for (var i in _running) { // stop timer if nothing running
if (_running[i].pause) {
_running[i].pause();
}
}
Y.Anim._stopTimer();
};
/**
* Stops all animation instances.
* @method stop
* @static
*/
Y.Anim.stop = function() {
for (var i in _running) { // stop timer if nothing running
if (_running[i].stop) {
_running[i].stop();
}
}
Y.Anim._stopTimer();
};
Y.Anim._startTimer = function() {
if (!_timer) {
_timer = setInterval(Y.Anim._runFrame, Y.Anim._intervalTime);
}
};
Y.Anim._stopTimer = function() {
clearInterval(_timer);
_timer = 0;
};
/**
* Called per Interval to handle each animation frame.
* @method _runFrame
* @private
* @static
*/
Y.Anim._runFrame = function() {
var done = true,
anim;
for (anim in _running) {
if (_running[anim]._runFrame) {
done = false;
_running[anim]._runFrame();
}
}
if (done) {
Y.Anim._stopTimer();
}
};
Y.Anim.RE_UNITS = /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/;
var proto = {
/**
* Starts or resumes an animation.
* @method run
* @chainable
*/
run: function() {
if (this.get(PAUSED)) {
this._resume();
} else if (!this.get(RUNNING)) {
this._start();
}
return this;
},
/**
* Pauses the animation and
* freezes it in its current state and time.
* Calling run() will continue where it left off.
* @method pause
* @chainable
*/
pause: function() {
if (this.get(RUNNING)) {
this._pause();
}
return this;
},
/**
* Stops the animation and resets its time.
* @method stop
* @param {Boolean} finish If true, the animation will move to the last frame
* @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;
this._set(START_TIME, new Date() - this.get(ELAPSED_TIME));
Y.Anim._startTimer();
/**
* @event resume
* @description fires when an animation is resumed (run from pause).
* @param {Event} ev The pause event.
* @type Event.Custom
*/
this.fire('resume');
},
_end: function(finish) {
var duration = this.get('duration') * 1000;
if (finish) { // jump to last frame
this._runAttrs(duration, duration, this.get(REVERSE));
}
this._set(START_TIME, null);
this._set(ELAPSED_TIME, 0);
this._set(PAUSED, false);
delete _running[Y.stamp(this)];
this.fire(END, {elapsed: this.get(ELAPSED_TIME)});
},
_runFrame: function() {
var d = this._runtimeAttr.duration,
t = new Date() - this.get(START_TIME),
reverse = this.get(REVERSE),
done = (t >= d);
this._runAttrs(t, d, reverse);
this._actualFrames += 1;
this._set(ELAPSED_TIME, t);
this.fire(TWEEN);
if (done) {
this._lastFrame();
}
},
_runAttrs: function(t, d, reverse) {
var attr = this._runtimeAttr,
customAttr = Y.Anim.behaviors,
easing = attr.easing,
lastFrame = d,
done = false,
attribute,
setter,
i;
if (t >= d) {
done = true;
}
if (reverse) {
t = d - t;
lastFrame = 0;
}
for (i in attr) {
if (attr[i].to) {
attribute = attr[i];
setter = (i in customAttr && 'set' in customAttr[i]) ?
customAttr[i].set : Y.Anim.DEFAULT_SETTER;
if (!done) {
setter(this, i, attribute.from, attribute.to, t, d, easing, attribute.unit);
} else {
setter(this, i, attribute.from, attribute.to, lastFrame, d, easing, attribute.unit);
}
}
}
},
_lastFrame: function() {
var iter = this.get('iterations'),
iterCount = this.get(ITERATION_COUNT);
iterCount += 1;
if (iter === 'infinite' || iterCount < iter) {
if (this.get('direction') === 'alternate') {
this.set(REVERSE, !this.get(REVERSE)); // flip it
}
/**
* @event iteration
* @description fires when an animation begins an iteration.
* @param {Event} ev The iteration event.
* @type Event.Custom
*/
this.fire('iteration');
} else {
iterCount = 0;
this._end();
}
this._set(START_TIME, new Date());
this._set(ITERATION_COUNT, iterCount);
},
_initAnimAttr: function() {
var from = this.get('from') || {},
to = this.get('to') || {},
attr = {
duration: this.get('duration') * 1000,
easing: this.get('easing')
},
customAttr = Y.Anim.behaviors,
node = this.get(NODE), // implicit attr init
unit, begin, end;
Y.each(to, function(val, name) {
if (typeof val === 'function') {
val = val.call(this, node);
}
begin = from[name];
if (begin === undefined) {
begin = (name in customAttr && 'get' in customAttr[name]) ?
customAttr[name].get(this, name) : Y.Anim.DEFAULT_GETTER(this, name);
} else if (typeof begin === 'function') {
begin = begin.call(this, node);
}
var mFrom = Y.Anim.RE_UNITS.exec(begin),
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: Y.Lang.isObject(begin) ? Y.clone(begin) : begin,
to: end,
unit: unit
};
}, this);
this._runtimeAttr = attr;
},
// TODO: move to computedStyle? (browsers dont agree on default computed offsets)
_getOffset: function(attr) {
var node = this._node,
val = node.getComputedStyle(attr),
get = (attr === 'left') ? 'getX': 'getY',
set = (attr === 'left') ? 'setX': 'setY',
position;
if (val === 'auto') {
position = node.getStyle('position');
if (position === 'absolute' || position === 'fixed') {
val = node[get]();
node[set](val);
} else {
val = 0;
}
}
return val;
},
destructor: function() {
delete Y.Anim._instances[Y.stamp(this)];
}
};
Y.extend(Y.Anim, Y.Base, proto);
}, '3.18.1', {"requires": ["base-base", "node-style", "color-base"]});
@@ -0,0 +1,53 @@
YUI.add('anim-color', function (Y, NAME) {
/**
* Adds support for color properties in <code>to</code>
* and <code>from</code> attributes.
* @module anim
* @submodule anim-color
*/
var NUM = Number;
Y.Anim.getUpdatedColorValue = function(fromColor, toColor, elapsed, duration, fn)
{
fromColor = Y.Color.re_RGB.exec(Y.Color.toRGB(fromColor));
toColor = Y.Color.re_RGB.exec(Y.Color.toRGB(toColor));
if (!fromColor || fromColor.length < 3 || !toColor || toColor.length < 3) {
Y.error('invalid from or to passed to color behavior');
}
return 'rgb(' + [
Math.floor(fn(elapsed, NUM(fromColor[1]), NUM(toColor[1]) - NUM(fromColor[1]), duration)),
Math.floor(fn(elapsed, NUM(fromColor[2]), NUM(toColor[2]) - NUM(fromColor[2]), duration)),
Math.floor(fn(elapsed, NUM(fromColor[3]), NUM(toColor[3]) - NUM(fromColor[3]), duration))
].join(', ') + ')';
};
Y.Anim.behaviors.color = {
set: function(anim, att, from, to, elapsed, duration, fn) {
anim._node.setStyle(att, Y.Anim.getUpdatedColorValue(from, to, elapsed, duration, fn));
},
// 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) {
Y.Anim.behaviors[v] = Y.Anim.behaviors.color;
}
);
}, '3.18.1', {"requires": ["anim-base"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("anim-color",function(e,t){var n=Number;e.Anim.getUpdatedColorValue=function(t,r,i,s,o){return t=e.Color.re_RGB.exec(e.Color.toRGB(t)),r=e.Color.re_RGB.exec(e.Color.toRGB(r)),(!t||t.length<3||!r||r.length<3)&&e.error("invalid from or to passed to color behavior"),"rgb("+[Math.floor(o(i,n(t[1]),n(r[1])-n(t[1]),s)),Math.floor(o(i,n(t[2]),n(r[2])-n(t[2]),s)),Math.floor(o(i,n(t[3]),n(r[3])-n(t[3]),s))].join(", ")+")"},e.Anim.behaviors.color={set:function(t,n,r,i,s,o,u){t._node.setStyle(n,e.Anim.getUpdatedColorValue(r,i,s,o,u))},get:function(e,t){var n=e._node.getComputedStyle(t);return n=n==="transparent"?"rgb(255, 255, 255)":n,n}},e.each(["backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],function(t){e.Anim.behaviors[t]=e.Anim.behaviors.color})},"3.18.1",{requires:["anim-base"]});
@@ -0,0 +1,53 @@
YUI.add('anim-color', function (Y, NAME) {
/**
* Adds support for color properties in <code>to</code>
* and <code>from</code> attributes.
* @module anim
* @submodule anim-color
*/
var NUM = Number;
Y.Anim.getUpdatedColorValue = function(fromColor, toColor, elapsed, duration, fn)
{
fromColor = Y.Color.re_RGB.exec(Y.Color.toRGB(fromColor));
toColor = Y.Color.re_RGB.exec(Y.Color.toRGB(toColor));
if (!fromColor || fromColor.length < 3 || !toColor || toColor.length < 3) {
Y.error('invalid from or to passed to color behavior');
}
return 'rgb(' + [
Math.floor(fn(elapsed, NUM(fromColor[1]), NUM(toColor[1]) - NUM(fromColor[1]), duration)),
Math.floor(fn(elapsed, NUM(fromColor[2]), NUM(toColor[2]) - NUM(fromColor[2]), duration)),
Math.floor(fn(elapsed, NUM(fromColor[3]), NUM(toColor[3]) - NUM(fromColor[3]), duration))
].join(', ') + ')';
};
Y.Anim.behaviors.color = {
set: function(anim, att, from, to, elapsed, duration, fn) {
anim._node.setStyle(att, Y.Anim.getUpdatedColorValue(from, to, elapsed, duration, fn));
},
// 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) {
Y.Anim.behaviors[v] = Y.Anim.behaviors.color;
}
);
}, '3.18.1', {"requires": ["anim-base"]});
@@ -0,0 +1,59 @@
YUI.add('anim-curve', function (Y, NAME) {
/**
* 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) {
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 {Number[]} points An array containing Bezier points
* @param {Number} t A number between 0 and 1 which is the basis for determining current position
* @return {Number[]} An array containing int x and y member data
*/
Y.Anim.getBezier = function(points, t) {
var n = points.length,
tmp = [],
i,
j;
for (i = 0; i < n; ++i){
tmp[i] = [points[i][0], points[i][1]]; // save input
}
for (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.18.1', {"requires": ["anim-xy"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("anim-curve",function(e,t){e.Anim.behaviors.curve={set:function(t,n,r,i,s,o,u){r=r.slice.call(r),i=i.slice.call(i);var a=u(s,0,100,o)/100;i.unshift(r),t._node.setXY(e.Anim.getBezier(i,a))},get:function(e){return e._node.getXY()}},e.Anim.getBezier=function(e,t){var n=e.length,r=[],i,s;for(i=0;i<n;++i)r[i]=[e[i][0],e[i][1]];for(s=1;s<n;++s)for(i=0;i<n-s;++i)r[i][0]=(1-t)*r[i][0]+t*r[parseInt(i+1,10)][0],r[i][1]=(1-t)*r[i][1]+t*r[parseInt(i+1,10)][1];return[r[0][0],r[0][1]]}},"3.18.1",{requires:["anim-xy"]});
@@ -0,0 +1,59 @@
YUI.add('anim-curve', function (Y, NAME) {
/**
* 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) {
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 {Number[]} points An array containing Bezier points
* @param {Number} t A number between 0 and 1 which is the basis for determining current position
* @return {Number[]} An array containing int x and y member data
*/
Y.Anim.getBezier = function(points, t) {
var n = points.length,
tmp = [],
i,
j;
for (i = 0; i < n; ++i){
tmp[i] = [points[i][0], points[i][1]]; // save input
}
for (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.18.1', {"requires": ["anim-xy"]});
@@ -0,0 +1,365 @@
YUI.add('anim-easing', function (Y, NAME) {
/*
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
*/
var 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;
}
};
Y.Easing = Easing;
}, '3.18.1', {"requires": ["anim-base"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("anim-easing",function(e,t){var n={easeNone:function(e,t,n,r){return n*e/r+t},easeIn:function(e,t,n,r){return n*(e/=r)*e+t},easeOut:function(e,t,n,r){return-n*(e/=r)*(e-2)+t},easeBoth:function(e,t,n,r){return(e/=r/2)<1?n/2*e*e+t:-n/2*(--e*(e-2)-1)+t},easeInStrong:function(e,t,n,r){return n*(e/=r)*e*e*e+t},easeOutStrong:function(e,t,n,r){return-n*((e=e/r-1)*e*e*e-1)+t},easeBothStrong:function(e,t,n,r){return(e/=r/2)<1?n/2*e*e*e*e+t:-n/2*((e-=2)*e*e*e-2)+t},elasticIn:function(e,t,n,r,i,s){var o;return e===0?t:(e/=r)===1?t+n:(s||(s=r*.3),!i||i<Math.abs(n)?(i=n,o=s/4):o=s/(2*Math.PI)*Math.asin(n/i),-(i*Math.pow(2,10*(e-=1))*Math.sin((e*r-o)*2*Math.PI/s))+t)},elasticOut:function(e,t,n,r,i,s){var o;return e===0?t:(e/=r)===1?t+n:(s||(s=r*.3),!i||i<Math.abs(n)?(i=n,o=s/4):o=s/(2*Math.PI)*Math.asin(n/i),i*Math.pow(2,-10*e)*Math.sin((e*r-o)*2*Math.PI/s)+n+t)},elasticBoth:function(e,t,n,r,i,s){var o;return e===0?t:(e/=r/2)===2?t+n:(s||(s=r*.3*1.5),!i||i<Math.abs(n)?(i=n,o=s/4):o=s/(2*Math.PI)*Math.asin(n/i),e<1?-0.5*i*Math.pow(2,10*(e-=1))*Math.sin((e*r-o)*2*Math.PI/s)+t:i*Math.pow(2,-10*(e-=1))*Math.sin((e*r-o)*2*Math.PI/s)*.5+n+t)},backIn:function(e,t,n,r,i){return i===undefined&&(i=1.70158),e===r&&(e-=.001),n*(e/=r)*e*((i+1)*e-i)+t},backOut:function(e,t,n,r,i){return typeof i=="undefined"&&(i=1.70158),n*((e=e/r-1)*e*((i+1)*e+i)+1)+t},backBoth:function(e,t,n,r,i){return typeof i=="undefined"&&(i=1.70158),(e/=r/2)<1?n/2*e*e*(((i*=1.525)+1)*e-i)+t:n/2*((e-=2)*e*(((i*=1.525)+1)*e+i)+2)+t},bounceIn:function(t,n,r,i){return r-e.Easing.bounceOut(i-t,0,r,i)+n},bounceOut:function(e,t,n,r){return(e/=r)<1/2.75?n*7.5625*e*e+t:e<2/2.75?n*(7.5625*(e-=1.5/2.75)*e+.75)+t:e<2.5/2.75?n*(7.5625*(e-=2.25/2.75)*e+.9375)+t:n*(7.5625*(e-=2.625/2.75)*e+.984375)+t},bounceBoth:function(t,n,r,i){return t<i/2?e.Easing.bounceIn(t*2,0,r,i)*.5+n:e.Easing.bounceOut(t*2-i,0,r,i)*.5+r*.5+n}};e.Easing=n},"3.18.1",{requires:["anim-base"]});
@@ -0,0 +1,365 @@
YUI.add('anim-easing', function (Y, NAME) {
/*
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
*/
var 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;
}
};
Y.Easing = Easing;
}, '3.18.1', {"requires": ["anim-base"]});
@@ -0,0 +1,26 @@
YUI.add('anim-node-plugin', function (Y, NAME) {
/**
* Binds an Anim instance to a Node instance
* @module anim
* @class Plugin.NodeFX
* @extends Anim
* @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.18.1', {"requires": ["node-pluginhost", "anim-base"]});
@@ -0,0 +1 @@
YUI.add("anim-node-plugin",function(e,t){var n=function(t){t=t?e.merge(t):{},t.node=t.host,n.superclass.constructor.apply(this,arguments)};n.NAME="nodefx",n.NS="fx",e.extend(n,e.Anim),e.namespace("Plugin"),e.Plugin.NodeFX=n},"3.18.1",{requires:["node-pluginhost","anim-base"]});
@@ -0,0 +1,26 @@
YUI.add('anim-node-plugin', function (Y, NAME) {
/**
* Binds an Anim instance to a Node instance
* @module anim
* @class Plugin.NodeFX
* @extends Anim
* @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.18.1', {"requires": ["node-pluginhost", "anim-base"]});
@@ -0,0 +1,38 @@
YUI.add('anim-scroll', function (Y, NAME) {
/**
* 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.18.1', {"requires": ["anim-base"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("anim-scroll",function(e,t){var n=Number;e.Anim.behaviors.scroll={set:function(e,t,r,i,s,o,u){var a=e._node,f=[u(s,n(r[0]),n(i[0])-n(r[0]),o),u(s,n(r[1]),n(i[1])-n(r[1]),o)];f[0]&&a.set("scrollLeft",f[0]),f[1]&&a.set("scrollTop",f[1])},get:function(e){var t=e._node;return[t.get("scrollLeft"),t.get("scrollTop")]}}},"3.18.1",{requires:["anim-base"]});
@@ -0,0 +1,38 @@
YUI.add('anim-scroll', function (Y, NAME) {
/**
* 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.18.1', {"requires": ["anim-base"]});
@@ -0,0 +1,185 @@
YUI.add('anim-shape', function (Y, NAME) {
/**
* Adds support for the <code>transform</code> attribute of <code>Graphic</code>
* <code>Shape</code> instances.
* @module anim
* @submodule anim-shape-transform
* @deprecated Use anim-shape instead.
*/
/**
* Adds support for the <code>transform</code> and <code>fill</code> attributes of <code>Graphic</code>
* and <code>Shape</code> instances. The <code>anim-shape</code> submodule can be used for all animations
* involving <code>Graphic</code> <code>Shape</code> attributes.
*
* @module anim
* @submodule anim-shape
*/
var NUM = Number,
TO,
TOSTRING,
COLOR = "color",
STOPS = "stops",
TYPE = "type",
GETUPDATEDSTOPS = function(anim, from, to, elapsed, duration, fn)
{
var i = 0,
getUpdatedColorValue = Y.Anim.getUpdatedColorValue,
toStop,
fromStop,
prop,
len = to.length,
stops = [],
stop;
for(; i < len; i = i + 1)
{
toStop = to[i];
fromStop = from[i];
stop = {};
for(prop in toStop)
{
if(toStop.hasOwnProperty(prop))
{
if(prop === COLOR)
{
stop[prop] = Y.Color.toHex(getUpdatedColorValue(
Y.Color.toHex(fromStop[prop]),
Y.Color.toHex(toStop[prop]),
elapsed,
duration,
fn
));
}
else
{
stop[prop] = fn(elapsed, NUM(fromStop[prop]), NUM(toStop[prop]) - NUM(fromStop[prop]), duration);
}
}
}
stops.push(stop);
}
return stops;
},
FILLANDSTROKEBEHAVIOR = {
set: function(anim, att, from, to, elapsed, duration, fn) {
var i,
updated = {},
getUpdatedColorValue = Y.Anim.getUpdatedColorValue,
getUpdatedStops = GETUPDATEDSTOPS;
for(i in to)
{
if(to.hasOwnProperty(i) && i !== TYPE)
{
switch(i)
{
case COLOR :
updated[i] = getUpdatedColorValue(from[i], to[i], elapsed, duration, fn);
break;
case STOPS :
updated[i] = getUpdatedStops(anim, from[i], to[i], elapsed, duration, fn);
break;
default :
updated[i] = fn(elapsed, NUM(from[i]), NUM(to[i]) - NUM(from[i]), duration);
break;
}
}
}
anim._node.set(att, updated);
}
};
Y.Anim.behaviors.fill = FILLANDSTROKEBEHAVIOR;
Y.Anim.behaviors.stroke = FILLANDSTROKEBEHAVIOR;
Y.Anim.behaviors.transform = {
set: function(anim, att, from, to, elapsed, duration, fn) {
var node = anim._node,
transform = "",
transformTo,
transformFrom,
toArgs,
fromArgs,
i = 0,
j,
argLen,
len;
to = TO;
len = TO.length;
for(; i < len; ++i)
{
toArgs = to[i].concat();
fromArgs = from[i].concat();
transformTo = toArgs.shift();
transformFrom = fromArgs.shift();
argLen = toArgs.length;
transform += transformTo + "(";
for(j = 0; j < argLen; ++j)
{
transform += fn(elapsed, NUM(fromArgs[j]), NUM(toArgs[j]) - NUM(fromArgs[j]), duration);
if(j < argLen - 1)
{
transform += ", ";
}
}
transform += ");";
}
if(transform)
{
node.set('transform', transform);
}
node._transform = TOSTRING;
},
get: function(anim) {
var node = anim._node,
fromMatrix = node.matrix,
toString = anim.get("to").transform,
fromString = node.get("transform"),
toArray = Y.MatrixUtil.getTransformArray(toString),
fromArray = fromString ? Y.MatrixUtil.getTransformArray(fromString) : null,
toMatrix,
i,
len,
transformFunction,
from;
if(toArray)
{
if(!fromArray || fromArray.length < 1)
{
fromArray = [];
len = toArray.length;
for(i = 0; i < len; ++i)
{
transformFunction = toArray[i][0];
fromArray[i] = Y.MatrixUtil.getTransformFunctionArray(transformFunction);
}
TO = toArray;
from = fromArray;
}
else if(Y.MatrixUtil.compareTransformSequence(toArray, fromArray))
{
TO = toArray;
from = fromArray;
}
else
{
toMatrix = new Y.Matrix();
len = toArray.length;
for(i = 0; i < len; ++i)
{
transformFunction = toArray[i].shift();
transformFunction = transformFunction === "matrix" ? "multiply" : transformFunction;
toMatrix[transformFunction].apply(toMatrix, toArray[i]);
}
TO = toMatrix.decompose();
from = fromMatrix.decompose();
}
}
TOSTRING = toString;
return from;
}
};
}, '3.18.1', {"requires": ["anim-base", "anim-easing", "anim-color", "matrix"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("anim-shape",function(e,t){var n=Number,r,i,s="color",o="stops",u="type",a=function(t,r,i,o,u,a){var f=0,l=e.Anim.getUpdatedColorValue,c,h,p,d=i.length,v=[],m;for(;f<d;f+=1){c=i[f],h=r[f],m={};for(p in c)c.hasOwnProperty(p)&&(p===s?m[p]=e.Color.toHex(l(e.Color.toHex(h[p]),e.Color.toHex(c[p]),o,u,a)):m[p]=a(o,n(h[p]),n(c[p])-n(h[p]),u));v.push(m)}return v},f={set:function(t,r,i,f,l,c,h){var p,d={},v=e.Anim.getUpdatedColorValue,m=a;for(p in f)if(f.hasOwnProperty(p)&&p!==u)switch(p){case s:d[p]=v(i[p],f[p],l,c,h);break;case o:d[p]=m(t,i[p],f[p],l,c,h);break;default:d[p]=h(l,n(i[p]),n(f[p])-n(i[p]),c)}t._node.set(r,d)}};e.Anim.behaviors.fill=f,e.Anim.behaviors.stroke=f,e.Anim.behaviors.transform={set:function(e,t,s,o,u,a,f){var l=e._node,c="",h,p,d,v,m=0,g,y,b;o=r,b=r.length;for(;m<b;++m){d=o[m].concat(),v=s[m].concat(),h=d.shift(),p=v.shift(),y=d.length,c+=h+"(";for(g=0;g<y;++g)c+=f(u,n(v[g]),n(d[g])-n(v[g]),a),g<y-1&&(c+=", ");c+=");"}c&&l.set("transform",c),l._transform=i},get:function(t){var n=t._node,s=n.matrix,o=t.get("to").transform,u=n.get("transform"),a=e.MatrixUtil.getTransformArray(o),f=u?e.MatrixUtil.getTransformArray(u):null,l,c,h,p,d;if(a)if(!f||f.length<1){f=[],h=a.length;for(c=0;c<h;++c)p=a[c][0],f[c]=e.MatrixUtil.getTransformFunctionArray(p);r=a,d=f}else if(e.MatrixUtil.compareTransformSequence(a,f))r=a,d=f;else{l=new e.Matrix,h=a.length;for(c=0;c<h;++c)p=a[c].shift(),p=p==="matrix"?"multiply":p,l[p].apply(l,a[c]);r=l.decompose(),d=s.decompose()}return i=o,d}}},"3.18.1",{requires:["anim-base","anim-easing","anim-color","matrix"]});
+185
View File
@@ -0,0 +1,185 @@
YUI.add('anim-shape', function (Y, NAME) {
/**
* Adds support for the <code>transform</code> attribute of <code>Graphic</code>
* <code>Shape</code> instances.
* @module anim
* @submodule anim-shape-transform
* @deprecated Use anim-shape instead.
*/
/**
* Adds support for the <code>transform</code> and <code>fill</code> attributes of <code>Graphic</code>
* and <code>Shape</code> instances. The <code>anim-shape</code> submodule can be used for all animations
* involving <code>Graphic</code> <code>Shape</code> attributes.
*
* @module anim
* @submodule anim-shape
*/
var NUM = Number,
TO,
TOSTRING,
COLOR = "color",
STOPS = "stops",
TYPE = "type",
GETUPDATEDSTOPS = function(anim, from, to, elapsed, duration, fn)
{
var i = 0,
getUpdatedColorValue = Y.Anim.getUpdatedColorValue,
toStop,
fromStop,
prop,
len = to.length,
stops = [],
stop;
for(; i < len; i = i + 1)
{
toStop = to[i];
fromStop = from[i];
stop = {};
for(prop in toStop)
{
if(toStop.hasOwnProperty(prop))
{
if(prop === COLOR)
{
stop[prop] = Y.Color.toHex(getUpdatedColorValue(
Y.Color.toHex(fromStop[prop]),
Y.Color.toHex(toStop[prop]),
elapsed,
duration,
fn
));
}
else
{
stop[prop] = fn(elapsed, NUM(fromStop[prop]), NUM(toStop[prop]) - NUM(fromStop[prop]), duration);
}
}
}
stops.push(stop);
}
return stops;
},
FILLANDSTROKEBEHAVIOR = {
set: function(anim, att, from, to, elapsed, duration, fn) {
var i,
updated = {},
getUpdatedColorValue = Y.Anim.getUpdatedColorValue,
getUpdatedStops = GETUPDATEDSTOPS;
for(i in to)
{
if(to.hasOwnProperty(i) && i !== TYPE)
{
switch(i)
{
case COLOR :
updated[i] = getUpdatedColorValue(from[i], to[i], elapsed, duration, fn);
break;
case STOPS :
updated[i] = getUpdatedStops(anim, from[i], to[i], elapsed, duration, fn);
break;
default :
updated[i] = fn(elapsed, NUM(from[i]), NUM(to[i]) - NUM(from[i]), duration);
break;
}
}
}
anim._node.set(att, updated);
}
};
Y.Anim.behaviors.fill = FILLANDSTROKEBEHAVIOR;
Y.Anim.behaviors.stroke = FILLANDSTROKEBEHAVIOR;
Y.Anim.behaviors.transform = {
set: function(anim, att, from, to, elapsed, duration, fn) {
var node = anim._node,
transform = "",
transformTo,
transformFrom,
toArgs,
fromArgs,
i = 0,
j,
argLen,
len;
to = TO;
len = TO.length;
for(; i < len; ++i)
{
toArgs = to[i].concat();
fromArgs = from[i].concat();
transformTo = toArgs.shift();
transformFrom = fromArgs.shift();
argLen = toArgs.length;
transform += transformTo + "(";
for(j = 0; j < argLen; ++j)
{
transform += fn(elapsed, NUM(fromArgs[j]), NUM(toArgs[j]) - NUM(fromArgs[j]), duration);
if(j < argLen - 1)
{
transform += ", ";
}
}
transform += ");";
}
if(transform)
{
node.set('transform', transform);
}
node._transform = TOSTRING;
},
get: function(anim) {
var node = anim._node,
fromMatrix = node.matrix,
toString = anim.get("to").transform,
fromString = node.get("transform"),
toArray = Y.MatrixUtil.getTransformArray(toString),
fromArray = fromString ? Y.MatrixUtil.getTransformArray(fromString) : null,
toMatrix,
i,
len,
transformFunction,
from;
if(toArray)
{
if(!fromArray || fromArray.length < 1)
{
fromArray = [];
len = toArray.length;
for(i = 0; i < len; ++i)
{
transformFunction = toArray[i][0];
fromArray[i] = Y.MatrixUtil.getTransformFunctionArray(transformFunction);
}
TO = toArray;
from = fromArray;
}
else if(Y.MatrixUtil.compareTransformSequence(toArray, fromArray))
{
TO = toArray;
from = fromArray;
}
else
{
toMatrix = new Y.Matrix();
len = toArray.length;
for(i = 0; i < len; ++i)
{
transformFunction = toArray[i].shift();
transformFunction = transformFunction === "matrix" ? "multiply" : transformFunction;
toMatrix[transformFunction].apply(toMatrix, toArray[i]);
}
TO = toMatrix.decompose();
from = fromMatrix.decompose();
}
}
TOSTRING = toString;
return from;
}
};
}, '3.18.1', {"requires": ["anim-base", "anim-easing", "anim-color", "matrix"]});
@@ -0,0 +1,26 @@
YUI.add('anim-xy', function (Y, NAME) {
/**
* 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.18.1', {"requires": ["anim-base", "node-screen"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("anim-xy",function(e,t){var n=Number;e.Anim.behaviors.xy={set:function(e,t,r,i,s,o,u){e._node.setXY([u(s,n(r[0]),n(i[0])-n(r[0]),o),u(s,n(r[1]),n(i[1])-n(r[1]),o)])},get:function(e){return e._node.getXY()}}},"3.18.1",{requires:["anim-base","node-screen"]});
+26
View File
@@ -0,0 +1,26 @@
YUI.add('anim-xy', function (Y, NAME) {
/**
* 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.18.1', {"requires": ["anim-base", "node-screen"]});
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
YUI.add("app-base",function(e,t){var n=e.Lang,r=e.Object,i=e.PjaxBase,s=e.Router,o=e.View,u=e.ClassNameManager.getClassName,a=e.config.win,f;f=e.Base.create("app",e.Base,[o,s,i],{views:{},initializer:function(t){function i(t,r){n[r]=e.merge(n[r],t)}t||(t={});var n={};r.each(this.views,i),r.each(t.views,i),this.views=n,this._viewInfoMap={},this.after("activeViewChange",e.bind("_afterActiveViewChange",this)),this.get("serverRouting")||this._pjaxBindUI()},createView:function(t,i){var s=this.getViewInfo(t),u=s&&s.type||o,a,f;return a=n.isString(u)?r.getValue(e,u.split(".")):u,f=new a(i),this._viewInfoMap[e.stamp(f,!0)]=s,f},getViewInfo:function(t){return n.isString(t)?this.views[t]:t&&this._viewInfoMap[e.stamp(t,!0)]},render:function(){var t=e.App.CLASS_NAMES,n=this.get("container"),r=this.get("viewContainer"),i=this.get("activeView"),s=i&&i.get("container"),o=n.compareTo(r);return n.addClass(t.app),r.addClass(t.views),i&&!r.contains(s)&&r.appendChild(s),!n.contains(r)&&!o&&n.appendChild(r),this},showView:function(t,r,i,s){var o,u;return i||(i={}),s?i=e.merge(i,{callback:s}):n.isFunction(i)&&(i={callback:i}),n.isString(t)&&(o=this.getViewInfo(t),o&&o.preserve&&o.instance?(t=o.instance,this._viewInfoMap[e.stamp(t,!0)]=o):(t=this.createView(t,r),u=!0)),i.update&&!u&&t.setAttrs(r),"render"in i?i.render&&t.render():u&&t.render(),this._set("activeView",t,{options:i})},_attachView:function(e,t){if(!e)return;var n=this.getViewInfo(e),r=this.get("viewContainer");e.addTarget(this),n&&(n.instance=e),r[t?"prepend":"append"](e.get("container"))},_destroyContainer:function(){var t=e.App.CLASS_NAMES,n=this.get("container"),r=this.get("viewContainer"),i=n.compareTo(r);if(e.one("body").compareTo(n)){this.detachEvents(),n.removeClass(t.app),i?n.removeClass(t.views):r.remove(!0);return}r.remove(!0),i||n.remove(!0)},_detachView:function(t){if(!t)return;var n=this.getViewInfo(t)||{};n.preserve?t.remove():(t.destroy({remove:!0}),delete this._viewInfoMap[e.stamp(t,!0)],t===n.instance&&delete n.instance),t.removeTarget(this)},_getRequest:function(){var e=s.prototype._getRequest.apply(this,arguments);return e.app=this,e},_getViewContainer:function(e){return!e&&!this._viewContainer&&(e=this._viewContainer=this.create(),this._set("viewContainer",e)),e},_initHtml5:function(){return this.get("serverRouting")===!1?!1:s.html5},_isChildView:function(e,t){var n=this.getViewInfo(e),r=this.getViewInfo(t);return n&&r?this.getViewInfo(n.parent)===r:!1},_isParentView:function(e,t){var n=this.getViewInfo(e),r=this.getViewInfo(t);return n&&r?this.getViewInfo(r.parent)===n:!1},_navigate:function(t,n){return this.get("serverRouting")||(n=e.merge({force:!0},n)),i.prototype._navigate.call(this,t,n)},_save:function(t,n){var r;return this.get("serverRouting")&&!this.get("html5")?this._hasSameOrigin(t)?(a&&(r=this._joinURL(t||""),n?a.location.replace(r):a.location=r),this):(e.error("Security error: The new URL must be of the same origin as the current URL."),this):s.prototype._save.apply(this,arguments)},_uiSetActiveView:function(e,t,n){n||(n={});var r=n.callback,i=this._isChildView(e,t),s=!i&&this._isParentView(e,t),o=!!n.prepend||s;if(e===t)return r&&r.call(this,e);this._attachView(e,o),this._detachView(t),r&&r.call(this,e)},_afterActiveViewChange:function(e){this._uiSetActiveView(e.newVal,e.prevVal,e.options)}},{ATTRS:{activeView:{value:null,readOnly:!0},container:{valueFn:function(){return e.one("body")}},html5:{valueFn:"_initHtml5"},linkSelector:{value:"a"},serverRouting:{valueFn:function(){return e.App.serverRouting},writeOnce:"initOnly"},viewContainer:{getter:"_getViewContainer",setter:e.one,writeOnce:!0}},_NON_ATTRS_CFG:["views"]}),e.namespace("App").Base=f,e.App=e.mix(e.Base.create("app",f,[]),e.App,!0),e.App.CLASS_NAMES={app:u("app"),views:u("app","views")}},"3.18.1",{requires:["classnamemanager","pjax-base","router","view"]});
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,235 @@
YUI.add('app-content', function (Y, NAME) {
/**
`Y.App` extension that provides pjax-style content fetching and handling.
@module app
@submodule app-content
@since 3.7.0
**/
var PjaxContent = Y.PjaxContent;
/**
`Y.App` extension that provides pjax-style content fetching and handling.
This makes it easy to fetch server rendered content for URLs using Ajax. The
HTML content returned from the server will be view-ified and set as the app's
main content, making it seamless to use a mixture of server and client rendered
views.
When the `"app-content"` module is used, it will automatically mix itself into
`Y.App`, and it provides three main features:
- **`Y.App.Content.route`**: A stack of middleware which forms a pjax-style
content route.
- **`loadContent()`**: Route middleware which load content from a server. This
makes an Ajax request for the requested URL, parses the returned content and
puts it on the route's response object.
- **`showContent()`**: Method which provides an easy way to view-ify HTML
content which should be shown as an app's active/visible view.
The following is an example of how these features can be used:
// Creates a new app and registers the `"post"` view.
var app = new Y.App({
views: {
post: {type: Y.PostView}
}
});
// Uses a simple server rendered content route for the About page.
app.route('/about/', Y.App.Content.route);
// Uses the `loadContent()` middleware to fetch the contents of the post
// from the server and shows that content in a `"post"` view.
app.route('/posts/:id/', 'loadContent', function (req, res, next) {
this.showContent(res.content.node, {view: 'post'});
});
@class App.Content
@uses PjaxContent
@extensionfor App
@since 3.7.0
**/
function AppContent() {
PjaxContent.apply(this, arguments);
}
/**
A stack of middleware which forms a pjax-style content route.
This route will load the rendered HTML content from the server, then create and
show a new view using those contents.
@property route
@type Array
@static
@since 3.7.0
**/
AppContent.route = ['loadContent', '_contentRoute'];
AppContent.prototype = {
// -- Public Methods -------------------------------------------------------
/**
Sets this app's `activeView` attribute using the specified `content`.
This provides an easy way to view-ify HTML content which should be shown as
this app's active/visible view. This method will determine the appropriate
view `container` node based on the specified `content`. By default, a new
`Y.View` instance will be created unless `options.view` is specified.
Under the hood, this method calls the `showView()` method, so refer to its
docs for more information.
@method showContent
@param {HTMLElement|Node|String} content The content to show, it may be
provided as a selector string, a DOM element, or a `Y.Node` instance.
@param {Object} [options] Optional objects containing any of the following
properties in addition to any `showView()` options:
@param {Object|String} [options.view] The name of a view defined in this
app's `views`, or an object with the following properties:
@param {String} options.view.name The name of a view defined in this
app's `views`.
@param {Object} [options.view.config] Optional configuration to use when
creating the new view instance. This config object can also be used
to update an existing or preserved view's attributes when
`options.update` is `true`. **Note:** If a `container` is specified,
it will be overridden by the `content` specified in the first
argument.
@param {Function} [callback] Optional callback function to call after the
new `activeView` is ready to use. **Note:** this will override
`options.callback` and it can be specified as either the second or third
argument. The function will be passed the following:
@param {View} callback.view A reference to the new `activeView`.
@chainable
@since 3.7.0
@see App.showView()
**/
showContent: function (content, options, callback) {
// Makes sure we have a node instance, and will query selector strings.
content = Y.one(content);
// Support the callback function being either the second or third arg.
if (typeof options === 'function') {
options = {callback: options};
callback = null;
}
// Mix in default option to *not* render the view because presumably we
// have pre-rendered content here. This also creates a copy so we can
// modify the object.
options = Y.merge({render: false}, options);
var view = options.view || '',
viewName = typeof view === 'string' ? view : view.name,
viewConfig = typeof view !== 'string' ? view.config : {},
viewInfo = this.getViewInfo(viewName),
container, template, type, ViewConstructor;
// Remove `view` from the `options` which will be passed along to the
// `showView()` method.
delete options.view;
// When the specified `content` is a document fragment, we want to see
// if it only contains a single node, and use that as the content. This
// checks `childNodes` which will include text nodes.
if (content && content.isFragment() &&
content.get('childNodes').size() === 1) {
content = content.get('firstChild');
}
// When the `content` is an element node (`nodeType` 1), we can use it
// as-is for the `container`. Otherwise, we'll construct a new container
// based on the `options.view`'s `containerTemplate`.
if (content && content.get('nodeType') === 1) {
container = content;
} else {
type = (viewInfo && viewInfo.type) || Y.View;
// Looks for a namespaced constructor function on `Y`.
ViewConstructor = typeof type === 'string' ?
Y.Object.getValue(Y, type.split('.')) : type;
// Find the correct node template for the view.
template = ViewConstructor.prototype.containerTemplate;
container = Y.Node.create(template);
// Append the document fragment to the newly created `container`
// node. This is the worst case where we have to create a wrapper
// node around the `content`.
container.append(content);
}
// Makes sure the view is created using _our_ `container` node.
viewConfig = Y.merge(viewConfig, {container: container});
// Finally switch to the new `activeView`. We want to make sure `view`
// is a string if it's falsy, that way a new view will be created.
return this.showView(viewName, viewConfig, options, callback);
},
// -- Protected Methods ----------------------------------------------------
/**
Provides a default content route which will show a server rendered view.
**Note:** This route callback assumes that it's called after the
`loadContent()` middleware.
@method _contentRoute
@param {Object} req Request object.
@param {Object} res Response Object.
@param {Function} next Function to pass control to the next route callback.
@protected
@since 3.7.0
@see Y.App.Content.route
**/
_contentRoute: function (req, res, next) {
var content = res.content,
doc = Y.config.doc,
activeViewHandle;
// We must have some content to work with.
if (!(content && content.node)) { return next(); }
if (content.title && doc) {
// Make sure the `activeView` does actually change before we go
// messing with the page title.
activeViewHandle = this.onceAfter('activeViewChange', function () {
doc.title = content.title;
});
}
this.showContent(content.node);
// Detach the handle just in case.
if (activeViewHandle) {
activeViewHandle.detach();
}
next();
}
};
// Mix statics.
AppContent.ATTRS = Y.Attribute.protectAttrs(PjaxContent.ATTRS);
// Mix prototype.
Y.mix(AppContent, PjaxContent, false, null, 1);
// -- Namespace ----------------------------------------------------------------
Y.App.Content = AppContent;
Y.Base.mix(Y.App, [AppContent]);
}, '3.18.1', {"requires": ["app-base", "pjax-content"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("app-content",function(e,t){function r(){n.apply(this,arguments)}var n=e.PjaxContent;r.route=["loadContent","_contentRoute"],r.prototype={showContent:function(t,n,r){t=e.one(t),typeof n=="function"&&(n={callback:n},r=null),n=e.merge({render:!1},n);var i=n.view||"",s=typeof i=="string"?i:i.name,o=typeof i!="string"?i.config:{},u=this.getViewInfo(s),a,f,l,c;return delete n.view,t&&t.isFragment()&&t.get("childNodes").size()===1&&(t=t.get("firstChild")),t&&t.get("nodeType")===1?a=t:(l=u&&u.type||e.View,c=typeof l=="string"?e.Object.getValue(e,l.split(".")):l,f=c.prototype.containerTemplate,a=e.Node.create(f),a.append(t)),o=e.merge(o,{container:a}),this.showView(s,o,n,r)},_contentRoute:function(t,n,r){var i=n.content,s=e.config.doc,o;if(!i||!i.node)return r();i.title&&s&&(o=this.onceAfter("activeViewChange",function(){s.title=i.title})),this.showContent(i.node),o&&o.detach(),r()}},r.ATTRS=e.Attribute.protectAttrs(n.ATTRS),e.mix(r,n,!1,null,1),e.App.Content=r,e.Base.mix(e.App,[r])},"3.18.1",{requires:["app-base","pjax-content"]});
@@ -0,0 +1,235 @@
YUI.add('app-content', function (Y, NAME) {
/**
`Y.App` extension that provides pjax-style content fetching and handling.
@module app
@submodule app-content
@since 3.7.0
**/
var PjaxContent = Y.PjaxContent;
/**
`Y.App` extension that provides pjax-style content fetching and handling.
This makes it easy to fetch server rendered content for URLs using Ajax. The
HTML content returned from the server will be view-ified and set as the app's
main content, making it seamless to use a mixture of server and client rendered
views.
When the `"app-content"` module is used, it will automatically mix itself into
`Y.App`, and it provides three main features:
- **`Y.App.Content.route`**: A stack of middleware which forms a pjax-style
content route.
- **`loadContent()`**: Route middleware which load content from a server. This
makes an Ajax request for the requested URL, parses the returned content and
puts it on the route's response object.
- **`showContent()`**: Method which provides an easy way to view-ify HTML
content which should be shown as an app's active/visible view.
The following is an example of how these features can be used:
// Creates a new app and registers the `"post"` view.
var app = new Y.App({
views: {
post: {type: Y.PostView}
}
});
// Uses a simple server rendered content route for the About page.
app.route('/about/', Y.App.Content.route);
// Uses the `loadContent()` middleware to fetch the contents of the post
// from the server and shows that content in a `"post"` view.
app.route('/posts/:id/', 'loadContent', function (req, res, next) {
this.showContent(res.content.node, {view: 'post'});
});
@class App.Content
@uses PjaxContent
@extensionfor App
@since 3.7.0
**/
function AppContent() {
PjaxContent.apply(this, arguments);
}
/**
A stack of middleware which forms a pjax-style content route.
This route will load the rendered HTML content from the server, then create and
show a new view using those contents.
@property route
@type Array
@static
@since 3.7.0
**/
AppContent.route = ['loadContent', '_contentRoute'];
AppContent.prototype = {
// -- Public Methods -------------------------------------------------------
/**
Sets this app's `activeView` attribute using the specified `content`.
This provides an easy way to view-ify HTML content which should be shown as
this app's active/visible view. This method will determine the appropriate
view `container` node based on the specified `content`. By default, a new
`Y.View` instance will be created unless `options.view` is specified.
Under the hood, this method calls the `showView()` method, so refer to its
docs for more information.
@method showContent
@param {HTMLElement|Node|String} content The content to show, it may be
provided as a selector string, a DOM element, or a `Y.Node` instance.
@param {Object} [options] Optional objects containing any of the following
properties in addition to any `showView()` options:
@param {Object|String} [options.view] The name of a view defined in this
app's `views`, or an object with the following properties:
@param {String} options.view.name The name of a view defined in this
app's `views`.
@param {Object} [options.view.config] Optional configuration to use when
creating the new view instance. This config object can also be used
to update an existing or preserved view's attributes when
`options.update` is `true`. **Note:** If a `container` is specified,
it will be overridden by the `content` specified in the first
argument.
@param {Function} [callback] Optional callback function to call after the
new `activeView` is ready to use. **Note:** this will override
`options.callback` and it can be specified as either the second or third
argument. The function will be passed the following:
@param {View} callback.view A reference to the new `activeView`.
@chainable
@since 3.7.0
@see App.showView()
**/
showContent: function (content, options, callback) {
// Makes sure we have a node instance, and will query selector strings.
content = Y.one(content);
// Support the callback function being either the second or third arg.
if (typeof options === 'function') {
options = {callback: options};
callback = null;
}
// Mix in default option to *not* render the view because presumably we
// have pre-rendered content here. This also creates a copy so we can
// modify the object.
options = Y.merge({render: false}, options);
var view = options.view || '',
viewName = typeof view === 'string' ? view : view.name,
viewConfig = typeof view !== 'string' ? view.config : {},
viewInfo = this.getViewInfo(viewName),
container, template, type, ViewConstructor;
// Remove `view` from the `options` which will be passed along to the
// `showView()` method.
delete options.view;
// When the specified `content` is a document fragment, we want to see
// if it only contains a single node, and use that as the content. This
// checks `childNodes` which will include text nodes.
if (content && content.isFragment() &&
content.get('childNodes').size() === 1) {
content = content.get('firstChild');
}
// When the `content` is an element node (`nodeType` 1), we can use it
// as-is for the `container`. Otherwise, we'll construct a new container
// based on the `options.view`'s `containerTemplate`.
if (content && content.get('nodeType') === 1) {
container = content;
} else {
type = (viewInfo && viewInfo.type) || Y.View;
// Looks for a namespaced constructor function on `Y`.
ViewConstructor = typeof type === 'string' ?
Y.Object.getValue(Y, type.split('.')) : type;
// Find the correct node template for the view.
template = ViewConstructor.prototype.containerTemplate;
container = Y.Node.create(template);
// Append the document fragment to the newly created `container`
// node. This is the worst case where we have to create a wrapper
// node around the `content`.
container.append(content);
}
// Makes sure the view is created using _our_ `container` node.
viewConfig = Y.merge(viewConfig, {container: container});
// Finally switch to the new `activeView`. We want to make sure `view`
// is a string if it's falsy, that way a new view will be created.
return this.showView(viewName, viewConfig, options, callback);
},
// -- Protected Methods ----------------------------------------------------
/**
Provides a default content route which will show a server rendered view.
**Note:** This route callback assumes that it's called after the
`loadContent()` middleware.
@method _contentRoute
@param {Object} req Request object.
@param {Object} res Response Object.
@param {Function} next Function to pass control to the next route callback.
@protected
@since 3.7.0
@see Y.App.Content.route
**/
_contentRoute: function (req, res, next) {
var content = res.content,
doc = Y.config.doc,
activeViewHandle;
// We must have some content to work with.
if (!(content && content.node)) { return next(); }
if (content.title && doc) {
// Make sure the `activeView` does actually change before we go
// messing with the page title.
activeViewHandle = this.onceAfter('activeViewChange', function () {
doc.title = content.title;
});
}
this.showContent(content.node);
// Detach the handle just in case.
if (activeViewHandle) {
activeViewHandle.detach();
}
next();
}
};
// Mix statics.
AppContent.ATTRS = Y.Attribute.protectAttrs(PjaxContent.ATTRS);
// Mix prototype.
Y.mix(AppContent, PjaxContent, false, null, 1);
// -- Namespace ----------------------------------------------------------------
Y.App.Content = AppContent;
Y.Base.mix(Y.App, [AppContent]);
}, '3.18.1', {"requires": ["app-base", "pjax-content"]});
@@ -0,0 +1 @@
.yui3-app-transitioning .yui3-app-views,.yui3-app-views.yui3-app-transitioning{overflow-x:hidden;position:relative;white-space:nowrap;letter-spacing:-0.31em;text-rendering:optimizespeed}.opera-only :-o-prefocus,.yui3-app-transitioning .yui3-app-views,.yui3-app-views.yui3-app-transitioning{word-spacing:-0.43em}.yui3-app-transitioning .yui3-app-views>*,.yui3-app-views.yui3-app-transitioning>*{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto;width:100%;white-space:normal;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#yui3-css-stamp.app-transitions-css{display:none}
@@ -0,0 +1,33 @@
.yui3-app-transitioning .yui3-app-views,
.yui3-app-views.yui3-app-transitioning {
overflow-x: hidden;
position: relative;
white-space: nowrap;
letter-spacing: -0.31em; /* webkit: collapse white-space between units */
text-rendering: optimizespeed; /* Webkit: fixes text-rendering: optimizeLegibility */
}
/* Opera as of 12 on Windows needs word-spacing.
The ".opera-only" selector is used to prevent actual prefocus styling
and is not required in markup.
*/
.opera-only :-o-prefocus,
.yui3-app-transitioning .yui3-app-views,
.yui3-app-views.yui3-app-transitioning {
word-spacing: -0.43em;
}
.yui3-app-transitioning .yui3-app-views > *,
.yui3-app-views.yui3-app-transitioning > * {
display: inline-block;
letter-spacing: normal;
word-spacing: normal;
vertical-align: top;
text-rendering: auto;
width: 100%;
white-space: normal;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
/* YUI CSS Detection Stamp */
#yui3-css-stamp.app-transitions-css { display: none; }
@@ -0,0 +1,353 @@
YUI.add('app-transitions-native', function (Y, NAME) {
/**
Provides the implementation of view transitions for `Y.App.Transitions` in
browsers which support native CSS3 transitions.
@module app
@submodule app-transitions-native
@since 3.5.0
**/
var AppTransitions = Y.App.Transitions;
/**
Provides the implementation of view transitions for `Y.App.Transitions` in
browsers which support native CSS3 transitions.
When this module is used, `Y.App.TransitionsNative` will automatically mix
itself in to `Y.App`.
@class App.TransitionsNative
@extensionfor App
@since 3.5.0
**/
function AppTransitionsNative() {}
AppTransitionsNative.prototype = {
// -- Protected Properties -------------------------------------------------
/**
Whether this app is currently transitioning its `activeView`.
@property _transitioning
@type Boolean
@default false
@protected
@since 3.5.0
**/
/**
A queue that holds pending calls to this app's `_uiTransitionActiveView()`
method.
@property _viewTransitionQueue
@type Array
@default []
@protected
@since 3.5.0
**/
// -- Lifecycle Methods ----------------------------------------------------
initializer: function () {
this._transitioning = false;
this._viewTransitionQueue = [];
// TODO: Consider the AOP approach that `Plugin.WidgetAnim` uses.
Y.Do.before(this._queueActiveView, this, '_uiSetActiveView');
},
// -- Protected Methods ----------------------------------------------------
/**
Dequeues any pending calls to `_uiTransitionActiveView()`.
**Note:** When there is more than one queued transition, only the most
recent `activeView` change will be visually transitioned, while the others
will have their `transition` option overridden to `false`.
@method _dequeueActiveView
@protected
@since 3.5.0
**/
_dequeueActiveView: function () {
var queue = this._viewTransitionQueue,
transition = queue.shift(),
options;
if (transition) {
// When items are still left in the queue, override the transition
// so it does not run.
if (queue.length) {
// Overrides `transition` option and splices in the new options.
options = Y.merge(transition[2], {transition: false});
transition.splice(2, 1, options);
}
this._uiTransitionActiveView.apply(this, transition);
}
},
/**
Returns an object containing a named fx for both `viewIn` and `viewOut`
based on the relationship between the specified `newView` and `oldView`.
@method _getFx
@param {View} newView The view being transitioned-in.
@param {View} oldView The view being transitioned-out.
@param {String} [transition] The preferred transition to use.
@return {Object} An object containing a named fx for both `viewIn` and
`viewOut`.
@protected
@since 3.5.0
**/
_getFx: function (newView, oldView, transition) {
var fx = AppTransitions.FX,
transitions = this.get('transitions');
if (transition === false || !transitions) {
return null;
}
if (transition) {
return fx[transition];
}
if (this._isChildView(newView, oldView)) {
return fx[transitions.toChild];
}
if (this._isParentView(newView, oldView)) {
return fx[transitions.toParent];
}
return fx[transitions.navigate];
},
/**
Queues calls to `_uiTransitionActiveView()` to make sure a currently running
transition isn't interrupted.
**Note:** This method prevents the default `_uiSetActiveView()` method from
running.
@method _queueActiveView
@protected
@since 3.5.0
**/
_queueActiveView: function () {
var args = Y.Array(arguments, 0, true);
this._viewTransitionQueue.push(args);
if (!this._transitioning) {
this._dequeueActiveView();
}
return new Y.Do.Prevent();
},
/**
Performs the actual change of this app's `activeView` by visually
transitioning between the `newView` and `oldView` using any specified
`options`.
The `newView` is attached to the app by rendering it to the `viewContainer`,
and making this app a bubble target of its events.
The `oldView` is detached from the app by removing it from the
`viewContainer`, and removing this app as a bubble target for its events.
The `oldView` will either be preserved or properly destroyed.
**Note:** This method overrides `_uiSetActiveView()` and provides all of its
functionality plus supports visual transitions. Also, the `activeView`
attribute is read-only and can be changed by calling the `showView()`
method.
@method _uiTransitionActiveView
@param {View} newView The View which is now this app's `activeView`.
@param {View} [oldView] The View which was this app's `activeView`.
@param {Object} [options] Optional object containing any of the following
properties:
@param {Function} [options.callback] Optional callback function to call
after new `activeView` is ready to use, the function will be passed:
@param {View} options.callback.view A reference to the new
`activeView`.
@param {Boolean} [options.prepend=false] Whether the `view` should be
prepended instead of appended to the `viewContainer`.
@param {Boolean} [options.render] Whether the `view` should be rendered.
**Note:** If no value is specified, a view instance will only be
rendered if it's newly created by this method.
@param {Boolean|String} [options.transition] Optional transition override.
A transition can be specified which will override the default, or
`false` for no transition.
@param {Boolean} [options.update=false] Whether an existing view should
have its attributes updated by passing the `config` object to its
`setAttrs()` method. **Note:** This option does not have an effect if
the `view` instance is created as a result of calling this method.
@protected
@since 3.5.0
**/
_uiTransitionActiveView: function (newView, oldView, options) {
options || (options = {});
var callback = options.callback,
container, transitioning, isChild, isParent, prepend,
fx, fxConfig, transitions;
// Quits early when to new and old views are the same.
if (newView === oldView) {
callback && callback.call(this, newView);
this._transitioning = false;
return this._dequeueActiveView();
}
fx = this._getFx(newView, oldView, options.transition);
isChild = this._isChildView(newView, oldView);
isParent = !isChild && this._isParentView(newView, oldView);
prepend = !!options.prepend || isParent;
// Preforms simply attach/detach of the new and old view respectively
// when there's no transition to perform.
if (!fx) {
this._attachView(newView, prepend);
this._detachView(oldView);
callback && callback.call(this, newView);
this._transitioning = false;
return this._dequeueActiveView();
}
this._transitioning = true;
container = this.get('container');
transitioning = Y.App.CLASS_NAMES.transitioning;
container.addClass(transitioning);
this._attachView(newView, prepend);
// Called when view transitions completed, if none were added this will
// run right away.
function complete() {
this._detachView(oldView);
container.removeClass(transitioning);
callback && callback.call(this, newView);
this._transitioning = false;
return this._dequeueActiveView();
}
// Setup a new stack to run the view transitions in parallel.
transitions = new Y.Parallel({context: this});
fxConfig = {
crossView: !!oldView && !!newView,
prepended: prepend
};
// Transition the new view first to prevent a gap when sliding.
if (newView && fx.viewIn) {
newView.get('container')
.transition(fx.viewIn, fxConfig, transitions.add());
}
if (oldView && fx.viewOut) {
oldView.get('container')
.transition(fx.viewOut, fxConfig, transitions.add());
}
transitions.done(complete);
}
};
// -- Transition fx ------------------------------------------------------------
Y.mix(Y.Transition.fx, {
'app:fadeIn': {
opacity : 1,
duration: 0.3,
on: {
start: function (data) {
var styles = {opacity: 0},
config = data.config;
if (config.crossView && !config.prepended) {
styles.transform = 'translateX(-100%)';
}
this.setStyles(styles);
},
end: function () {
this.setStyle('transform', 'translateX(0)');
}
}
},
'app:fadeOut': {
opacity : 0,
duration: 0.3,
on: {
start: function (data) {
var styles = {opacity: 1},
config = data.config;
if (config.crossView && config.prepended) {
styles.transform = 'translateX(-100%)';
}
this.setStyles(styles);
},
end: function () {
this.setStyle('transform', 'translateX(0)');
}
}
},
'app:slideLeft': {
duration : 0.3,
transform: 'translateX(-100%)',
on: {
start: function () {
this.setStyles({
opacity : 1,
transform: 'translateX(0%)'
});
},
end: function () {
this.setStyle('transform', 'translateX(0)');
}
}
},
'app:slideRight': {
duration : 0.3,
transform: 'translateX(0)',
on: {
start: function () {
this.setStyles({
opacity : 1,
transform: 'translateX(-100%)'
});
},
end: function () {
this.setStyle('transform', 'translateX(0)');
}
}
}
});
// -- Namespacae ---------------------------------------------------------------
Y.App.TransitionsNative = AppTransitionsNative;
Y.Base.mix(Y.App, [AppTransitionsNative]);
}, '3.18.1', {"requires": ["app-transitions", "app-transitions-css", "parallel", "transition"]});
@@ -0,0 +1 @@
YUI.add("app-transitions-native",function(e,t){function r(){}var n=e.App.Transitions;r.prototype={initializer:function(){this._transitioning=!1,this._viewTransitionQueue=[],e.Do.before(this._queueActiveView,this,"_uiSetActiveView")},_dequeueActiveView:function(){var t=this._viewTransitionQueue,n=t.shift(),r;n&&(t.length&&(r=e.merge(n[2],{transition:!1}),n.splice(2,1,r)),this._uiTransitionActiveView.apply(this,n))},_getFx:function(e,t,r){var i=n.FX,s=this.get("transitions");return r===!1||!s?null:r?i[r]:this._isChildView(e,t)?i[s.toChild]:this._isParentView(e,t)?i[s.toParent]:i[s.navigate]},_queueActiveView:function(){var t=e.Array(arguments,0,!0);return this._viewTransitionQueue.push(t),this._transitioning||this._dequeueActiveView(),new e.Do.Prevent},_uiTransitionActiveView:function(t,n,r){function p(){return this._detachView(n),s.removeClass(o),i&&i.call(this,t),this._transitioning=!1,this._dequeueActiveView()}r||(r={});var i=r.callback,s,o,u,a,f,l,c,h;if(t===n)return i&&i.call(this,t),this._transitioning=!1,this._dequeueActiveView();l=this._getFx(t,n,r.transition),u=this._isChildView(t,n),a=!u&&this._isParentView(t,n),f=!!r.prepend||a;if(!l)return this._attachView(t,f),this._detachView(n),i&&i.call(this,t),this._transitioning=!1,this._dequeueActiveView();this._transitioning=!0,s=this.get("container"),o=e.App.CLASS_NAMES.transitioning,s.addClass(o),this._attachView(t,f),h=new e.Parallel({context:this}),c={crossView:!!n&&!!t,prepended:f},t&&l.viewIn&&t.get("container").transition(l.viewIn,c,h.add()),n&&l.viewOut&&n.get("container").transition(l.viewOut,c,h.add()),h.done(p)}},e.mix(e.Transition.fx,{"app:fadeIn":{opacity:1,duration:.3,on:{start:function(e){var t={opacity:0},n=e.config;n.crossView&&!n.prepended&&(t.transform="translateX(-100%)"),this.setStyles(t)},end:function(){this.setStyle("transform","translateX(0)")}}},"app:fadeOut":{opacity:0,duration:.3,on:{start:function(e){var t={opacity:1},n=e.config;n.crossView&&n.prepended&&(t.transform="translateX(-100%)"),this.setStyles(t)},end:function(){this.setStyle("transform","translateX(0)")}}},"app:slideLeft":{duration:.3,transform:"translateX(-100%)",on:{start:function(){this.setStyles({opacity:1,transform:"translateX(0%)"})},end:function(){this.setStyle("transform","translateX(0)")}}},"app:slideRight":{duration:.3,transform:"translateX(0)",on:{start:function(){this.setStyles({opacity:1,transform:"translateX(-100%)"})},end:function(){this.setStyle("transform","translateX(0)")}}}}),e.App.TransitionsNative=r,e.Base.mix(e.App,[r])},"3.18.1",{requires:["app-transitions","app-transitions-css","parallel","transition"]});
@@ -0,0 +1,353 @@
YUI.add('app-transitions-native', function (Y, NAME) {
/**
Provides the implementation of view transitions for `Y.App.Transitions` in
browsers which support native CSS3 transitions.
@module app
@submodule app-transitions-native
@since 3.5.0
**/
var AppTransitions = Y.App.Transitions;
/**
Provides the implementation of view transitions for `Y.App.Transitions` in
browsers which support native CSS3 transitions.
When this module is used, `Y.App.TransitionsNative` will automatically mix
itself in to `Y.App`.
@class App.TransitionsNative
@extensionfor App
@since 3.5.0
**/
function AppTransitionsNative() {}
AppTransitionsNative.prototype = {
// -- Protected Properties -------------------------------------------------
/**
Whether this app is currently transitioning its `activeView`.
@property _transitioning
@type Boolean
@default false
@protected
@since 3.5.0
**/
/**
A queue that holds pending calls to this app's `_uiTransitionActiveView()`
method.
@property _viewTransitionQueue
@type Array
@default []
@protected
@since 3.5.0
**/
// -- Lifecycle Methods ----------------------------------------------------
initializer: function () {
this._transitioning = false;
this._viewTransitionQueue = [];
// TODO: Consider the AOP approach that `Plugin.WidgetAnim` uses.
Y.Do.before(this._queueActiveView, this, '_uiSetActiveView');
},
// -- Protected Methods ----------------------------------------------------
/**
Dequeues any pending calls to `_uiTransitionActiveView()`.
**Note:** When there is more than one queued transition, only the most
recent `activeView` change will be visually transitioned, while the others
will have their `transition` option overridden to `false`.
@method _dequeueActiveView
@protected
@since 3.5.0
**/
_dequeueActiveView: function () {
var queue = this._viewTransitionQueue,
transition = queue.shift(),
options;
if (transition) {
// When items are still left in the queue, override the transition
// so it does not run.
if (queue.length) {
// Overrides `transition` option and splices in the new options.
options = Y.merge(transition[2], {transition: false});
transition.splice(2, 1, options);
}
this._uiTransitionActiveView.apply(this, transition);
}
},
/**
Returns an object containing a named fx for both `viewIn` and `viewOut`
based on the relationship between the specified `newView` and `oldView`.
@method _getFx
@param {View} newView The view being transitioned-in.
@param {View} oldView The view being transitioned-out.
@param {String} [transition] The preferred transition to use.
@return {Object} An object containing a named fx for both `viewIn` and
`viewOut`.
@protected
@since 3.5.0
**/
_getFx: function (newView, oldView, transition) {
var fx = AppTransitions.FX,
transitions = this.get('transitions');
if (transition === false || !transitions) {
return null;
}
if (transition) {
return fx[transition];
}
if (this._isChildView(newView, oldView)) {
return fx[transitions.toChild];
}
if (this._isParentView(newView, oldView)) {
return fx[transitions.toParent];
}
return fx[transitions.navigate];
},
/**
Queues calls to `_uiTransitionActiveView()` to make sure a currently running
transition isn't interrupted.
**Note:** This method prevents the default `_uiSetActiveView()` method from
running.
@method _queueActiveView
@protected
@since 3.5.0
**/
_queueActiveView: function () {
var args = Y.Array(arguments, 0, true);
this._viewTransitionQueue.push(args);
if (!this._transitioning) {
this._dequeueActiveView();
}
return new Y.Do.Prevent();
},
/**
Performs the actual change of this app's `activeView` by visually
transitioning between the `newView` and `oldView` using any specified
`options`.
The `newView` is attached to the app by rendering it to the `viewContainer`,
and making this app a bubble target of its events.
The `oldView` is detached from the app by removing it from the
`viewContainer`, and removing this app as a bubble target for its events.
The `oldView` will either be preserved or properly destroyed.
**Note:** This method overrides `_uiSetActiveView()` and provides all of its
functionality plus supports visual transitions. Also, the `activeView`
attribute is read-only and can be changed by calling the `showView()`
method.
@method _uiTransitionActiveView
@param {View} newView The View which is now this app's `activeView`.
@param {View} [oldView] The View which was this app's `activeView`.
@param {Object} [options] Optional object containing any of the following
properties:
@param {Function} [options.callback] Optional callback function to call
after new `activeView` is ready to use, the function will be passed:
@param {View} options.callback.view A reference to the new
`activeView`.
@param {Boolean} [options.prepend=false] Whether the `view` should be
prepended instead of appended to the `viewContainer`.
@param {Boolean} [options.render] Whether the `view` should be rendered.
**Note:** If no value is specified, a view instance will only be
rendered if it's newly created by this method.
@param {Boolean|String} [options.transition] Optional transition override.
A transition can be specified which will override the default, or
`false` for no transition.
@param {Boolean} [options.update=false] Whether an existing view should
have its attributes updated by passing the `config` object to its
`setAttrs()` method. **Note:** This option does not have an effect if
the `view` instance is created as a result of calling this method.
@protected
@since 3.5.0
**/
_uiTransitionActiveView: function (newView, oldView, options) {
options || (options = {});
var callback = options.callback,
container, transitioning, isChild, isParent, prepend,
fx, fxConfig, transitions;
// Quits early when to new and old views are the same.
if (newView === oldView) {
callback && callback.call(this, newView);
this._transitioning = false;
return this._dequeueActiveView();
}
fx = this._getFx(newView, oldView, options.transition);
isChild = this._isChildView(newView, oldView);
isParent = !isChild && this._isParentView(newView, oldView);
prepend = !!options.prepend || isParent;
// Preforms simply attach/detach of the new and old view respectively
// when there's no transition to perform.
if (!fx) {
this._attachView(newView, prepend);
this._detachView(oldView);
callback && callback.call(this, newView);
this._transitioning = false;
return this._dequeueActiveView();
}
this._transitioning = true;
container = this.get('container');
transitioning = Y.App.CLASS_NAMES.transitioning;
container.addClass(transitioning);
this._attachView(newView, prepend);
// Called when view transitions completed, if none were added this will
// run right away.
function complete() {
this._detachView(oldView);
container.removeClass(transitioning);
callback && callback.call(this, newView);
this._transitioning = false;
return this._dequeueActiveView();
}
// Setup a new stack to run the view transitions in parallel.
transitions = new Y.Parallel({context: this});
fxConfig = {
crossView: !!oldView && !!newView,
prepended: prepend
};
// Transition the new view first to prevent a gap when sliding.
if (newView && fx.viewIn) {
newView.get('container')
.transition(fx.viewIn, fxConfig, transitions.add());
}
if (oldView && fx.viewOut) {
oldView.get('container')
.transition(fx.viewOut, fxConfig, transitions.add());
}
transitions.done(complete);
}
};
// -- Transition fx ------------------------------------------------------------
Y.mix(Y.Transition.fx, {
'app:fadeIn': {
opacity : 1,
duration: 0.3,
on: {
start: function (data) {
var styles = {opacity: 0},
config = data.config;
if (config.crossView && !config.prepended) {
styles.transform = 'translateX(-100%)';
}
this.setStyles(styles);
},
end: function () {
this.setStyle('transform', 'translateX(0)');
}
}
},
'app:fadeOut': {
opacity : 0,
duration: 0.3,
on: {
start: function (data) {
var styles = {opacity: 1},
config = data.config;
if (config.crossView && config.prepended) {
styles.transform = 'translateX(-100%)';
}
this.setStyles(styles);
},
end: function () {
this.setStyle('transform', 'translateX(0)');
}
}
},
'app:slideLeft': {
duration : 0.3,
transform: 'translateX(-100%)',
on: {
start: function () {
this.setStyles({
opacity : 1,
transform: 'translateX(0%)'
});
},
end: function () {
this.setStyle('transform', 'translateX(0)');
}
}
},
'app:slideRight': {
duration : 0.3,
transform: 'translateX(0)',
on: {
start: function () {
this.setStyles({
opacity : 1,
transform: 'translateX(-100%)'
});
},
end: function () {
this.setStyle('transform', 'translateX(0)');
}
}
}
});
// -- Namespacae ---------------------------------------------------------------
Y.App.TransitionsNative = AppTransitionsNative;
Y.Base.mix(Y.App, [AppTransitionsNative]);
}, '3.18.1', {"requires": ["app-transitions", "app-transitions-css", "parallel", "transition"]});
@@ -0,0 +1,242 @@
YUI.add('app-transitions', function (Y, NAME) {
/**
`Y.App` extension that provides view transitions in browsers which support
native CSS3 transitions.
@module app
@submodule app-transitions
@since 3.5.0
**/
/**
`Y.App` extension that provides view transitions in browsers which support
native CSS3 transitions.
View transitions provide an nice way to move from one "page" to the next that is
both pleasant to the user and helps to communicate a hierarchy between sections
of an application.
When the `"app-transitions"` module is used, it will automatically mix itself
into `Y.App` and transition between `activeView` changes using the following
effects:
- **`fade`**: Cross-fades between the old an new active views.
- **`slideLeft`**: The old and new active views are positioned next to each
other and both slide to the left.
- **`slideRight`**: The old and new active views are positioned next to each
other and both slide to the right.
**Note:** Transitions are an opt-in feature and are enabled via an app's
`transitions` attribute.
@class App.Transitions
@uses App.TransitionsNative
@extensionfor App
@since 3.5.0
**/
function AppTransitions() {}
AppTransitions.ATTRS = {
/**
Whether or not this application should use view transitions, and if so then
which ones or `true` for the defaults which are specified by the
`transitions` prototype property.
**Note:** Transitions are an opt-in feature and will only be used in
browsers which support native CSS3 transitions.
@attribute transitions
@type Boolean|Object
@default false
@since 3.5.0
**/
transitions: {
setter: '_setTransitions',
value : false
}
};
/**
Collect of transitions -> fx.
A transition (e.g. "fade") is a simple name given to a configuration of fx to
apply, consisting of `viewIn` and `viewOut` properties who's values are names of
fx registered on `Y.Transition.fx`.
By default transitions: `fade`, `slideLeft`, and `slideRight` have fx defined.
@property FX
@type Object
@static
@since 3.5.0
**/
AppTransitions.FX = {
fade: {
viewIn : 'app:fadeIn',
viewOut: 'app:fadeOut'
},
slideLeft: {
viewIn : 'app:slideLeft',
viewOut: 'app:slideLeft'
},
slideRight: {
viewIn : 'app:slideRight',
viewOut: 'app:slideRight'
}
};
AppTransitions.prototype = {
// -- Public Properties ----------------------------------------------------
/**
Default transitions to use when the `activeView` changes.
The following are types of changes for which transitions can be defined that
correspond to the relationship between the new and previous `activeView`:
* `navigate`: The default transition to use when changing the `activeView`
of the application.
* `toChild`: The transition to use when the new `activeView` is configured
as a child of the previously active view via its `parent` property as
defined in this app's `views`.
* `toParent`: The transition to use when the new `activeView` is
configured as the `parent` of the previously active view as defined in
this app's `views`.
**Note:** Transitions are an opt-in feature and will only be used in
browsers which support native CSS3 transitions.
@property transitions
@type Object
@default
{
navigate: 'fade',
toChild : 'slideLeft',
toParent: 'slideRight'
}
@since 3.5.0
**/
transitions: {
navigate: 'fade',
toChild : 'slideLeft',
toParent: 'slideRight'
},
// -- Public Methods -------------------------------------------------------
/**
Sets which view is active/visible for the application. This will set the
app's `activeView` attribute to the specified `view`.
The `view` will be "attached" to this app, meaning it will be both rendered
into this app's `viewContainer` node and all of its events will bubble to
the app. The previous `activeView` will be "detached" from this app.
When a string-name is provided for a view which has been registered on this
app's `views` object, the referenced metadata will be used and the
`activeView` will be set to either a preserved view instance, or a new
instance of the registered view will be created using the specified `config`
object passed-into this method.
A callback function can be specified as either the third or fourth argument,
and this function will be called after the new `view` becomes the
`activeView`, is rendered to the `viewContainer`, and is ready to use.
@example
var app = new Y.App({
views: {
usersView: {
// Imagine that `Y.UsersView` has been defined.
type: Y.UsersView
}
},
transitions: true,
users : new Y.ModelList()
});
app.route('/users/', function () {
this.showView('usersView', {users: this.get('users')});
});
app.render();
app.navigate('/uses/');
// => Creates a new `Y.UsersView` and transitions to it.
@method showView
@param {String|View} view The name of a view defined in the `views` object,
or a view instance which should become this app's `activeView`.
@param {Object} [config] Optional configuration to use when creating a new
view instance. This config object can also be used to update an existing
or preserved view's attributes when `options.update` is `true`.
@param {Object} [options] Optional object containing any of the following
properties:
@param {Function} [options.callback] Optional callback function to call
after new `activeView` is ready to use, the function will be passed:
@param {View} options.callback.view A reference to the new
`activeView`.
@param {Boolean} [options.prepend=false] Whether the `view` should be
prepended instead of appended to the `viewContainer`.
@param {Boolean} [options.render] Whether the `view` should be rendered.
**Note:** If no value is specified, a view instance will only be
rendered if it's newly created by this method.
@param {Boolean|String} [options.transition] Optional transition override.
A transition can be specified which will override the default, or
`false` for no transition.
@param {Boolean} [options.update=false] Whether an existing view should
have its attributes updated by passing the `config` object to its
`setAttrs()` method. **Note:** This option does not have an effect if
the `view` instance is created as a result of calling this method.
@param {Function} [callback] Optional callback Function to call after the
new `activeView` is ready to use. **Note:** this will override
`options.callback` and it can be specified as either the third or fourth
argument. The function will be passed the following:
@param {View} callback.view A reference to the new `activeView`.
@chainable
@since 3.5.0
**/
// Does not override `showView()` but does use `options.transitions`.
// -- Protected Methods ----------------------------------------------------
/**
Setter for `transitions` attribute.
When specified as `true`, the defaults will be use as specified by the
`transitions` prototype property.
@method _setTransitions
@param {Boolean|Object} transitions The new `transitions` attribute value.
@return {Mixed} The processed value which represents the new state.
@protected
@see App.Base.showView()
@since 3.5.0
**/
_setTransitions: function (transitions) {
var defTransitions = this.transitions;
if (transitions && transitions === true) {
return Y.merge(defTransitions);
}
return transitions;
}
};
// -- Namespace ----------------------------------------------------------------
Y.App.Transitions = AppTransitions;
Y.Base.mix(Y.App, [AppTransitions]);
Y.mix(Y.App.CLASS_NAMES, {
transitioning: Y.ClassNameManager.getClassName('app', 'transitioning')
});
}, '3.18.1', {"requires": ["app-base"]});
@@ -0,0 +1 @@
YUI.add("app-transitions",function(e,t){function n(){}n.ATTRS={transitions:{setter:"_setTransitions",value:!1}},n.FX={fade:{viewIn:"app:fadeIn",viewOut:"app:fadeOut"},slideLeft:{viewIn:"app:slideLeft",viewOut:"app:slideLeft"},slideRight:{viewIn:"app:slideRight",viewOut:"app:slideRight"}},n.prototype={transitions:{navigate:"fade",toChild:"slideLeft",toParent:"slideRight"},_setTransitions:function(t){var n=this.transitions;return t&&t===!0?e.merge(n):t}},e.App.Transitions=n,e.Base.mix(e.App,[n]),e.mix(e.App.CLASS_NAMES,{transitioning:e.ClassNameManager.getClassName("app","transitioning")})},"3.18.1",{requires:["app-base"]});
@@ -0,0 +1,242 @@
YUI.add('app-transitions', function (Y, NAME) {
/**
`Y.App` extension that provides view transitions in browsers which support
native CSS3 transitions.
@module app
@submodule app-transitions
@since 3.5.0
**/
/**
`Y.App` extension that provides view transitions in browsers which support
native CSS3 transitions.
View transitions provide an nice way to move from one "page" to the next that is
both pleasant to the user and helps to communicate a hierarchy between sections
of an application.
When the `"app-transitions"` module is used, it will automatically mix itself
into `Y.App` and transition between `activeView` changes using the following
effects:
- **`fade`**: Cross-fades between the old an new active views.
- **`slideLeft`**: The old and new active views are positioned next to each
other and both slide to the left.
- **`slideRight`**: The old and new active views are positioned next to each
other and both slide to the right.
**Note:** Transitions are an opt-in feature and are enabled via an app's
`transitions` attribute.
@class App.Transitions
@uses App.TransitionsNative
@extensionfor App
@since 3.5.0
**/
function AppTransitions() {}
AppTransitions.ATTRS = {
/**
Whether or not this application should use view transitions, and if so then
which ones or `true` for the defaults which are specified by the
`transitions` prototype property.
**Note:** Transitions are an opt-in feature and will only be used in
browsers which support native CSS3 transitions.
@attribute transitions
@type Boolean|Object
@default false
@since 3.5.0
**/
transitions: {
setter: '_setTransitions',
value : false
}
};
/**
Collect of transitions -> fx.
A transition (e.g. "fade") is a simple name given to a configuration of fx to
apply, consisting of `viewIn` and `viewOut` properties who's values are names of
fx registered on `Y.Transition.fx`.
By default transitions: `fade`, `slideLeft`, and `slideRight` have fx defined.
@property FX
@type Object
@static
@since 3.5.0
**/
AppTransitions.FX = {
fade: {
viewIn : 'app:fadeIn',
viewOut: 'app:fadeOut'
},
slideLeft: {
viewIn : 'app:slideLeft',
viewOut: 'app:slideLeft'
},
slideRight: {
viewIn : 'app:slideRight',
viewOut: 'app:slideRight'
}
};
AppTransitions.prototype = {
// -- Public Properties ----------------------------------------------------
/**
Default transitions to use when the `activeView` changes.
The following are types of changes for which transitions can be defined that
correspond to the relationship between the new and previous `activeView`:
* `navigate`: The default transition to use when changing the `activeView`
of the application.
* `toChild`: The transition to use when the new `activeView` is configured
as a child of the previously active view via its `parent` property as
defined in this app's `views`.
* `toParent`: The transition to use when the new `activeView` is
configured as the `parent` of the previously active view as defined in
this app's `views`.
**Note:** Transitions are an opt-in feature and will only be used in
browsers which support native CSS3 transitions.
@property transitions
@type Object
@default
{
navigate: 'fade',
toChild : 'slideLeft',
toParent: 'slideRight'
}
@since 3.5.0
**/
transitions: {
navigate: 'fade',
toChild : 'slideLeft',
toParent: 'slideRight'
},
// -- Public Methods -------------------------------------------------------
/**
Sets which view is active/visible for the application. This will set the
app's `activeView` attribute to the specified `view`.
The `view` will be "attached" to this app, meaning it will be both rendered
into this app's `viewContainer` node and all of its events will bubble to
the app. The previous `activeView` will be "detached" from this app.
When a string-name is provided for a view which has been registered on this
app's `views` object, the referenced metadata will be used and the
`activeView` will be set to either a preserved view instance, or a new
instance of the registered view will be created using the specified `config`
object passed-into this method.
A callback function can be specified as either the third or fourth argument,
and this function will be called after the new `view` becomes the
`activeView`, is rendered to the `viewContainer`, and is ready to use.
@example
var app = new Y.App({
views: {
usersView: {
// Imagine that `Y.UsersView` has been defined.
type: Y.UsersView
}
},
transitions: true,
users : new Y.ModelList()
});
app.route('/users/', function () {
this.showView('usersView', {users: this.get('users')});
});
app.render();
app.navigate('/uses/');
// => Creates a new `Y.UsersView` and transitions to it.
@method showView
@param {String|View} view The name of a view defined in the `views` object,
or a view instance which should become this app's `activeView`.
@param {Object} [config] Optional configuration to use when creating a new
view instance. This config object can also be used to update an existing
or preserved view's attributes when `options.update` is `true`.
@param {Object} [options] Optional object containing any of the following
properties:
@param {Function} [options.callback] Optional callback function to call
after new `activeView` is ready to use, the function will be passed:
@param {View} options.callback.view A reference to the new
`activeView`.
@param {Boolean} [options.prepend=false] Whether the `view` should be
prepended instead of appended to the `viewContainer`.
@param {Boolean} [options.render] Whether the `view` should be rendered.
**Note:** If no value is specified, a view instance will only be
rendered if it's newly created by this method.
@param {Boolean|String} [options.transition] Optional transition override.
A transition can be specified which will override the default, or
`false` for no transition.
@param {Boolean} [options.update=false] Whether an existing view should
have its attributes updated by passing the `config` object to its
`setAttrs()` method. **Note:** This option does not have an effect if
the `view` instance is created as a result of calling this method.
@param {Function} [callback] Optional callback Function to call after the
new `activeView` is ready to use. **Note:** this will override
`options.callback` and it can be specified as either the third or fourth
argument. The function will be passed the following:
@param {View} callback.view A reference to the new `activeView`.
@chainable
@since 3.5.0
**/
// Does not override `showView()` but does use `options.transitions`.
// -- Protected Methods ----------------------------------------------------
/**
Setter for `transitions` attribute.
When specified as `true`, the defaults will be use as specified by the
`transitions` prototype property.
@method _setTransitions
@param {Boolean|Object} transitions The new `transitions` attribute value.
@return {Mixed} The processed value which represents the new state.
@protected
@see App.Base.showView()
@since 3.5.0
**/
_setTransitions: function (transitions) {
var defTransitions = this.transitions;
if (transitions && transitions === true) {
return Y.merge(defTransitions);
}
return transitions;
}
};
// -- Namespace ----------------------------------------------------------------
Y.App.Transitions = AppTransitions;
Y.Base.mix(Y.App, [AppTransitions]);
Y.mix(Y.App.CLASS_NAMES, {
transitioning: Y.ClassNameManager.getClassName('app', 'transitioning')
});
}, '3.18.1', {"requires": ["app-base"]});
@@ -0,0 +1,400 @@
YUI.add('array-extras', function (Y, NAME) {
/**
Adds additional utility methods to the `Y.Array` class.
@module collection
@submodule array-extras
**/
var A = Y.Array,
L = Y.Lang,
ArrayProto = Array.prototype;
/**
Returns the index of the last item in the array that contains the specified
value, or `-1` if the value isn't found.
@method lastIndexOf
@param {Array} a Array to search in.
@param {Any} val Value to search for.
@param {Number} [fromIndex] Index at which to start searching backwards.
Defaults to the array's length - 1. If negative, it will be taken as an offset
from the end of the array. If the calculated index is less than 0, the array
will not be searched and `-1` will be returned.
@return {Number} Index of the item that contains the value, or `-1` if not
found.
@static
@for Array
**/
A.lastIndexOf = L._isNative(ArrayProto.lastIndexOf) ?
function(a, val, fromIndex) {
// An undefined fromIndex is still considered a value by some (all?)
// native implementations, so we can't pass it unless it's actually
// specified.
return fromIndex || fromIndex === 0 ? a.lastIndexOf(val, fromIndex) :
a.lastIndexOf(val);
} :
function(a, val, fromIndex) {
var len = a.length,
i = len - 1;
if (fromIndex || fromIndex === 0) {
i = Math.min(fromIndex < 0 ? len + fromIndex : fromIndex, len);
}
if (i > -1 && len > 0) {
for (; i > -1; --i) {
if (i in a && a[i] === val) {
return i;
}
}
}
return -1;
};
/**
Returns a copy of the input array with duplicate items removed.
Note: If the input array only contains strings, the `Y.Array.dedupe()` method is
a much faster alternative.
@method unique
@param {Array} array Array to dedupe.
@param {Function} [testFn] Custom function to use to test the equality of two
values. A truthy return value indicates that the values are equal. A falsy
return value indicates that the values are not equal.
@param {Any} testFn.a First value to compare.
@param {Any} testFn.b Second value to compare.
@param {Number} testFn.index Index of the current item in the original
array.
@param {Array} testFn.array The original array.
@return {Boolean} _true_ if the items are equal, _false_ otherwise.
@return {Array} Copy of the input array with duplicate items removed.
@static
**/
A.unique = function (array, testFn) {
var i = 0,
len = array.length,
results = [],
j, result, resultLen, value;
// Note the label here. It's used to jump out of the inner loop when a value
// is not unique.
outerLoop: for (; i < len; i++) {
value = array[i];
// For each value in the input array, iterate through the result array
// and check for uniqueness against each result value.
for (j = 0, resultLen = results.length; j < resultLen; j++) {
result = results[j];
// If the test function returns true or there's no test function and
// the value equals the current result item, stop iterating over the
// results and continue to the next value in the input array.
if (testFn) {
if (testFn.call(array, value, result, i, array)) {
continue outerLoop;
}
} else if (value === result) {
continue outerLoop;
}
}
// If we get this far, that means the current value is not already in
// the result array, so add it.
results.push(value);
}
return results;
};
/**
Executes the supplied function on each item in the array. Returns a new array
containing the items for which the supplied function returned a truthy value.
@method filter
@param {Array} a Array to filter.
@param {Function} f Function to execute on each item.
@param {Object} [o] Optional context object.
@return {Array} Array of items for which the supplied function returned a
truthy value (empty if it never returned a truthy value).
@static
*/
A.filter = L._isNative(ArrayProto.filter) ?
function(a, f, o) {
return ArrayProto.filter.call(a, f, o);
} :
function(a, f, o) {
var i = 0,
len = a.length,
results = [],
item;
for (; i < len; ++i) {
if (i in a) {
item = a[i];
if (f.call(o, item, i, a)) {
results.push(item);
}
}
}
return results;
};
/**
The inverse of `Array.filter()`. Executes the supplied function on each item.
Returns a new array containing the items for which the supplied function
returned `false`.
@method reject
@param {Array} a the array to iterate.
@param {Function} f the function to execute on each item.
@param {object} [o] Optional context object.
@return {Array} The items for which the supplied function returned `false`.
@static
*/
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. Iteration stops if the
supplied function does not return a truthy value.
@method every
@param {Array} a the array to iterate.
@param {Function} f the function to execute on each item.
@param {Object} [o] Optional context object.
@return {Boolean} `true` if every item in the array returns `true` from the
supplied function, `false` otherwise.
@static
*/
A.every = L._isNative(ArrayProto.every) ?
function(a, f, o) {
return ArrayProto.every.call(a, f, o);
} :
function(a, f, o) {
for (var i = 0, l = a.length; i < l; ++i) {
if (i in a && !f.call(o, a[i], i, a)) {
return false;
}
}
return true;
};
/**
Executes the supplied function on each item in the array and returns a new array
containing all the values returned by the supplied function.
@example
// Convert an array of numbers into an array of strings.
Y.Array.map([1, 2, 3, 4], function (item) {
return '' + item;
});
// => ['1', '2', '3', '4']
@method map
@param {Array} a the array to iterate.
@param {Function} f the function to execute on each item.
@param {object} [o] Optional context object.
@return {Array} A new array containing the return value of the supplied function
for each item in the original array.
@static
*/
A.map = L._isNative(ArrayProto.map) ?
function(a, f, o) {
return ArrayProto.map.call(a, f, o);
} :
function(a, f, o) {
var i = 0,
len = a.length,
results = ArrayProto.concat.call(a);
for (; i < len; ++i) {
if (i in a) {
results[i] = f.call(o, a[i], i, a);
}
}
return results;
};
/**
Executes the supplied function on each item in the array, "folding" the array
into a single value.
@method reduce
@param {Array} a Array to iterate.
@param {Any} init Initial value to start with.
@param {Function} f Function to execute on each item. This function should
update and return the value of the computation. It will receive the following
arguments:
@param {Any} f.previousValue Value returned from the previous iteration,
or the initial value if this is the first iteration.
@param {Any} f.currentValue Value of the current item being iterated.
@param {Number} f.index Index of the current item.
@param {Array} f.array Array being iterated.
@param {Object} [o] Optional context object.
@return {Any} Final result from iteratively applying the given function to each
element in the array.
@static
*/
A.reduce = L._isNative(ArrayProto.reduce) ?
function(a, init, f, o) {
// ES5 Array.reduce doesn't support a thisObject, so we need to
// implement it manually.
return ArrayProto.reduce.call(a, function(init, item, i, a) {
return f.call(o, init, item, i, a);
}, init);
} :
function(a, init, f, o) {
var i = 0,
len = a.length,
result = init;
for (; i < len; ++i) {
if (i in a) {
result = f.call(o, result, a[i], i, a);
}
}
return result;
};
/**
Executes the supplied function on each item in the array, searching for the
first item that matches the supplied function.
@method find
@param {Array} a the array to search.
@param {Function} f the function to execute on each item. Iteration is stopped
as soon as this function returns `true`.
@param {Object} [o] Optional context object.
@return {Object} the first item that the supplied function returns `true` for,
or `null` if it never returns `true`.
@static
*/
A.find = function(a, f, o) {
for (var i = 0, l = a.length; i < l; i++) {
if (i in a && 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 grep
@param {Array} a Array to iterate over.
@param {RegExp} pattern Regular expression to test against each item.
@return {Array} All the items in the array that produce a match against the
supplied regular expression. If no items match, an empty array is returned.
@static
*/
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 for which the
supplied function returns `true`, and one with the items for which the function
returns `false`.
@method partition
@param {Array} a Array to iterate over.
@param {Function} f Function to execute for each item in the array. It will
receive the following arguments:
@param {Any} f.item Current item.
@param {Number} f.index Index of the current item.
@param {Array} f.array The array being iterated.
@param {Object} [o] Optional execution context.
@return {Object} An object with two properties: `matches` and `rejects`. Each is
an array containing the items that were selected or rejected by the test
function (or an empty array if none).
@static
*/
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 zip
@param {Array} a Array to iterate over.
@param {Array} a2 Another array whose values will be paired with values of the
first array.
@return {Array} An array of arrays formed by pairing each element of the first
array with an item in the second array having the corresponding index.
@static
*/
A.zip = function(a, a2) {
var results = [];
A.each(a, function(item, index) {
results.push([item, a2[index]]);
});
return results;
};
/**
Flattens an array of nested arrays at any abitrary depth into a single, flat
array.
@method flatten
@param {Array} a Array with nested arrays to flatten.
@return {Array} An array whose nested arrays have been flattened.
@static
@since 3.7.0
**/
A.flatten = function(a) {
var result = [],
i, len, val;
// Always return an array.
if (!a) {
return result;
}
for (i = 0, len = a.length; i < len; ++i) {
val = a[i];
if (L.isArray(val)) {
// Recusively flattens any nested arrays.
result.push.apply(result, A.flatten(val));
} else {
result.push(val);
}
}
return result;
};
}, '3.18.1', {"requires": ["yui-base"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("array-extras",function(e,t){var n=e.Array,r=e.Lang,i=Array.prototype;n.lastIndexOf=r._isNative(i.lastIndexOf)?function(e,t,n){return n||n===0?e.lastIndexOf(t,n):e.lastIndexOf(t)}:function(e,t,n){var r=e.length,i=r-1;if(n||n===0)i=Math.min(n<0?r+n:n,r);if(i>-1&&r>0)for(;i>-1;--i)if(i in e&&e[i]===t)return i;return-1},n.unique=function(e,t){var n=0,r=e.length,i=[],s,o,u,a;e:for(;n<r;n++){a=e[n];for(s=0,u=i.length;s<u;s++){o=i[s];if(t){if(t.call(e,a,o,n,e))continue e}else if(a===o)continue e}i.push(a)}return i},n.filter=r._isNative(i.filter)?function(e,t,n){return i.filter.call(e,t,n)}:function(e,t,n){var r=0,i=e.length,s=[],o;for(;r<i;++r)r in e&&(o=e[r],t.call(n,o,r,e)&&s.push(o));return s},n.reject=function(e,t,r){return n.filter(e,function(e,n,i){return!t.call(r,e,n,i)})},n.every=r._isNative(i.every)?function(e,t,n){return i.every.call(e,t,n)}:function(e,t,n){for(var r=0,i=e.length;r<i;++r)if(r in e&&!t.call(n,e[r],r,e))return!1;return!0},n.map=r._isNative(i.map)?function(e,t,n){return i.map.call(e,t,n)}:function(e,t,n){var r=0,s=e.length,o=i.concat.call(e);for(;r<s;++r)r in e&&(o[r]=t.call(n,e[r],r,e));return o},n.reduce=r._isNative(i.reduce)?function(e,t,n,r){return i.reduce.call(e,function(e,t,i,s){return n.call(r,e,t,i,s)},t)}:function(e,t,n,r){var i=0,s=e.length,o=t;for(;i<s;++i)i in e&&(o=n.call(r,o,e[i],i,e));return o},n.find=function(e,t,n){for(var r=0,i=e.length;r<i;r++)if(r in e&&t.call(n,e[r],r,e))return e[r];return null},n.grep=function(e,t){return n.filter(e,function(e,n){return t.test(e)})},n.partition=function(e,t,r){var i={matches:[],rejects:[]};return n.each(e,function(n,s){var u=t.call(r,n,s,e)?i.matches:i.rejects;u.push(n)}),i},n.zip=function(e,t){var r=[];return n.each(e,function(e,n){r.push([e,t[n]])}),r},n.flatten=function(e){var t=[],i,s,o;if(!e)return t;for(i=0,s=e.length;i<s;++i)o=e[i],r.isArray(o)?t.push.apply(t,n.flatten(o)):t.push(o);return t}},"3.18.1",{requires:["yui-base"]});
@@ -0,0 +1,400 @@
YUI.add('array-extras', function (Y, NAME) {
/**
Adds additional utility methods to the `Y.Array` class.
@module collection
@submodule array-extras
**/
var A = Y.Array,
L = Y.Lang,
ArrayProto = Array.prototype;
/**
Returns the index of the last item in the array that contains the specified
value, or `-1` if the value isn't found.
@method lastIndexOf
@param {Array} a Array to search in.
@param {Any} val Value to search for.
@param {Number} [fromIndex] Index at which to start searching backwards.
Defaults to the array's length - 1. If negative, it will be taken as an offset
from the end of the array. If the calculated index is less than 0, the array
will not be searched and `-1` will be returned.
@return {Number} Index of the item that contains the value, or `-1` if not
found.
@static
@for Array
**/
A.lastIndexOf = L._isNative(ArrayProto.lastIndexOf) ?
function(a, val, fromIndex) {
// An undefined fromIndex is still considered a value by some (all?)
// native implementations, so we can't pass it unless it's actually
// specified.
return fromIndex || fromIndex === 0 ? a.lastIndexOf(val, fromIndex) :
a.lastIndexOf(val);
} :
function(a, val, fromIndex) {
var len = a.length,
i = len - 1;
if (fromIndex || fromIndex === 0) {
i = Math.min(fromIndex < 0 ? len + fromIndex : fromIndex, len);
}
if (i > -1 && len > 0) {
for (; i > -1; --i) {
if (i in a && a[i] === val) {
return i;
}
}
}
return -1;
};
/**
Returns a copy of the input array with duplicate items removed.
Note: If the input array only contains strings, the `Y.Array.dedupe()` method is
a much faster alternative.
@method unique
@param {Array} array Array to dedupe.
@param {Function} [testFn] Custom function to use to test the equality of two
values. A truthy return value indicates that the values are equal. A falsy
return value indicates that the values are not equal.
@param {Any} testFn.a First value to compare.
@param {Any} testFn.b Second value to compare.
@param {Number} testFn.index Index of the current item in the original
array.
@param {Array} testFn.array The original array.
@return {Boolean} _true_ if the items are equal, _false_ otherwise.
@return {Array} Copy of the input array with duplicate items removed.
@static
**/
A.unique = function (array, testFn) {
var i = 0,
len = array.length,
results = [],
j, result, resultLen, value;
// Note the label here. It's used to jump out of the inner loop when a value
// is not unique.
outerLoop: for (; i < len; i++) {
value = array[i];
// For each value in the input array, iterate through the result array
// and check for uniqueness against each result value.
for (j = 0, resultLen = results.length; j < resultLen; j++) {
result = results[j];
// If the test function returns true or there's no test function and
// the value equals the current result item, stop iterating over the
// results and continue to the next value in the input array.
if (testFn) {
if (testFn.call(array, value, result, i, array)) {
continue outerLoop;
}
} else if (value === result) {
continue outerLoop;
}
}
// If we get this far, that means the current value is not already in
// the result array, so add it.
results.push(value);
}
return results;
};
/**
Executes the supplied function on each item in the array. Returns a new array
containing the items for which the supplied function returned a truthy value.
@method filter
@param {Array} a Array to filter.
@param {Function} f Function to execute on each item.
@param {Object} [o] Optional context object.
@return {Array} Array of items for which the supplied function returned a
truthy value (empty if it never returned a truthy value).
@static
*/
A.filter = L._isNative(ArrayProto.filter) ?
function(a, f, o) {
return ArrayProto.filter.call(a, f, o);
} :
function(a, f, o) {
var i = 0,
len = a.length,
results = [],
item;
for (; i < len; ++i) {
if (i in a) {
item = a[i];
if (f.call(o, item, i, a)) {
results.push(item);
}
}
}
return results;
};
/**
The inverse of `Array.filter()`. Executes the supplied function on each item.
Returns a new array containing the items for which the supplied function
returned `false`.
@method reject
@param {Array} a the array to iterate.
@param {Function} f the function to execute on each item.
@param {object} [o] Optional context object.
@return {Array} The items for which the supplied function returned `false`.
@static
*/
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. Iteration stops if the
supplied function does not return a truthy value.
@method every
@param {Array} a the array to iterate.
@param {Function} f the function to execute on each item.
@param {Object} [o] Optional context object.
@return {Boolean} `true` if every item in the array returns `true` from the
supplied function, `false` otherwise.
@static
*/
A.every = L._isNative(ArrayProto.every) ?
function(a, f, o) {
return ArrayProto.every.call(a, f, o);
} :
function(a, f, o) {
for (var i = 0, l = a.length; i < l; ++i) {
if (i in a && !f.call(o, a[i], i, a)) {
return false;
}
}
return true;
};
/**
Executes the supplied function on each item in the array and returns a new array
containing all the values returned by the supplied function.
@example
// Convert an array of numbers into an array of strings.
Y.Array.map([1, 2, 3, 4], function (item) {
return '' + item;
});
// => ['1', '2', '3', '4']
@method map
@param {Array} a the array to iterate.
@param {Function} f the function to execute on each item.
@param {object} [o] Optional context object.
@return {Array} A new array containing the return value of the supplied function
for each item in the original array.
@static
*/
A.map = L._isNative(ArrayProto.map) ?
function(a, f, o) {
return ArrayProto.map.call(a, f, o);
} :
function(a, f, o) {
var i = 0,
len = a.length,
results = ArrayProto.concat.call(a);
for (; i < len; ++i) {
if (i in a) {
results[i] = f.call(o, a[i], i, a);
}
}
return results;
};
/**
Executes the supplied function on each item in the array, "folding" the array
into a single value.
@method reduce
@param {Array} a Array to iterate.
@param {Any} init Initial value to start with.
@param {Function} f Function to execute on each item. This function should
update and return the value of the computation. It will receive the following
arguments:
@param {Any} f.previousValue Value returned from the previous iteration,
or the initial value if this is the first iteration.
@param {Any} f.currentValue Value of the current item being iterated.
@param {Number} f.index Index of the current item.
@param {Array} f.array Array being iterated.
@param {Object} [o] Optional context object.
@return {Any} Final result from iteratively applying the given function to each
element in the array.
@static
*/
A.reduce = L._isNative(ArrayProto.reduce) ?
function(a, init, f, o) {
// ES5 Array.reduce doesn't support a thisObject, so we need to
// implement it manually.
return ArrayProto.reduce.call(a, function(init, item, i, a) {
return f.call(o, init, item, i, a);
}, init);
} :
function(a, init, f, o) {
var i = 0,
len = a.length,
result = init;
for (; i < len; ++i) {
if (i in a) {
result = f.call(o, result, a[i], i, a);
}
}
return result;
};
/**
Executes the supplied function on each item in the array, searching for the
first item that matches the supplied function.
@method find
@param {Array} a the array to search.
@param {Function} f the function to execute on each item. Iteration is stopped
as soon as this function returns `true`.
@param {Object} [o] Optional context object.
@return {Object} the first item that the supplied function returns `true` for,
or `null` if it never returns `true`.
@static
*/
A.find = function(a, f, o) {
for (var i = 0, l = a.length; i < l; i++) {
if (i in a && 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 grep
@param {Array} a Array to iterate over.
@param {RegExp} pattern Regular expression to test against each item.
@return {Array} All the items in the array that produce a match against the
supplied regular expression. If no items match, an empty array is returned.
@static
*/
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 for which the
supplied function returns `true`, and one with the items for which the function
returns `false`.
@method partition
@param {Array} a Array to iterate over.
@param {Function} f Function to execute for each item in the array. It will
receive the following arguments:
@param {Any} f.item Current item.
@param {Number} f.index Index of the current item.
@param {Array} f.array The array being iterated.
@param {Object} [o] Optional execution context.
@return {Object} An object with two properties: `matches` and `rejects`. Each is
an array containing the items that were selected or rejected by the test
function (or an empty array if none).
@static
*/
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 zip
@param {Array} a Array to iterate over.
@param {Array} a2 Another array whose values will be paired with values of the
first array.
@return {Array} An array of arrays formed by pairing each element of the first
array with an item in the second array having the corresponding index.
@static
*/
A.zip = function(a, a2) {
var results = [];
A.each(a, function(item, index) {
results.push([item, a2[index]]);
});
return results;
};
/**
Flattens an array of nested arrays at any abitrary depth into a single, flat
array.
@method flatten
@param {Array} a Array with nested arrays to flatten.
@return {Array} An array whose nested arrays have been flattened.
@static
@since 3.7.0
**/
A.flatten = function(a) {
var result = [],
i, len, val;
// Always return an array.
if (!a) {
return result;
}
for (i = 0, len = a.length; i < len; ++i) {
val = a[i];
if (L.isArray(val)) {
// Recusively flattens any nested arrays.
result.push.apply(result, A.flatten(val));
} else {
result.push(val);
}
}
return result;
};
}, '3.18.1', {"requires": ["yui-base"]});
@@ -0,0 +1,40 @@
YUI.add('array-invoke', function (Y, NAME) {
/**
@module collection
@submodule array-invoke
*/
/**
Executes a named method on each item in an array of objects. Items in the array
that do not have a function by that name will be skipped.
@example
Y.Array.invoke(arrayOfDrags, 'plug', Y.Plugin.DDProxy);
@method invoke
@param {Array} items Array of objects supporting the named method.
@param {String} name the name of the method to execute on each item.
@param {Any} [args*] Any number of additional args are passed as parameters to
the execution of the named method.
@return {Array} All return values, indexed according to the item index.
@static
@for Array
**/
Y.Array.invoke = function(items, name) {
var args = Y.Array(arguments, 2, true),
isFunction = Y.Lang.isFunction,
ret = [];
Y.Array.each(Y.Array(items), function(item, i) {
if (item && isFunction(item[name])) {
ret[i] = item[name].apply(item, args);
}
});
return ret;
};
}, '3.18.1', {"requires": ["yui-base"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("array-invoke",function(e,t){e.Array.invoke=function(t,n){var r=e.Array(arguments,2,!0),i=e.Lang.isFunction,s=[];return e.Array.each(e.Array(t),function(e,t){e&&i(e[n])&&(s[t]=e[n].apply(e,r))}),s}},"3.18.1",{requires:["yui-base"]});
@@ -0,0 +1,40 @@
YUI.add('array-invoke', function (Y, NAME) {
/**
@module collection
@submodule array-invoke
*/
/**
Executes a named method on each item in an array of objects. Items in the array
that do not have a function by that name will be skipped.
@example
Y.Array.invoke(arrayOfDrags, 'plug', Y.Plugin.DDProxy);
@method invoke
@param {Array} items Array of objects supporting the named method.
@param {String} name the name of the method to execute on each item.
@param {Any} [args*] Any number of additional args are passed as parameters to
the execution of the named method.
@return {Array} All return values, indexed according to the item index.
@static
@for Array
**/
Y.Array.invoke = function(items, name) {
var args = Y.Array(arguments, 2, true),
isFunction = Y.Lang.isFunction,
ret = [];
Y.Array.each(Y.Array(items), function(item, i) {
if (item && isFunction(item[name])) {
ret[i] = item[name].apply(item, args);
}
});
return ret;
};
}, '3.18.1', {"requires": ["yui-base"]});
@@ -0,0 +1,87 @@
YUI.add('arraylist-add', function (Y, NAME) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist-add
* @deprecated Use ModelList or a custom ArrayList subclass
*/
/*
* Adds methods add and remove to Y.ArrayList
*/
Y.mix(Y.ArrayList.prototype, {
/**
* Add a single item to the ArrayList. Does not prevent duplicates.
*
* @method add
* @param { mixed } item Item presumably of the same type as others in the
* ArrayList.
* @param {Number} index (Optional.) Number representing the position at
* which the item should be inserted.
* @return {ArrayList} the instance.
* @for ArrayList
* @deprecated Use ModelList or a custom ArrayList subclass
* @chainable
*/
add: function(item, index) {
var items = this._items;
if (Y.Lang.isNumber(index)) {
items.splice(index, 0, item);
}
else {
items.push(item);
}
return this;
},
/**
* Removes first or all occurrences of an item to the ArrayList. If a
* comparator is not provided, uses itemsAreEqual method to determine
* matches.
*
* @method remove
* @param { mixed } needle Item to find and remove from the list.
* @param { Boolean } all If true, remove all occurrences.
* @param { Function } comparator optional a/b function to test equivalence.
* @return {ArrayList} the instance.
* @for ArrayList
* @deprecated Use ModelList or a custom ArrayList subclass
* @chainable
*/
remove: function(needle, all, comparator) {
comparator = comparator || this.itemsAreEqual;
for (var i = this._items.length - 1; i >= 0; --i) {
if (comparator.call(this, needle, this.item(i))) {
this._items.splice(i, 1);
if (!all) {
break;
}
}
}
return this;
},
/**
* Default comparator for items stored in this list. Used by remove().
*
* @method itemsAreEqual
* @param { mixed } a item to test equivalence with.
* @param { mixed } b other item to test equivalance.
* @return { Boolean } true if items are deemed equivalent.
* @for ArrayList
* @deprecated Use ModelList or a custom ArrayList subclass
*/
itemsAreEqual: function(a, b) {
return a === b;
}
});
}, '3.18.1', {"requires": ["arraylist"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("arraylist-add",function(e,t){e.mix(e.ArrayList.prototype,{add:function(t,n){var r=this._items;return e.Lang.isNumber(n)?r.splice(n,0,t):r.push(t),this},remove:function(e,t,n){n=n||this.itemsAreEqual;for(var r=this._items.length-1;r>=0;--r)if(n.call(this,e,this.item(r))){this._items.splice(r,1);if(!t)break}return this},itemsAreEqual:function(e,t){return e===t}})},"3.18.1",{requires:["arraylist"]});
@@ -0,0 +1,87 @@
YUI.add('arraylist-add', function (Y, NAME) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist-add
* @deprecated Use ModelList or a custom ArrayList subclass
*/
/*
* Adds methods add and remove to Y.ArrayList
*/
Y.mix(Y.ArrayList.prototype, {
/**
* Add a single item to the ArrayList. Does not prevent duplicates.
*
* @method add
* @param { mixed } item Item presumably of the same type as others in the
* ArrayList.
* @param {Number} index (Optional.) Number representing the position at
* which the item should be inserted.
* @return {ArrayList} the instance.
* @for ArrayList
* @deprecated Use ModelList or a custom ArrayList subclass
* @chainable
*/
add: function(item, index) {
var items = this._items;
if (Y.Lang.isNumber(index)) {
items.splice(index, 0, item);
}
else {
items.push(item);
}
return this;
},
/**
* Removes first or all occurrences of an item to the ArrayList. If a
* comparator is not provided, uses itemsAreEqual method to determine
* matches.
*
* @method remove
* @param { mixed } needle Item to find and remove from the list.
* @param { Boolean } all If true, remove all occurrences.
* @param { Function } comparator optional a/b function to test equivalence.
* @return {ArrayList} the instance.
* @for ArrayList
* @deprecated Use ModelList or a custom ArrayList subclass
* @chainable
*/
remove: function(needle, all, comparator) {
comparator = comparator || this.itemsAreEqual;
for (var i = this._items.length - 1; i >= 0; --i) {
if (comparator.call(this, needle, this.item(i))) {
this._items.splice(i, 1);
if (!all) {
break;
}
}
}
return this;
},
/**
* Default comparator for items stored in this list. Used by remove().
*
* @method itemsAreEqual
* @param { mixed } a item to test equivalence with.
* @param { mixed } b other item to test equivalance.
* @return { Boolean } true if items are deemed equivalent.
* @for ArrayList
* @deprecated Use ModelList or a custom ArrayList subclass
*/
itemsAreEqual: function(a, b) {
return a === b;
}
});
}, '3.18.1', {"requires": ["arraylist"]});
@@ -0,0 +1,45 @@
YUI.add('arraylist-filter', function (Y, NAME) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist-filter
* @deprecated Use ModelList or a custom subclass implementation
*/
/*
* Adds filter method to ArrayList prototype
*/
Y.mix(Y.ArrayList.prototype, {
/**
* <p>Create a new ArrayList (or augmenting class instance) from a subset
* of items as determined by the boolean function passed as the
* argument. The original ArrayList is unchanged.</p>
*
* <p>The validator signature is <code>validator( item )</code>.</p>
*
* @method filter
* @param { Function } validator Boolean function to determine in or out.
* @return { ArrayList } New instance based on who passed the validator.
* @for ArrayList
* @deprecated Use ModelList or a custom subclass implementation
*/
filter: function(validator) {
var items = [];
Y.Array.each(this._items, function(item, i) {
item = this.item(i);
if (validator(item)) {
items.push(item);
}
}, this);
return new this.constructor(items);
}
});
}, '3.18.1', {"requires": ["arraylist"]});
@@ -0,0 +1 @@
YUI.add("arraylist-filter",function(e,t){e.mix(e.ArrayList.prototype,{filter:function(t){var n=[];return e.Array.each(this._items,function(e,r){e=this.item(r),t(e)&&n.push(e)},this),new this.constructor(n)}})},"3.18.1",{requires:["arraylist"]});
@@ -0,0 +1,45 @@
YUI.add('arraylist-filter', function (Y, NAME) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist-filter
* @deprecated Use ModelList or a custom subclass implementation
*/
/*
* Adds filter method to ArrayList prototype
*/
Y.mix(Y.ArrayList.prototype, {
/**
* <p>Create a new ArrayList (or augmenting class instance) from a subset
* of items as determined by the boolean function passed as the
* argument. The original ArrayList is unchanged.</p>
*
* <p>The validator signature is <code>validator( item )</code>.</p>
*
* @method filter
* @param { Function } validator Boolean function to determine in or out.
* @return { ArrayList } New instance based on who passed the validator.
* @for ArrayList
* @deprecated Use ModelList or a custom subclass implementation
*/
filter: function(validator) {
var items = [];
Y.Array.each(this._items, function(item, i) {
item = this.item(i);
if (validator(item)) {
items.push(item);
}
}, this);
return new this.constructor(items);
}
});
}, '3.18.1', {"requires": ["arraylist"]});
@@ -0,0 +1,214 @@
YUI.add('arraylist', function (Y, NAME) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist
*/
var YArray = Y.Array,
YArray_each = YArray.each,
ArrayListProto;
/**
* Generic ArrayList class for managing lists of items and iterating operations
* over them. The targeted use for this class is for augmentation onto a
* class that is responsible for managing multiple instances of another class
* (e.g. NodeList for Nodes). The recommended use is to augment your class with
* ArrayList, then use ArrayList.addMethod to mirror the API of the constituent
* items on the list's API.
*
* The default implementation creates immutable lists, but mutability can be
* provided via the arraylist-add submodule or by implementing mutation methods
* directly on the augmented class's prototype.
*
* @class ArrayList
* @constructor
* @param items { Array } array of items this list will be responsible for
*/
function ArrayList( items ) {
if ( items !== undefined ) {
this._items = Y.Lang.isArray( items ) ? items : YArray( items );
} else {
// ||= to support lazy initialization from augment
this._items = this._items || [];
}
}
ArrayListProto = {
/**
* Get an item by index from the list. Override this method if managing a
* list of objects that have a different public representation (e.g. Node
* instances vs DOM nodes). The iteration methods that accept a user
* function will use this method for access list items for operation.
*
* @method item
* @param i { Integer } index to fetch
* @return { mixed } the item at the requested index
*/
item: function ( i ) {
return this._items[i];
},
/**
* <p>Execute a function on each item of the list, optionally providing a
* custom execution context. Default context is the item.</p>
*
* <p>The callback signature is <code>callback( item, index )</code>.</p>
*
* @method each
* @param fn { Function } the function to execute
* @param context { mixed } optional override 'this' in the function
* @return { ArrayList } this instance
* @chainable
*/
each: function ( fn, context ) {
YArray_each( this._items, function ( item, i ) {
item = this.item( i );
fn.call( context || item, item, i, this );
}, this);
return this;
},
/**
* <p>Execute a function on each item of the list, optionally providing a
* custom execution context. Default context is the item.</p>
*
* <p>The callback signature is <code>callback( item, index )</code>.</p>
*
* <p>Unlike <code>each</code>, if the callback returns true, the
* iteration will stop.</p>
*
* @method some
* @param fn { Function } the function to execute
* @param context { mixed } optional override 'this' in the function
* @return { Boolean } True if the function returned true on an item
*/
some: function ( fn, context ) {
return YArray.some( this._items, function ( item, i ) {
item = this.item( i );
return fn.call( context || item, item, i, this );
}, this);
},
/**
* Finds the first index of the needle in the managed array of items.
*
* @method indexOf
* @param needle { mixed } The item to search for
* @return { Integer } Array index if found. Otherwise -1
*/
indexOf: function ( needle ) {
return YArray.indexOf( this._items, needle );
},
/**
* How many items are in this list?
*
* @method size
* @return { Integer } Number of items in the list
*/
size: function () {
return this._items.length;
},
/**
* Is this instance managing any items?
*
* @method isEmpty
* @return { Boolean } true if 1 or more items are being managed
*/
isEmpty: function () {
return !this.size();
},
/**
* Provides an array-like representation for JSON.stringify.
*
* @method toJSON
* @return { Array } an array representation of the ArrayList
*/
toJSON: function () {
return this._items;
}
};
// Default implementation does not distinguish between public and private
// item getter
/**
* Protected method for optimizations that may be appropriate for API
* mirroring. Similar in functionality to <code>item</code>, but is used by
* methods added with <code>ArrayList.addMethod()</code>.
*
* @method _item
* @protected
* @param i { Integer } Index of item to fetch
* @return { mixed } The item appropriate for pass through API methods
*/
ArrayListProto._item = ArrayListProto.item;
// Mixed onto existing proto to preserve constructor NOT being an own property.
// This has bitten me when composing classes by enumerating, copying prototypes.
Y.mix(ArrayList.prototype, ArrayListProto);
Y.mix( ArrayList, {
/**
* <p>Adds a pass through method to dest (typically the prototype of a list
* class) that calls the named method on each item in the list with
* whatever parameters are passed in. Allows for API indirection via list
* instances.</p>
*
* <p>Accepts a single string name or an array of string names.</p>
*
* <pre><code>list.each( function ( item ) {
* item.methodName( 1, 2, 3 );
* } );
* // becomes
* list.methodName( 1, 2, 3 );</code></pre>
*
* <p>Additionally, the pass through methods use the item retrieved by the
* <code>_item</code> method in case there is any special behavior that is
* appropriate for API mirroring.</p>
*
* <p>If the iterated method returns a value, the return value from the
* added method will be an array of values with each value being at the
* corresponding index for that item. If the iterated method does not
* return a value, the added method will be chainable.
*
* @method addMethod
* @static
* @param dest {Object} Object or prototype to receive the iterator method
* @param name {String|String[]} Name of method of methods to create
*/
addMethod: function ( dest, names ) {
names = YArray( names );
YArray_each( names, function ( name ) {
dest[ name ] = function () {
var args = YArray( arguments, 0, true ),
ret = [];
YArray_each( this._items, function ( item, i ) {
item = this._item( i );
var result = item[ name ].apply( item, args );
if ( result !== undefined && result !== item ) {
ret[i] = result;
}
}, this);
return ret.length ? ret : this;
};
} );
}
} );
Y.ArrayList = ArrayList;
}, '3.18.1', {"requires": ["yui-base"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("arraylist",function(e,t){function s(t){t!==undefined?this._items=e.Lang.isArray(t)?t:n(t):this._items=this._items||[]}var n=e.Array,r=n.each,i;i={item:function(e){return this._items[e]},each:function(e,t){return r(this._items,function(n,r){n=this.item(r),e.call(t||n,n,r,this)},this),this},some:function(e,t){return n.some(this._items,function(n,r){return n=this.item(r),e.call(t||n,n,r,this)},this)},indexOf:function(e){return n.indexOf(this._items,e)},size:function(){return this._items.length},isEmpty:function(){return!this.size()},toJSON:function(){return this._items}},i._item=i.item,e.mix(s.prototype,i),e.mix(s,{addMethod:function(e,t){t=n(t),r(t,function(t){e[t]=function(){var e=n(arguments,0,!0),i=[];return r(this._items,function(n,r){n=this._item(r);var s=n[t].apply(n,e);s!==undefined&&s!==n&&(i[r]=s)},this),i.length?i:this}})}}),e.ArrayList=s},"3.18.1",{requires:["yui-base"]});
+214
View File
@@ -0,0 +1,214 @@
YUI.add('arraylist', function (Y, NAME) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
* @submodule arraylist
*/
var YArray = Y.Array,
YArray_each = YArray.each,
ArrayListProto;
/**
* Generic ArrayList class for managing lists of items and iterating operations
* over them. The targeted use for this class is for augmentation onto a
* class that is responsible for managing multiple instances of another class
* (e.g. NodeList for Nodes). The recommended use is to augment your class with
* ArrayList, then use ArrayList.addMethod to mirror the API of the constituent
* items on the list's API.
*
* The default implementation creates immutable lists, but mutability can be
* provided via the arraylist-add submodule or by implementing mutation methods
* directly on the augmented class's prototype.
*
* @class ArrayList
* @constructor
* @param items { Array } array of items this list will be responsible for
*/
function ArrayList( items ) {
if ( items !== undefined ) {
this._items = Y.Lang.isArray( items ) ? items : YArray( items );
} else {
// ||= to support lazy initialization from augment
this._items = this._items || [];
}
}
ArrayListProto = {
/**
* Get an item by index from the list. Override this method if managing a
* list of objects that have a different public representation (e.g. Node
* instances vs DOM nodes). The iteration methods that accept a user
* function will use this method for access list items for operation.
*
* @method item
* @param i { Integer } index to fetch
* @return { mixed } the item at the requested index
*/
item: function ( i ) {
return this._items[i];
},
/**
* <p>Execute a function on each item of the list, optionally providing a
* custom execution context. Default context is the item.</p>
*
* <p>The callback signature is <code>callback( item, index )</code>.</p>
*
* @method each
* @param fn { Function } the function to execute
* @param context { mixed } optional override 'this' in the function
* @return { ArrayList } this instance
* @chainable
*/
each: function ( fn, context ) {
YArray_each( this._items, function ( item, i ) {
item = this.item( i );
fn.call( context || item, item, i, this );
}, this);
return this;
},
/**
* <p>Execute a function on each item of the list, optionally providing a
* custom execution context. Default context is the item.</p>
*
* <p>The callback signature is <code>callback( item, index )</code>.</p>
*
* <p>Unlike <code>each</code>, if the callback returns true, the
* iteration will stop.</p>
*
* @method some
* @param fn { Function } the function to execute
* @param context { mixed } optional override 'this' in the function
* @return { Boolean } True if the function returned true on an item
*/
some: function ( fn, context ) {
return YArray.some( this._items, function ( item, i ) {
item = this.item( i );
return fn.call( context || item, item, i, this );
}, this);
},
/**
* Finds the first index of the needle in the managed array of items.
*
* @method indexOf
* @param needle { mixed } The item to search for
* @return { Integer } Array index if found. Otherwise -1
*/
indexOf: function ( needle ) {
return YArray.indexOf( this._items, needle );
},
/**
* How many items are in this list?
*
* @method size
* @return { Integer } Number of items in the list
*/
size: function () {
return this._items.length;
},
/**
* Is this instance managing any items?
*
* @method isEmpty
* @return { Boolean } true if 1 or more items are being managed
*/
isEmpty: function () {
return !this.size();
},
/**
* Provides an array-like representation for JSON.stringify.
*
* @method toJSON
* @return { Array } an array representation of the ArrayList
*/
toJSON: function () {
return this._items;
}
};
// Default implementation does not distinguish between public and private
// item getter
/**
* Protected method for optimizations that may be appropriate for API
* mirroring. Similar in functionality to <code>item</code>, but is used by
* methods added with <code>ArrayList.addMethod()</code>.
*
* @method _item
* @protected
* @param i { Integer } Index of item to fetch
* @return { mixed } The item appropriate for pass through API methods
*/
ArrayListProto._item = ArrayListProto.item;
// Mixed onto existing proto to preserve constructor NOT being an own property.
// This has bitten me when composing classes by enumerating, copying prototypes.
Y.mix(ArrayList.prototype, ArrayListProto);
Y.mix( ArrayList, {
/**
* <p>Adds a pass through method to dest (typically the prototype of a list
* class) that calls the named method on each item in the list with
* whatever parameters are passed in. Allows for API indirection via list
* instances.</p>
*
* <p>Accepts a single string name or an array of string names.</p>
*
* <pre><code>list.each( function ( item ) {
* item.methodName( 1, 2, 3 );
* } );
* // becomes
* list.methodName( 1, 2, 3 );</code></pre>
*
* <p>Additionally, the pass through methods use the item retrieved by the
* <code>_item</code> method in case there is any special behavior that is
* appropriate for API mirroring.</p>
*
* <p>If the iterated method returns a value, the return value from the
* added method will be an array of values with each value being at the
* corresponding index for that item. If the iterated method does not
* return a value, the added method will be chainable.
*
* @method addMethod
* @static
* @param dest {Object} Object or prototype to receive the iterator method
* @param name {String|String[]} Name of method of methods to create
*/
addMethod: function ( dest, names ) {
names = YArray( names );
YArray_each( names, function ( name ) {
dest[ name ] = function () {
var args = YArray( arguments, 0, true ),
ret = [];
YArray_each( this._items, function ( item, i ) {
item = this._item( i );
var result = item[ name ].apply( item, args );
if ( result !== undefined && result !== item ) {
ret[i] = result;
}
}, this);
return ret.length ? ret : this;
};
} );
}
} );
Y.ArrayList = ArrayList;
}, '3.18.1', {"requires": ["yui-base"]});
@@ -0,0 +1,181 @@
YUI.add('arraysort', function (Y, NAME) {
/*jshint expr:true, onevar:false */
/**
Provides comparator functions useful for sorting arrays.
@module arraysort
**/
var LANG = Y.Lang,
ISVALUE = LANG.isValue,
ISSTRING = LANG.isString;
/**
Provides comparator functions useful for sorting arrays.
@class ArraySort
@static
**/
var ArraySort = Y.ArraySort = {
// -- Public Methods -------------------------------------------------------
/**
Comparator function for simple case-insensitive sorting of an array of
strings.
@method compare
@param a {Object} First sort argument.
@param b {Object} Second sort argument.
@param desc {Boolean} `true` if sort direction is descending, `false` if
sort direction is ascending.
@return {Boolean} -1 when a < b. 0 when a == b. 1 when a > b.
@static
*/
compare: function(a, b, desc) {
if(!ISVALUE(a)) {
if(!ISVALUE(b)) {
return 0;
}
else {
return 1;
}
}
else if(!ISVALUE(b)) {
return -1;
}
if(ISSTRING(a)) {
a = a.toLowerCase();
}
if(ISSTRING(b)) {
b = b.toLowerCase();
}
if(a < b) {
return (desc) ? 1 : -1;
}
else if (a > b) {
return (desc) ? -1 : 1;
}
else {
return 0;
}
},
/**
Performs a natural-order comparison of two strings or numbers (or a string
and a number). This ensures that a value like 'foo2' will be sorted before
'foo10', whereas a standard ASCII sort would sort 'foo10' first.
@example
var items = ['item10', 'item2', 'item1', 10, '1', 2];
items.sort(Y.ArraySort.naturalCompare);
console.log(items); // => ['1', 2, 10, 'item1', 'item2', 'item10']
@method naturalCompare
@param {Number|String} a First value to compare.
@param {Number|String} b Second value to compare.
@param {Object} [options] Options.
@param {Boolean} [options.caseSensitive=false] If `true`, a
case-sensitive comparison will be performed. By default the
comparison is case-insensitive.
@param {Boolean} [options.descending=false] If `true`, the sort order
will be reversed so that larger values are sorted before smaller
values.
@return {Number} `0` if the two items are equal, a negative number if _a_
should be sorted before _b_, or a positive number if _b_ should be
sorted before _a_.
@static
@since 3.11.0
**/
naturalCompare: function (a, b, options) {
// Coerce `a` and `b` to strings.
a += '';
b += '';
// Convert `a` and `b` to lowercase unless `options.caseSensitive` is
// truthy.
if (!options || !options.caseSensitive) {
a = a.toLowerCase();
b = b.toLowerCase();
}
// Split `a` and `b` into alpha parts and numeric parts.
var aParts = ArraySort._splitAlphaNum(a),
bParts = ArraySort._splitAlphaNum(b),
length = Math.min(aParts.length, bParts.length),
result = 0,
aPart,
bPart,
i;
// Compare each part of `a` with each part of `b`.
for (i = 0; i < length; i++) {
aPart = aParts[i];
bPart = bParts[i];
// If the two parts aren't equal, compare them and stop iterating.
if (aPart !== bPart) {
// First, try comparing them as numbers.
result = aPart - bPart;
// If that didn't work, compare them as strings. This falsiness
// check works because `result` can't be 0 (we checked for
// equality above) and NaN is falsy.
if (!result) {
result = aPart > bPart ? 1 : -1;
}
// At this point we know enough to be able to sort the two
// strings, so we don't need to compare any more parts.
break;
}
}
// If we get here and `result` is still 0, then sort the shorter string
// before the longer string.
result || (result = a.length - b.length);
// Return the result, flipping the order if `options.descending` is
// truthy.
return options && options.descending ? -result : result;
},
// -- Protected Methods ----------------------------------------------------
/**
Splits a string into an array of alpha character and digit character parts.
@example
Y.ArraySort._splitAlphaNum('abc123def456');
// => ['abc', '123', 'def', '456']
@method _splitAlphaNum
@param {String} string String to split.
@return {String[]} Array of alpha parts and digit parts.
@protected
@static
@since 3.11.0
**/
_splitAlphaNum: function (string) {
/*jshint boss:true */
var parts = [],
regex = /(\d+|\D+)/g,
match;
while (match = regex.exec(string)) { // assignment
parts.push(match[1]);
}
return parts;
}
};
}, '3.18.1', {"requires": ["yui-base"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("arraysort",function(e,t){var n=e.Lang,r=n.isValue,i=n.isString,s=e.ArraySort={compare:function(e,t,n){return r(e)?r(t)?(i(e)&&(e=e.toLowerCase()),i(t)&&(t=t.toLowerCase()),e<t?n?1:-1:e>t?n?-1:1:0):-1:r(t)?1:0},naturalCompare:function(e,t,n){e+="",t+="";if(!n||!n.caseSensitive)e=e.toLowerCase(),t=t.toLowerCase();var r=s._splitAlphaNum(e),i=s._splitAlphaNum(t),o=Math.min(r.length,i.length),u=0,a,f,l;for(l=0;l<o;l++){a=r[l],f=i[l];if(a!==f){u=a-f,u||(u=a>f?1:-1);break}}return u||(u=e.length-t.length),n&&n.descending?-u:u},_splitAlphaNum:function(e){var t=[],n=/(\d+|\D+)/g,r;while(r=n.exec(e))t.push(r[1]);return t}}},"3.18.1",{requires:["yui-base"]});
+181
View File
@@ -0,0 +1,181 @@
YUI.add('arraysort', function (Y, NAME) {
/*jshint expr:true, onevar:false */
/**
Provides comparator functions useful for sorting arrays.
@module arraysort
**/
var LANG = Y.Lang,
ISVALUE = LANG.isValue,
ISSTRING = LANG.isString;
/**
Provides comparator functions useful for sorting arrays.
@class ArraySort
@static
**/
var ArraySort = Y.ArraySort = {
// -- Public Methods -------------------------------------------------------
/**
Comparator function for simple case-insensitive sorting of an array of
strings.
@method compare
@param a {Object} First sort argument.
@param b {Object} Second sort argument.
@param desc {Boolean} `true` if sort direction is descending, `false` if
sort direction is ascending.
@return {Boolean} -1 when a < b. 0 when a == b. 1 when a > b.
@static
*/
compare: function(a, b, desc) {
if(!ISVALUE(a)) {
if(!ISVALUE(b)) {
return 0;
}
else {
return 1;
}
}
else if(!ISVALUE(b)) {
return -1;
}
if(ISSTRING(a)) {
a = a.toLowerCase();
}
if(ISSTRING(b)) {
b = b.toLowerCase();
}
if(a < b) {
return (desc) ? 1 : -1;
}
else if (a > b) {
return (desc) ? -1 : 1;
}
else {
return 0;
}
},
/**
Performs a natural-order comparison of two strings or numbers (or a string
and a number). This ensures that a value like 'foo2' will be sorted before
'foo10', whereas a standard ASCII sort would sort 'foo10' first.
@example
var items = ['item10', 'item2', 'item1', 10, '1', 2];
items.sort(Y.ArraySort.naturalCompare);
console.log(items); // => ['1', 2, 10, 'item1', 'item2', 'item10']
@method naturalCompare
@param {Number|String} a First value to compare.
@param {Number|String} b Second value to compare.
@param {Object} [options] Options.
@param {Boolean} [options.caseSensitive=false] If `true`, a
case-sensitive comparison will be performed. By default the
comparison is case-insensitive.
@param {Boolean} [options.descending=false] If `true`, the sort order
will be reversed so that larger values are sorted before smaller
values.
@return {Number} `0` if the two items are equal, a negative number if _a_
should be sorted before _b_, or a positive number if _b_ should be
sorted before _a_.
@static
@since 3.11.0
**/
naturalCompare: function (a, b, options) {
// Coerce `a` and `b` to strings.
a += '';
b += '';
// Convert `a` and `b` to lowercase unless `options.caseSensitive` is
// truthy.
if (!options || !options.caseSensitive) {
a = a.toLowerCase();
b = b.toLowerCase();
}
// Split `a` and `b` into alpha parts and numeric parts.
var aParts = ArraySort._splitAlphaNum(a),
bParts = ArraySort._splitAlphaNum(b),
length = Math.min(aParts.length, bParts.length),
result = 0,
aPart,
bPart,
i;
// Compare each part of `a` with each part of `b`.
for (i = 0; i < length; i++) {
aPart = aParts[i];
bPart = bParts[i];
// If the two parts aren't equal, compare them and stop iterating.
if (aPart !== bPart) {
// First, try comparing them as numbers.
result = aPart - bPart;
// If that didn't work, compare them as strings. This falsiness
// check works because `result` can't be 0 (we checked for
// equality above) and NaN is falsy.
if (!result) {
result = aPart > bPart ? 1 : -1;
}
// At this point we know enough to be able to sort the two
// strings, so we don't need to compare any more parts.
break;
}
}
// If we get here and `result` is still 0, then sort the shorter string
// before the longer string.
result || (result = a.length - b.length);
// Return the result, flipping the order if `options.descending` is
// truthy.
return options && options.descending ? -result : result;
},
// -- Protected Methods ----------------------------------------------------
/**
Splits a string into an array of alpha character and digit character parts.
@example
Y.ArraySort._splitAlphaNum('abc123def456');
// => ['abc', '123', 'def', '456']
@method _splitAlphaNum
@param {String} string String to split.
@return {String[]} Array of alpha parts and digit parts.
@protected
@static
@since 3.11.0
**/
_splitAlphaNum: function (string) {
/*jshint boss:true */
var parts = [],
regex = /(\d+|\D+)/g,
match;
while (match = regex.exec(string)) { // assignment
parts.push(match[1]);
}
return parts;
}
};
}, '3.18.1', {"requires": ["yui-base"]});
@@ -0,0 +1,554 @@
YUI.add('async-queue', function (Y, NAME) {
/**
* <p>AsyncQueue allows you create a chain of function callbacks executed
* via setTimeout (or synchronously) that are guaranteed to run in order.
* Items in the queue can be promoted or removed. Start or resume the
* execution chain with run(). pause() to temporarily delay execution, or
* stop() to halt and clear the queue.</p>
*
* @module async-queue
*/
/**
* <p>A specialized queue class that supports scheduling callbacks to execute
* sequentially, iteratively, even asynchronously.</p>
*
* <p>Callbacks can be function refs or objects with the following keys. Only
* the <code>fn</code> key is required.</p>
*
* <ul>
* <li><code>fn</code> -- The callback function</li>
* <li><code>context</code> -- The execution context for the callbackFn.</li>
* <li><code>args</code> -- Arguments to pass to callbackFn.</li>
* <li><code>timeout</code> -- Millisecond delay before executing callbackFn.
* (Applies to each iterative execution of callback)</li>
* <li><code>iterations</code> -- Number of times to repeat the callback.
* <li><code>until</code> -- Repeat the callback until this function returns
* true. This setting trumps iterations.</li>
* <li><code>autoContinue</code> -- Set to false to prevent the AsyncQueue from
* executing the next callback in the Queue after
* the callback completes.</li>
* <li><code>id</code> -- Name that can be used to get, promote, get the
* indexOf, or delete this callback.</li>
* </ul>
*
* @class AsyncQueue
* @extends EventTarget
* @constructor
* @param callback* {Function|Object} 0..n callbacks to seed the queue
*/
Y.AsyncQueue = function() {
this._init();
this.add.apply(this, arguments);
};
var Queue = Y.AsyncQueue,
EXECUTE = 'execute',
SHIFT = 'shift',
PROMOTE = 'promote',
REMOVE = 'remove',
isObject = Y.Lang.isObject,
isFunction = Y.Lang.isFunction;
/**
* <p>Static default values used to populate callback configuration properties.
* Preconfigured defaults include:</p>
*
* <ul>
* <li><code>autoContinue</code>: <code>true</code></li>
* <li><code>iterations</code>: 1</li>
* <li><code>timeout</code>: 10 (10ms between callbacks)</li>
* <li><code>until</code>: (function to run until iterations &lt;= 0)</li>
* </ul>
*
* @property 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, { prefix: 'queue', emitFacade: true });
this._q = [];
/**
* Callback defaults for this instance. Static defaults that are not
* overridden are also included.
*
* @property defaults
* @type {Object}
*/
this.defaults = {};
this._initEvents();
},
/**
* Initializes the instance events.
*
* @method _initEvents
* @protected
*/
_initEvents : function () {
this.publish({
'execute' : { defaultFn : this._defExecFn, emitFacade: true },
'shift' : { defaultFn : this._defShiftFn, emitFacade: true },
'add' : { defaultFn : this._defAddFn, emitFacade: true },
'promote' : { defaultFn : this._defPromoteFn, emitFacade: true },
'remove' : { defaultFn : this._defRemoveFn, emitFacade: true }
});
},
/**
* Returns the next callback needing execution. If a callback is
* configured to repeat via iterations or until, it will be returned until
* the completion criteria is met.
*
* When the queue is empty, null is returned.
*
* @method next
* @return {Function} the callback to execute
*/
next : function () {
var callback;
while (this._q.length) {
callback = this._q[0] = this._prepare(this._q[0]);
if (callback && callback.until()) {
this.fire(SHIFT, { callback: callback });
callback = null;
} else {
break;
}
}
return callback || null;
},
/**
* Default functionality for the &quot;shift&quot; event. Shifts the
* callback stored in the event object's <em>callback</em> property from
* the queue if it is the first item.
*
* @method _defShiftFn
* @param e {Event} The event object
* @protected
*/
_defShiftFn : function (e) {
if (this.indexOf(e.callback) === 0) {
this._q.shift();
}
},
/**
* Creates a wrapper function to execute the callback using the aggregated
* configuration generated by combining the static AsyncQueue.defaults, the
* instance defaults, and the specified callback settings.
*
* The wrapper function is decorated with the callback configuration as
* properties for runtime modification.
*
* @method _prepare
* @param callback {Object|Function} the raw callback
* @return {Function} a decorated function wrapper to execute the callback
* @protected
*/
_prepare: function (callback) {
if (isFunction(callback) && callback._prepared) {
return callback;
}
var config = Y.merge(
Queue.defaults,
{ context : this, args: [], _prepared: true },
this.defaults,
(isFunction(callback) ? { fn: callback } : callback)),
wrapper = Y.bind(function () {
if (!wrapper._running) {
wrapper.iterations--;
}
if (isFunction(wrapper.fn)) {
wrapper.fn.apply(wrapper.context || Y,
Y.Array(wrapper.args));
}
}, this);
return Y.mix(wrapper, config);
},
/**
* Sets the queue in motion. All queued callbacks will be executed in
* order unless pause() or stop() is called or if one of the callbacks is
* configured with autoContinue: false.
*
* @method run
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
run : function () {
var callback,
cont = true;
if (this._executing) {
this._running = true;
return this;
}
for (callback = this.next();
callback && !this.isRunning();
callback = this.next())
{
cont = (callback.timeout < 0) ?
this._execute(callback) :
this._schedule(callback);
// Break to avoid an extra call to next (final-expression of the
// 'for' loop), because the until function of the next callback
// in the queue may return a wrong result if it depends on the
// not-yet-finished work of the previous callback.
if (!cont) {
break;
}
}
if (!callback) {
/**
* Event fired when there is no remaining callback in the running queue. Also fired after stop().
* @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;
this._executing = callback;
callback.iterations--;
this.fire(EXECUTE, { callback: callback });
var cont = this._running && callback.autoContinue;
this._running = callback._running = false;
this._executing = false;
return cont;
},
/**
* Schedules the execution of asynchronous callbacks.
*
* @method _schedule
* @param callback {Object} the callback object to execute
* @return {Boolean} whether the run loop should continue
* @protected
*/
_schedule : function (callback) {
this._running = Y.later(callback.timeout, this, function () {
if (this._execute(callback)) {
this.run();
}
});
return false;
},
/**
* Determines if the queue is waiting for a callback to complete execution.
*
* @method isRunning
* @return {Boolean} true if queue is waiting for a
* from any initiated transactions
*/
isRunning : function () {
return !!this._running;
},
/**
* Default functionality for the &quot;execute&quot; event. Executes the
* callback function
*
* @method _defExecFn
* @param e {Event} the event object
* @protected
*/
_defExecFn : function (e) {
e.callback();
},
/**
* Add any number of callbacks to the end of the queue. Callbacks may be
* provided as functions or objects.
*
* @method add
* @param callback* {Function|Object} 0..n callbacks
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
add : function () {
this.fire('add', { callbacks: Y.Array(arguments,0,true) });
return this;
},
/**
* Default functionality for the &quot;add&quot; event. Adds the callbacks
* in the event facade to the queue. Callbacks successfully added to the
* queue are present in the event's <code>added</code> property in the
* after phase.
*
* @method _defAddFn
* @param e {Event} the event object
* @protected
*/
_defAddFn : function(e) {
var _q = this._q,
added = [];
Y.Array.each(e.callbacks, function (c) {
if (isObject(c)) {
_q.push(c);
added.push(c);
}
});
e.added = added;
},
/**
* Pause the execution of the queue after the execution of the current
* callback completes. If called from code outside of a queued callback,
* clears the timeout for the pending callback. Paused queue can be
* restarted with q.run()
*
* @method pause
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
pause: function () {
if (this._running && 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 = [];
if (this._running && isObject(this._running)) {
this._running.cancel();
this._running = false;
}
// otherwise don't systematically set this._running to false, because if
// stop has been called from inside a queued callback, the _execute method
// currenty running needs to call run() one more time for the 'complete'
// event to be fired.
// if stop is called from outside a callback, we need to explicitely call
// run() once again to fire the 'complete' event.
if (!this._executing) {
this.run();
}
return this;
},
/**
* Returns the current index of a callback. Pass in either the id or
* callback function from getCallback.
*
* @method indexOf
* @param callback {String|Function} the callback or its specified id
* @return {Number} index of the callback or -1 if not found
*/
indexOf : function (callback) {
var i = 0, len = this._q.length, c;
for (; i < len; ++i) {
c = this._q[i];
if (c === callback || c.id === callback) {
return i;
}
}
return -1;
},
/**
* Retrieve a callback by its id. Useful to modify the configuration
* while the queue is running.
*
* @method getCallback
* @param id {String} the id assigned to the callback
* @return {Object} the callback object
*/
getCallback : function (id) {
var i = this.indexOf(id);
return (i > -1) ? this._q[i] : null;
},
/**
* Promotes the named callback to the top of the queue. If a callback is
* currently executing or looping (via until or iterations), the promotion
* is scheduled to occur after the current callback has completed.
*
* @method promote
* @param callback {String|Object} the callback object or a callback's id
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
promote : function (callback) {
var payload = { callback : callback },e;
if (this.isRunning()) {
e = this.after(SHIFT, function () {
this.fire(PROMOTE, payload);
e.detach();
}, this);
} else {
this.fire(PROMOTE, payload);
}
return this;
},
/**
* <p>Default functionality for the &quot;promote&quot; event. Promotes the
* named callback to the head of the queue.</p>
*
* <p>The event object will contain a property &quot;callback&quot;, which
* holds the id of a callback or the callback object itself.</p>
*
* @method _defPromoteFn
* @param e {Event} the custom event
* @protected
*/
_defPromoteFn : function (e) {
var i = this.indexOf(e.callback),
promoted = (i > -1) ? this._q.splice(i,1)[0] : null;
e.promoted = promoted;
if (promoted) {
this._q.unshift(promoted);
}
},
/**
* Removes the callback from the queue. If the queue is active, the
* removal is scheduled to occur after the current callback has completed.
*
* @method remove
* @param callback {String|Object} the callback object or a callback's id
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
remove : function (callback) {
var payload = { callback : callback },e;
// Can't return the removed callback because of the deferral until
// current callback is complete
if (this.isRunning()) {
e = this.after(SHIFT, function () {
this.fire(REMOVE, payload);
e.detach();
},this);
} else {
this.fire(REMOVE, payload);
}
return this;
},
/**
* <p>Default functionality for the &quot;remove&quot; event. Removes the
* callback from the queue.</p>
*
* <p>The event object will contain a property &quot;callback&quot;, which
* holds the id of a callback or the callback object itself.</p>
*
* @method _defRemoveFn
* @param e {Event} the custom event
* @protected
*/
_defRemoveFn : function (e) {
var i = this.indexOf(e.callback);
e.removed = (i > -1) ? this._q.splice(i,1)[0] : null;
},
/**
* Returns the number of callbacks in the queue.
*
* @method size
* @return {Number}
*/
size : function () {
// next() flushes callbacks that have met their until() criteria and
// therefore shouldn't count since they wouldn't execute anyway.
if (!this.isRunning()) {
this.next();
}
return this._q.length;
}
});
}, '3.18.1', {"requires": ["event-custom"]});
+1
View File
@@ -0,0 +1 @@
YUI.add("async-queue",function(e,t){e.AsyncQueue=function(){this._init(),this.add.apply(this,arguments)};var n=e.AsyncQueue,r="execute",i="shift",s="promote",o="remove",u=e.Lang.isObject,a=e.Lang.isFunction;n.defaults=e.mix({autoContinue:!0,iterations:1,timeout:10,until:function(){return this.iterations|=0,this.iterations<=0}},e.config.queueDefaults||{}),e.extend(n,e.EventTarget,{_running:!1,_init:function(){e.EventTarget.call(this,{prefix:"queue",emitFacade:!0}),this._q=[],this.defaults={},this._initEvents()},_initEvents:function(){this.publish({execute:{defaultFn:this._defExecFn,emitFacade:!0},shift:{defaultFn:this._defShiftFn,emitFacade:!0},add:{defaultFn:this._defAddFn,emitFacade:!0},promote:{defaultFn:this._defPromoteFn,emitFacade:!0},remove:{defaultFn:this._defRemoveFn,emitFacade:!0}})},next:function(){var e;while(this._q.length){e=this._q[0]=this._prepare(this._q[0]);if(!e||!e.until())break;this.fire(i,{callback:e}),e=null}return e||null},_defShiftFn:function(e){this.indexOf(e.callback)===0&&this._q.shift()},_prepare:function(t){if(a(t)&&t._prepared)return t;var r=e.merge(n.defaults,{context:this,args:[],_prepared:!0},this.defaults,a(t)?{fn:t}:t),i=e.bind(function(){i._running||i.iterations--,a(i.fn)&&i.fn.apply(i.context||e,e.Array(i.args))},this);return e.mix(i,r)},run:function(){var e,t=!0;if(this._executing)return this._running=!0,this;for(e=this.next();e&&!this.isRunning();e=this.next()){t=e.timeout<0?this._execute(e):this._schedule(e);if(!t)break}return e||this.fire("complete"),this},_execute:function(e){this._running=e._running=!0,this._executing=e,e.iterations--,this.fire(r,{callback:e});var t=this._running&&e.autoContinue;return this._running=e._running=!1,this._executing=!1,t},_schedule:function(t){return this._running=e.later(t.timeout,this,function(){this._execute(t)&&this.run()}),!1},isRunning:function(){return!!this._running},_defExecFn:function(e){e.callback()},add:function(){return this.fire("add",{callbacks:e.Array(arguments,0,!0)}),this},_defAddFn:function(t){var n=this._q,r=[];e.Array.each(t.callbacks,function(e){u(e)&&(n.push(e),r.push(e))}),t.added=r},pause:function(){return this._running&&u(this._running)&&this._running.cancel(),this._running=!1,this},stop:function(){return this._q=[],this._running&&u(this._running)&&(this._running.cancel(),this._running=!1),this._executing||this.run(),this},indexOf:function(e){var t=0,n=this._q.length,r;for(;t<n;++t){r=this._q[t];if(r===e||r.id===e)return t}return-1},getCallback:function(e){var t=this.indexOf(e);return t>-1?this._q[t]:null},promote:function(e){var t={callback:e},n;return this.isRunning()?n=this.after(i,function(){this.fire(s,t),n.detach()},this):this.fire(s,t),this},_defPromoteFn:function(e){var t=this.indexOf(e.callback),n=t>-1?this._q.splice(t,1)[0]:null;e.promoted=n,n&&this._q.unshift(n)},remove:function(e){var t={callback:e},n;return this.isRunning()?n=this.after(i,function(){this.fire(o,t),n.detach()},this):this.fire(o,t),this},_defRemoveFn:function(e){var t=this.indexOf(e.callback);e.removed=t>-1?this._q.splice(t,1)[0]:null},size:function(){return this.isRunning()||this.next(),this._q.length}})},"3.18.1",{requires:["event-custom"]});
@@ -0,0 +1,554 @@
YUI.add('async-queue', function (Y, NAME) {
/**
* <p>AsyncQueue allows you create a chain of function callbacks executed
* via setTimeout (or synchronously) that are guaranteed to run in order.
* Items in the queue can be promoted or removed. Start or resume the
* execution chain with run(). pause() to temporarily delay execution, or
* stop() to halt and clear the queue.</p>
*
* @module async-queue
*/
/**
* <p>A specialized queue class that supports scheduling callbacks to execute
* sequentially, iteratively, even asynchronously.</p>
*
* <p>Callbacks can be function refs or objects with the following keys. Only
* the <code>fn</code> key is required.</p>
*
* <ul>
* <li><code>fn</code> -- The callback function</li>
* <li><code>context</code> -- The execution context for the callbackFn.</li>
* <li><code>args</code> -- Arguments to pass to callbackFn.</li>
* <li><code>timeout</code> -- Millisecond delay before executing callbackFn.
* (Applies to each iterative execution of callback)</li>
* <li><code>iterations</code> -- Number of times to repeat the callback.
* <li><code>until</code> -- Repeat the callback until this function returns
* true. This setting trumps iterations.</li>
* <li><code>autoContinue</code> -- Set to false to prevent the AsyncQueue from
* executing the next callback in the Queue after
* the callback completes.</li>
* <li><code>id</code> -- Name that can be used to get, promote, get the
* indexOf, or delete this callback.</li>
* </ul>
*
* @class AsyncQueue
* @extends EventTarget
* @constructor
* @param callback* {Function|Object} 0..n callbacks to seed the queue
*/
Y.AsyncQueue = function() {
this._init();
this.add.apply(this, arguments);
};
var Queue = Y.AsyncQueue,
EXECUTE = 'execute',
SHIFT = 'shift',
PROMOTE = 'promote',
REMOVE = 'remove',
isObject = Y.Lang.isObject,
isFunction = Y.Lang.isFunction;
/**
* <p>Static default values used to populate callback configuration properties.
* Preconfigured defaults include:</p>
*
* <ul>
* <li><code>autoContinue</code>: <code>true</code></li>
* <li><code>iterations</code>: 1</li>
* <li><code>timeout</code>: 10 (10ms between callbacks)</li>
* <li><code>until</code>: (function to run until iterations &lt;= 0)</li>
* </ul>
*
* @property 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, { prefix: 'queue', emitFacade: true });
this._q = [];
/**
* Callback defaults for this instance. Static defaults that are not
* overridden are also included.
*
* @property defaults
* @type {Object}
*/
this.defaults = {};
this._initEvents();
},
/**
* Initializes the instance events.
*
* @method _initEvents
* @protected
*/
_initEvents : function () {
this.publish({
'execute' : { defaultFn : this._defExecFn, emitFacade: true },
'shift' : { defaultFn : this._defShiftFn, emitFacade: true },
'add' : { defaultFn : this._defAddFn, emitFacade: true },
'promote' : { defaultFn : this._defPromoteFn, emitFacade: true },
'remove' : { defaultFn : this._defRemoveFn, emitFacade: true }
});
},
/**
* Returns the next callback needing execution. If a callback is
* configured to repeat via iterations or until, it will be returned until
* the completion criteria is met.
*
* When the queue is empty, null is returned.
*
* @method next
* @return {Function} the callback to execute
*/
next : function () {
var callback;
while (this._q.length) {
callback = this._q[0] = this._prepare(this._q[0]);
if (callback && callback.until()) {
this.fire(SHIFT, { callback: callback });
callback = null;
} else {
break;
}
}
return callback || null;
},
/**
* Default functionality for the &quot;shift&quot; event. Shifts the
* callback stored in the event object's <em>callback</em> property from
* the queue if it is the first item.
*
* @method _defShiftFn
* @param e {Event} The event object
* @protected
*/
_defShiftFn : function (e) {
if (this.indexOf(e.callback) === 0) {
this._q.shift();
}
},
/**
* Creates a wrapper function to execute the callback using the aggregated
* configuration generated by combining the static AsyncQueue.defaults, the
* instance defaults, and the specified callback settings.
*
* The wrapper function is decorated with the callback configuration as
* properties for runtime modification.
*
* @method _prepare
* @param callback {Object|Function} the raw callback
* @return {Function} a decorated function wrapper to execute the callback
* @protected
*/
_prepare: function (callback) {
if (isFunction(callback) && callback._prepared) {
return callback;
}
var config = Y.merge(
Queue.defaults,
{ context : this, args: [], _prepared: true },
this.defaults,
(isFunction(callback) ? { fn: callback } : callback)),
wrapper = Y.bind(function () {
if (!wrapper._running) {
wrapper.iterations--;
}
if (isFunction(wrapper.fn)) {
wrapper.fn.apply(wrapper.context || Y,
Y.Array(wrapper.args));
}
}, this);
return Y.mix(wrapper, config);
},
/**
* Sets the queue in motion. All queued callbacks will be executed in
* order unless pause() or stop() is called or if one of the callbacks is
* configured with autoContinue: false.
*
* @method run
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
run : function () {
var callback,
cont = true;
if (this._executing) {
this._running = true;
return this;
}
for (callback = this.next();
callback && !this.isRunning();
callback = this.next())
{
cont = (callback.timeout < 0) ?
this._execute(callback) :
this._schedule(callback);
// Break to avoid an extra call to next (final-expression of the
// 'for' loop), because the until function of the next callback
// in the queue may return a wrong result if it depends on the
// not-yet-finished work of the previous callback.
if (!cont) {
break;
}
}
if (!callback) {
/**
* Event fired when there is no remaining callback in the running queue. Also fired after stop().
* @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;
this._executing = callback;
callback.iterations--;
this.fire(EXECUTE, { callback: callback });
var cont = this._running && callback.autoContinue;
this._running = callback._running = false;
this._executing = false;
return cont;
},
/**
* Schedules the execution of asynchronous callbacks.
*
* @method _schedule
* @param callback {Object} the callback object to execute
* @return {Boolean} whether the run loop should continue
* @protected
*/
_schedule : function (callback) {
this._running = Y.later(callback.timeout, this, function () {
if (this._execute(callback)) {
this.run();
}
});
return false;
},
/**
* Determines if the queue is waiting for a callback to complete execution.
*
* @method isRunning
* @return {Boolean} true if queue is waiting for a
* from any initiated transactions
*/
isRunning : function () {
return !!this._running;
},
/**
* Default functionality for the &quot;execute&quot; event. Executes the
* callback function
*
* @method _defExecFn
* @param e {Event} the event object
* @protected
*/
_defExecFn : function (e) {
e.callback();
},
/**
* Add any number of callbacks to the end of the queue. Callbacks may be
* provided as functions or objects.
*
* @method add
* @param callback* {Function|Object} 0..n callbacks
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
add : function () {
this.fire('add', { callbacks: Y.Array(arguments,0,true) });
return this;
},
/**
* Default functionality for the &quot;add&quot; event. Adds the callbacks
* in the event facade to the queue. Callbacks successfully added to the
* queue are present in the event's <code>added</code> property in the
* after phase.
*
* @method _defAddFn
* @param e {Event} the event object
* @protected
*/
_defAddFn : function(e) {
var _q = this._q,
added = [];
Y.Array.each(e.callbacks, function (c) {
if (isObject(c)) {
_q.push(c);
added.push(c);
}
});
e.added = added;
},
/**
* Pause the execution of the queue after the execution of the current
* callback completes. If called from code outside of a queued callback,
* clears the timeout for the pending callback. Paused queue can be
* restarted with q.run()
*
* @method pause
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
pause: function () {
if (this._running && 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 = [];
if (this._running && isObject(this._running)) {
this._running.cancel();
this._running = false;
}
// otherwise don't systematically set this._running to false, because if
// stop has been called from inside a queued callback, the _execute method
// currenty running needs to call run() one more time for the 'complete'
// event to be fired.
// if stop is called from outside a callback, we need to explicitely call
// run() once again to fire the 'complete' event.
if (!this._executing) {
this.run();
}
return this;
},
/**
* Returns the current index of a callback. Pass in either the id or
* callback function from getCallback.
*
* @method indexOf
* @param callback {String|Function} the callback or its specified id
* @return {Number} index of the callback or -1 if not found
*/
indexOf : function (callback) {
var i = 0, len = this._q.length, c;
for (; i < len; ++i) {
c = this._q[i];
if (c === callback || c.id === callback) {
return i;
}
}
return -1;
},
/**
* Retrieve a callback by its id. Useful to modify the configuration
* while the queue is running.
*
* @method getCallback
* @param id {String} the id assigned to the callback
* @return {Object} the callback object
*/
getCallback : function (id) {
var i = this.indexOf(id);
return (i > -1) ? this._q[i] : null;
},
/**
* Promotes the named callback to the top of the queue. If a callback is
* currently executing or looping (via until or iterations), the promotion
* is scheduled to occur after the current callback has completed.
*
* @method promote
* @param callback {String|Object} the callback object or a callback's id
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
promote : function (callback) {
var payload = { callback : callback },e;
if (this.isRunning()) {
e = this.after(SHIFT, function () {
this.fire(PROMOTE, payload);
e.detach();
}, this);
} else {
this.fire(PROMOTE, payload);
}
return this;
},
/**
* <p>Default functionality for the &quot;promote&quot; event. Promotes the
* named callback to the head of the queue.</p>
*
* <p>The event object will contain a property &quot;callback&quot;, which
* holds the id of a callback or the callback object itself.</p>
*
* @method _defPromoteFn
* @param e {Event} the custom event
* @protected
*/
_defPromoteFn : function (e) {
var i = this.indexOf(e.callback),
promoted = (i > -1) ? this._q.splice(i,1)[0] : null;
e.promoted = promoted;
if (promoted) {
this._q.unshift(promoted);
}
},
/**
* Removes the callback from the queue. If the queue is active, the
* removal is scheduled to occur after the current callback has completed.
*
* @method remove
* @param callback {String|Object} the callback object or a callback's id
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
remove : function (callback) {
var payload = { callback : callback },e;
// Can't return the removed callback because of the deferral until
// current callback is complete
if (this.isRunning()) {
e = this.after(SHIFT, function () {
this.fire(REMOVE, payload);
e.detach();
},this);
} else {
this.fire(REMOVE, payload);
}
return this;
},
/**
* <p>Default functionality for the &quot;remove&quot; event. Removes the
* callback from the queue.</p>
*
* <p>The event object will contain a property &quot;callback&quot;, which
* holds the id of a callback or the callback object itself.</p>
*
* @method _defRemoveFn
* @param e {Event} the custom event
* @protected
*/
_defRemoveFn : function (e) {
var i = this.indexOf(e.callback);
e.removed = (i > -1) ? this._q.splice(i,1)[0] : null;
},
/**
* Returns the number of callbacks in the queue.
*
* @method size
* @return {Number}
*/
size : function () {
// next() flushes callbacks that have met their until() criteria and
// therefore shouldn't count since they wouldn't execute anyway.
if (!this.isRunning()) {
this.next();
}
return this._q.length;
}
});
}, '3.18.1', {"requires": ["event-custom"]});
@@ -0,0 +1,110 @@
YUI.add('attribute-base', function (Y, NAME) {
/**
* The attribute module provides an augmentable Attribute implementation, which
* adds configurable attributes and attribute change events to the class being
* augmented. It also provides a State class, which is used internally by Attribute,
* but can also be used independently to provide a name/property/value data structure to
* store state.
*
* @module attribute
*/
/**
* The attribute-base submodule provides core attribute handling support, with everything
* aside from complex attribute handling in the provider's constructor.
*
* @module attribute
* @submodule attribute-base
*/
/**
* <p>
* Attribute provides configurable attribute support along with attribute change events. It is designed to be
* augmented on to a host class, and provides the host with the ability to configure attributes to store and retrieve state,
* along with attribute change events.
* </p>
* <p>For example, attributes added to the host can be configured:</p>
* <ul>
* <li>As read only.</li>
* <li>As write once.</li>
* <li>With a setter function, which can be used to manipulate
* values passed to Attribute's <a href="#method_set">set</a> method, before they are stored.</li>
* <li>With a getter function, which can be used to manipulate stored values,
* before they are returned by Attribute's <a href="#method_get">get</a> method.</li>
* <li>With a validator function, to validate values before they are stored.</li>
* </ul>
*
* <p>See the <a href="#method_addAttr">addAttr</a> method, for the complete set of configuration
* options available for attributes.</p>
*
* <p><strong>NOTE:</strong> Most implementations will be better off extending the <a href="Base.html">Base</a> class,
* instead of augmenting Attribute directly. Base augments Attribute and will handle the initial configuration
* of attributes for derived classes, accounting for values passed into the constructor.</p>
*
* @class Attribute
* @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>).
* These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor.
* @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>).
* These are not merged/cloned. The caller is responsible for isolating user provided values if required.
* @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>).
* @uses AttributeCore
* @uses AttributeObservable
* @uses EventTarget
* @uses AttributeExtras
*/
function Attribute() {
Y.AttributeCore.apply(this, arguments);
Y.AttributeObservable.apply(this, arguments);
Y.AttributeExtras.apply(this, arguments);
}
Y.mix(Attribute, Y.AttributeCore, false, null, 1);
Y.mix(Attribute, Y.AttributeExtras, false, null, 1);
// Needs to be `true`, to overwrite methods from AttributeCore
Y.mix(Attribute, Y.AttributeObservable, true, null, 1);
/**
* <p>The value to return from an attribute setter in order to prevent the set from going through.</p>
*
* <p>You can return this value from your setter if you wish to combine validator and setter
* functionality into a single setter function, which either returns the massaged value to be stored or
* AttributeCore.INVALID_VALUE to prevent invalid values from being stored.</p>
*
* @property INVALID_VALUE
* @type Object
* @static
* @final
*/
Attribute.INVALID_VALUE = Y.AttributeCore.INVALID_VALUE;
/**
* The list of properties which can be configured for
* each attribute (e.g. setter, getter, writeOnce etc.).
*
* This property is used internally as a whitelist for faster
* Y.mix operations.
*
* @property _ATTR_CFG
* @type Array
* @static
* @protected
*/
Attribute._ATTR_CFG = Y.AttributeCore._ATTR_CFG.concat(Y.AttributeObservable._ATTR_CFG);
/**
* Utility method to protect an attribute configuration hash, by merging the
* entire object and the individual attr config objects.
*
* @method protectAttrs
* @static
* @param {Object} attrs A hash of attribute to configuration object pairs.
* @return {Object} A protected version of the `attrs` argument.
*/
Attribute.protectAttrs = Y.AttributeCore.protectAttrs;
Y.Attribute = Attribute;
}, '3.18.1', {"requires": ["attribute-core", "attribute-observable", "attribute-extras"]});
@@ -0,0 +1 @@
YUI.add("attribute-base",function(e,t){function n(){e.AttributeCore.apply(this,arguments),e.AttributeObservable.apply(this,arguments),e.AttributeExtras.apply(this,arguments)}e.mix(n,e.AttributeCore,!1,null,1),e.mix(n,e.AttributeExtras,!1,null,1),e.mix(n,e.AttributeObservable,!0,null,1),n.INVALID_VALUE=e.AttributeCore.INVALID_VALUE,n._ATTR_CFG=e.AttributeCore._ATTR_CFG.concat(e.AttributeObservable._ATTR_CFG),n.protectAttrs=e.AttributeCore.protectAttrs,e.Attribute=n},"3.18.1",{requires:["attribute-core","attribute-observable","attribute-extras"]});
@@ -0,0 +1,110 @@
YUI.add('attribute-base', function (Y, NAME) {
/**
* The attribute module provides an augmentable Attribute implementation, which
* adds configurable attributes and attribute change events to the class being
* augmented. It also provides a State class, which is used internally by Attribute,
* but can also be used independently to provide a name/property/value data structure to
* store state.
*
* @module attribute
*/
/**
* The attribute-base submodule provides core attribute handling support, with everything
* aside from complex attribute handling in the provider's constructor.
*
* @module attribute
* @submodule attribute-base
*/
/**
* <p>
* Attribute provides configurable attribute support along with attribute change events. It is designed to be
* augmented on to a host class, and provides the host with the ability to configure attributes to store and retrieve state,
* along with attribute change events.
* </p>
* <p>For example, attributes added to the host can be configured:</p>
* <ul>
* <li>As read only.</li>
* <li>As write once.</li>
* <li>With a setter function, which can be used to manipulate
* values passed to Attribute's <a href="#method_set">set</a> method, before they are stored.</li>
* <li>With a getter function, which can be used to manipulate stored values,
* before they are returned by Attribute's <a href="#method_get">get</a> method.</li>
* <li>With a validator function, to validate values before they are stored.</li>
* </ul>
*
* <p>See the <a href="#method_addAttr">addAttr</a> method, for the complete set of configuration
* options available for attributes.</p>
*
* <p><strong>NOTE:</strong> Most implementations will be better off extending the <a href="Base.html">Base</a> class,
* instead of augmenting Attribute directly. Base augments Attribute and will handle the initial configuration
* of attributes for derived classes, accounting for values passed into the constructor.</p>
*
* @class Attribute
* @param attrs {Object} The attributes to add during construction (passed through to <a href="#method_addAttrs">addAttrs</a>).
* These can also be defined on the constructor being augmented with Attribute by defining the ATTRS property on the constructor.
* @param values {Object} The initial attribute values to apply (passed through to <a href="#method_addAttrs">addAttrs</a>).
* These are not merged/cloned. The caller is responsible for isolating user provided values if required.
* @param lazy {boolean} Whether or not to add attributes lazily (passed through to <a href="#method_addAttrs">addAttrs</a>).
* @uses AttributeCore
* @uses AttributeObservable
* @uses EventTarget
* @uses AttributeExtras
*/
function Attribute() {
Y.AttributeCore.apply(this, arguments);
Y.AttributeObservable.apply(this, arguments);
Y.AttributeExtras.apply(this, arguments);
}
Y.mix(Attribute, Y.AttributeCore, false, null, 1);
Y.mix(Attribute, Y.AttributeExtras, false, null, 1);
// Needs to be `true`, to overwrite methods from AttributeCore
Y.mix(Attribute, Y.AttributeObservable, true, null, 1);
/**
* <p>The value to return from an attribute setter in order to prevent the set from going through.</p>
*
* <p>You can return this value from your setter if you wish to combine validator and setter
* functionality into a single setter function, which either returns the massaged value to be stored or
* AttributeCore.INVALID_VALUE to prevent invalid values from being stored.</p>
*
* @property INVALID_VALUE
* @type Object
* @static
* @final
*/
Attribute.INVALID_VALUE = Y.AttributeCore.INVALID_VALUE;
/**
* The list of properties which can be configured for
* each attribute (e.g. setter, getter, writeOnce etc.).
*
* This property is used internally as a whitelist for faster
* Y.mix operations.
*
* @property _ATTR_CFG
* @type Array
* @static
* @protected
*/
Attribute._ATTR_CFG = Y.AttributeCore._ATTR_CFG.concat(Y.AttributeObservable._ATTR_CFG);
/**
* Utility method to protect an attribute configuration hash, by merging the
* entire object and the individual attr config objects.
*
* @method protectAttrs
* @static
* @param {Object} attrs A hash of attribute to configuration object pairs.
* @return {Object} A protected version of the `attrs` argument.
*/
Attribute.protectAttrs = Y.AttributeCore.protectAttrs;
Y.Attribute = Attribute;
}, '3.18.1', {"requires": ["attribute-core", "attribute-observable", "attribute-extras"]});
@@ -0,0 +1,56 @@
YUI.add('attribute-complex', function (Y, NAME) {
/**
* Adds support for attribute providers to handle complex attributes in the constructor
*
* @module attribute
* @submodule attribute-complex
* @for Attribute
* @deprecated AttributeComplex's overrides are now part of AttributeCore.
*/
var Attribute = Y.Attribute;
Attribute.Complex = function() {};
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 : Attribute.prototype._normAttrVals,
/**
* 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 : Attribute.prototype._getAttrInitVal
};
// Consistency with the rest of the Attribute addons for now.
Y.AttributeComplex = Attribute.Complex;
}, '3.18.1', {"requires": ["attribute-base"]});
@@ -0,0 +1 @@
YUI.add("attribute-complex",function(e,t){var n=e.Attribute;n.Complex=function(){},n.Complex.prototype={_normAttrVals:n.prototype._normAttrVals,_getAttrInitVal:n.prototype._getAttrInitVal},e.AttributeComplex=n.Complex},"3.18.1",{requires:["attribute-base"]});
@@ -0,0 +1,56 @@
YUI.add('attribute-complex', function (Y, NAME) {
/**
* Adds support for attribute providers to handle complex attributes in the constructor
*
* @module attribute
* @submodule attribute-complex
* @for Attribute
* @deprecated AttributeComplex's overrides are now part of AttributeCore.
*/
var Attribute = Y.Attribute;
Attribute.Complex = function() {};
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 : Attribute.prototype._normAttrVals,
/**
* 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 : Attribute.prototype._getAttrInitVal
};
// Consistency with the rest of the Attribute addons for now.
Y.AttributeComplex = Attribute.Complex;
}, '3.18.1', {"requires": ["attribute-base"]});
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,157 @@
YUI.add('attribute-extras', function (Y, NAME) {
/**
* The attribute module provides an augmentable Attribute implementation, which
* adds configurable attributes and attribute change events to the class being
* augmented. It also provides a State class, which is used internally by Attribute,
* but can also be used independently to provide a name/property/value data structure to
* store state.
*
* @module attribute
*/
/**
* The attribute-extras submodule provides less commonly used attribute methods, and can
* be augmented/mixed into an implemention which used attribute-core.
*
* @module attribute
* @submodule attribute-extras
*/
var BROADCAST = "broadcast",
PUBLISHED = "published",
INIT_VALUE = "initValue",
MODIFIABLE = {
readOnly:1,
writeOnce:1,
getter:1,
broadcast:1
};
/**
* A augmentable implementation for AttributeCore, providing less frequently used
* methods for Attribute management such as modifyAttrs(), removeAttr and reset()
*
* @class AttributeExtras
* @extensionfor AttributeCore
*/
function AttributeExtras() {}
AttributeExtras.prototype = {
/**
* Updates the configuration of an attribute which has already been added.
* <p>
* The properties which can be modified through this interface are limited
* to the following subset of attributes, which can be safely modified
* after a value has already been set on the attribute:
* </p>
* <dl>
* <dt>readOnly;</dt>
* <dt>writeOnce;</dt>
* <dt>broadcast; and</dt>
* <dt>getter.</dt>
* </dl>
* <p>
* Note: New attributes cannot be added using this interface. New attributes must be
* added using {{#crossLink "AttributeCore/addAttr:method"}}addAttr{{/crossLink}}, or an
* appropriate manner for a class which utilises Attributes (e.g. the
* {{#crossLink "Base/ATTRS:property"}}ATTRS{{/crossLink}} property in
* {{#crossLink "Base"}}Base{{/crossLink}}).
* </p>
* @method modifyAttr
* @param {String} name The name of the attribute whose configuration is to be updated.
* @param {Object} config An object with configuration property/value pairs, specifying the configuration properties to modify.
*/
modifyAttr: function(name, config) {
var host = this, // help compression
prop, state;
if (host.attrAdded(name)) {
if (host._isLazyAttr(name)) {
host._addLazyAttr(name);
}
state = host._state;
for (prop in config) {
if (MODIFIABLE[prop] && config.hasOwnProperty(prop)) {
state.add(name, prop, config[prop]);
// If we reconfigured broadcast, need to republish
if (prop === BROADCAST) {
state.remove(name, PUBLISHED);
}
}
}
} else {
Y.log('Attribute modifyAttr:' + name + ' has not been added. Use addAttr to add the attribute', 'warn', 'attribute');
}
},
/**
* Removes an attribute from the host object
*
* @method removeAttr
* @param {String} name The name of the attribute to be removed.
*/
removeAttr: function(name) {
this._state.removeAll(name);
},
/**
* Resets the attribute (or all attributes) to its initial value, as long as
* the attribute is not readOnly, or writeOnce.
*
* @method reset
* @param {String} name Optional. The name of the attribute to reset. If omitted, all attributes are reset.
* @return {Object} A reference to the host object.
* @chainable
*/
reset : function(name) {
var host = this; // help compression
if (name) {
if (host._isLazyAttr(name)) {
host._addLazyAttr(name);
}
host.set(name, host._state.get(name, INIT_VALUE));
} else {
Y.Object.each(host._state.data, function(v, n) {
host.reset(n);
});
}
return host;
},
/**
* Returns an object with the configuration properties (and value)
* for the given attribute. If attrName is not provided, returns the
* configuration properties for all attributes.
*
* @method _getAttrCfg
* @protected
* @param {String} name Optional. The attribute name. If not provided, the method will return the configuration for all attributes.
* @return {Object} The configuration properties for the given attribute, or all attributes.
*/
_getAttrCfg : function(name) {
var o,
state = this._state;
if (name) {
o = state.getAll(name) || {};
} else {
o = {};
Y.each(state.data, function(v, n) {
o[n] = state.getAll(n);
});
}
return o;
}
};
Y.AttributeExtras = AttributeExtras;
}, '3.18.1', {"requires": ["oop"]});
@@ -0,0 +1 @@
YUI.add("attribute-extras",function(e,t){function o(){}var n="broadcast",r="published",i="initValue",s={readOnly:1,writeOnce:1,getter:1,broadcast:1};o.prototype={modifyAttr:function(e,t){var i=this,o,u;if(i.attrAdded(e)){i._isLazyAttr(e)&&i._addLazyAttr(e),u=i._state;for(o in t)s[o]&&t.hasOwnProperty(o)&&(u.add(e,o,t[o]),o===n&&u.remove(e,r))}},removeAttr:function(e){this._state.removeAll(e)},reset:function(t){var n=this;return t?(n._isLazyAttr(t)&&n._addLazyAttr(t),n.set(t,n._state.get(t,i))):e.Object.each(n._state.data,function(e,t){n.reset(t)}),n},_getAttrCfg:function(t){var n,r=this._state;return t?n=r.getAll(t)||{}:(n={},e.each(r.data,function(e,t){n[t]=r.getAll(t)})),n}},e.AttributeExtras=o},"3.18.1",{requires:["oop"]});
@@ -0,0 +1,156 @@
YUI.add('attribute-extras', function (Y, NAME) {
/**
* The attribute module provides an augmentable Attribute implementation, which
* adds configurable attributes and attribute change events to the class being
* augmented. It also provides a State class, which is used internally by Attribute,
* but can also be used independently to provide a name/property/value data structure to
* store state.
*
* @module attribute
*/
/**
* The attribute-extras submodule provides less commonly used attribute methods, and can
* be augmented/mixed into an implemention which used attribute-core.
*
* @module attribute
* @submodule attribute-extras
*/
var BROADCAST = "broadcast",
PUBLISHED = "published",
INIT_VALUE = "initValue",
MODIFIABLE = {
readOnly:1,
writeOnce:1,
getter:1,
broadcast:1
};
/**
* A augmentable implementation for AttributeCore, providing less frequently used
* methods for Attribute management such as modifyAttrs(), removeAttr and reset()
*
* @class AttributeExtras
* @extensionfor AttributeCore
*/
function AttributeExtras() {}
AttributeExtras.prototype = {
/**
* Updates the configuration of an attribute which has already been added.
* <p>
* The properties which can be modified through this interface are limited
* to the following subset of attributes, which can be safely modified
* after a value has already been set on the attribute:
* </p>
* <dl>
* <dt>readOnly;</dt>
* <dt>writeOnce;</dt>
* <dt>broadcast; and</dt>
* <dt>getter.</dt>
* </dl>
* <p>
* Note: New attributes cannot be added using this interface. New attributes must be
* added using {{#crossLink "AttributeCore/addAttr:method"}}addAttr{{/crossLink}}, or an
* appropriate manner for a class which utilises Attributes (e.g. the
* {{#crossLink "Base/ATTRS:property"}}ATTRS{{/crossLink}} property in
* {{#crossLink "Base"}}Base{{/crossLink}}).
* </p>
* @method modifyAttr
* @param {String} name The name of the attribute whose configuration is to be updated.
* @param {Object} config An object with configuration property/value pairs, specifying the configuration properties to modify.
*/
modifyAttr: function(name, config) {
var host = this, // help compression
prop, state;
if (host.attrAdded(name)) {
if (host._isLazyAttr(name)) {
host._addLazyAttr(name);
}
state = host._state;
for (prop in config) {
if (MODIFIABLE[prop] && config.hasOwnProperty(prop)) {
state.add(name, prop, config[prop]);
// If we reconfigured broadcast, need to republish
if (prop === BROADCAST) {
state.remove(name, PUBLISHED);
}
}
}
} else {
}
},
/**
* Removes an attribute from the host object
*
* @method removeAttr
* @param {String} name The name of the attribute to be removed.
*/
removeAttr: function(name) {
this._state.removeAll(name);
},
/**
* Resets the attribute (or all attributes) to its initial value, as long as
* the attribute is not readOnly, or writeOnce.
*
* @method reset
* @param {String} name Optional. The name of the attribute to reset. If omitted, all attributes are reset.
* @return {Object} A reference to the host object.
* @chainable
*/
reset : function(name) {
var host = this; // help compression
if (name) {
if (host._isLazyAttr(name)) {
host._addLazyAttr(name);
}
host.set(name, host._state.get(name, INIT_VALUE));
} else {
Y.Object.each(host._state.data, function(v, n) {
host.reset(n);
});
}
return host;
},
/**
* Returns an object with the configuration properties (and value)
* for the given attribute. If attrName is not provided, returns the
* configuration properties for all attributes.
*
* @method _getAttrCfg
* @protected
* @param {String} name Optional. The attribute name. If not provided, the method will return the configuration for all attributes.
* @return {Object} The configuration properties for the given attribute, or all attributes.
*/
_getAttrCfg : function(name) {
var o,
state = this._state;
if (name) {
o = state.getAll(name) || {};
} else {
o = {};
Y.each(state.data, function(v, n) {
o[n] = state.getAll(n);
});
}
return o;
}
};
Y.AttributeExtras = AttributeExtras;
}, '3.18.1', {"requires": ["oop"]});
@@ -0,0 +1,237 @@
YUI.add('attribute-observable', function (Y, NAME) {
/*For log lines*/
/*jshint maxlen:200*/
/**
* The attribute module provides an augmentable Attribute implementation, which
* adds configurable attributes and attribute change events to the class being
* augmented. It also provides a State class, which is used internally by Attribute,
* but can also be used independently to provide a name/property/value data structure to
* store state.
*
* @module attribute
*/
/**
* The `attribute-observable` submodule provides augmentable attribute change event support
* for AttributeCore based implementations.
*
* @module attribute
* @submodule attribute-observable
*/
var EventTarget = Y.EventTarget,
CHANGE = "Change",
BROADCAST = "broadcast";
/**
* Provides an augmentable implementation of attribute change events for
* AttributeCore.
*
* @class AttributeObservable
* @extensionfor AttributeCore
* @uses EventTarget
*/
function AttributeObservable() {
// Perf tweak - avoid creating event literals if not required.
this._ATTR_E_FACADE = {};
EventTarget.call(this, {emitFacade:true});
}
AttributeObservable._ATTR_CFG = [BROADCAST];
AttributeObservable.prototype = {
/**
* Sets the value of an attribute.
*
* @method set
* @chainable
*
* @param {String} name The name of the attribute. If the
* current value of the attribute is an Object, dot notation can be used
* to set the value of a property within the object (e.g. <code>set("x.y.z", 5)</code>).
*
* @param {Any} value The value to set the attribute to.
*
* @param {Object} opts (Optional) Optional event data to be mixed into
* the event facade passed to subscribers of the attribute's change event. This
* can be used as a flexible way to identify the source of a call to set, allowing
* the developer to distinguish between set called internally by the host, vs.
* set called externally by the application developer.
*
* @return {Object} A reference to the host object.
*/
set : function(name, val, opts) {
return this._setAttr(name, val, opts);
},
/**
* Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details.
*
* @method _set
* @protected
* @chainable
*
* @param {String} name The name of the attribute.
* @param {Any} val The value to set the attribute to.
* @param {Object} opts (Optional) Optional event data to be mixed into
* the event facade passed to subscribers of the attribute's change event.
* @return {Object} A reference to the host object.
*/
_set : function(name, val, opts) {
return this._setAttr(name, val, opts, true);
},
/**
* Sets multiple attribute values.
*
* @method setAttrs
* @param {Object} attrs An object with attributes name/value pairs.
* @param {Object} opts Properties to mix into the event payload. These are shared and mixed into each set
* @return {Object} A reference to the host object.
* @chainable
*/
setAttrs : function(attrs, opts) {
return this._setAttrs(attrs, opts);
},
/**
* Implementation behind the public setAttrs method, to set multiple attribute values.
*
* @method _setAttrs
* @protected
* @param {Object} attrs An object with attributes name/value pairs.
* @param {Object} opts Properties to mix into the event payload. These are shared and mixed into each set
* @return {Object} A reference to the host object.
* @chainable
*/
_setAttrs : function(attrs, opts) {
var attr;
for (attr in attrs) {
if ( attrs.hasOwnProperty(attr) ) {
this.set(attr, attrs[attr], opts);
}
}
return this;
},
/**
* Utility method to help setup the event payload and fire the attribute change event.
*
* @method _fireAttrChange
* @private
* @param {String} attrName The name of the attribute
* @param {String} subAttrName The full path of the property being changed,
* if this is a sub-attribute value being change. Otherwise null.
* @param {Any} currVal The current value of the attribute
* @param {Any} newVal The new value of the attribute
* @param {Object} opts Any additional event data to mix into the attribute change event's event facade.
* @param {Object} [cfg] The attribute config stored in State, if already available.
*/
_fireAttrChange : function(attrName, subAttrName, currVal, newVal, opts, cfg) {
var host = this,
eventName = this._getFullType(attrName + CHANGE),
state = host._state,
facade,
broadcast,
e;
if (!cfg) {
cfg = state.data[attrName] || {};
}
if (!cfg.published) {
// PERF: Using lower level _publish() for
// critical path performance
e = host._publish(eventName);
e.emitFacade = true;
e.defaultTargetOnly = true;
e.defaultFn = host._defAttrChangeFn;
broadcast = cfg.broadcast;
if (broadcast !== undefined) {
e.broadcast = broadcast;
}
cfg.published = true;
}
if (opts) {
facade = Y.merge(opts);
facade._attrOpts = opts;
} else {
facade = host._ATTR_E_FACADE;
}
// Not using the single object signature for fire({type:..., newVal:...}), since
// we don't want to override type. Changed to the fire(type, {newVal:...}) signature.
facade.attrName = attrName;
facade.subAttrName = subAttrName;
facade.prevVal = currVal;
facade.newVal = newVal;
if (host._hasPotentialSubscribers(eventName)) {
host.fire(eventName, facade);
} else {
this._setAttrVal(attrName, subAttrName, currVal, newVal, opts, cfg);
}
},
/**
* Default function for attribute change events.
*
* @private
* @method _defAttrChangeFn
* @param {EventFacade} e The event object for attribute change events.
* @param {boolean} eventFastPath Whether or not we're using this as a fast path in the case of no listeners or not
*/
_defAttrChangeFn : function(e, eventFastPath) {
var opts = e._attrOpts;
if (opts) {
delete e._attrOpts;
}
if (!this._setAttrVal(e.attrName, e.subAttrName, e.prevVal, e.newVal, opts)) {
Y.log('State not updated and stopImmediatePropagation called for attribute: ' + e.attrName + ' , value:' + e.newVal, 'warn', 'attribute');
if (!eventFastPath) {
// Prevent "after" listeners from being invoked since nothing changed.
e.stopImmediatePropagation();
}
} else {
if (!eventFastPath) {
e.newVal = this.get(e.attrName);
}
}
}
};
// Basic prototype augment - no lazy constructor invocation.
Y.mix(AttributeObservable, EventTarget, false, null, 1);
Y.AttributeObservable = AttributeObservable;
/**
The `AttributeEvents` class extension was deprecated in YUI 3.8.0 and is now
an alias for the `AttributeObservable` class extension. Use that class
extnesion instead. This alias will be removed in a future version of YUI.
@class AttributeEvents
@uses EventTarget
@deprecated Use `AttributeObservable` instead.
@see AttributeObservable
**/
Y.AttributeEvents = AttributeObservable;
}, '3.18.1', {"requires": ["event-custom"]});
@@ -0,0 +1 @@
YUI.add("attribute-observable",function(e,t){function s(){this._ATTR_E_FACADE={},n.call(this,{emitFacade:!0})}var n=e.EventTarget,r="Change",i="broadcast";s._ATTR_CFG=[i],s.prototype={set:function(e,t,n){return this._setAttr(e,t,n)},_set:function(e,t,n){return this._setAttr(e,t,n,!0)},setAttrs:function(e,t){return this._setAttrs(e,t)},_setAttrs:function(e,t){var n;for(n in e)e.hasOwnProperty(n)&&this.set(n,e[n],t);return this},_fireAttrChange:function(t,n,i,s,o,u){var a=this,f=this._getFullType(t+r),l=a._state,c,h,p;u||(u=l.data[t]||{}),u.published||(p=a._publish(f),p.emitFacade=!0,p.defaultTargetOnly=!0,p.defaultFn=a._defAttrChangeFn,h=u.broadcast,h!==undefined&&(p.broadcast=h),u.published=!0),o?(c=e.merge(o),c._attrOpts=o):c=a._ATTR_E_FACADE,c.attrName=t,c.subAttrName=n,c.prevVal=i,c.newVal=s,a._hasPotentialSubscribers(f)?a.fire(f,c):this._setAttrVal(t,n,i,s,o,u)},_defAttrChangeFn:function(e,t){var n=e._attrOpts;n&&delete e._attrOpts,this._setAttrVal(e.attrName,e.subAttrName,e.prevVal,e.newVal,n)?t||(e.newVal=this.get(e.attrName)):t||e.stopImmediatePropagation()}},e.mix(s,n,!1,null,1),e.AttributeObservable=s,e.AttributeEvents=s},"3.18.1",{requires:["event-custom"]});
@@ -0,0 +1,236 @@
YUI.add('attribute-observable', function (Y, NAME) {
/*For log lines*/
/*jshint maxlen:200*/
/**
* The attribute module provides an augmentable Attribute implementation, which
* adds configurable attributes and attribute change events to the class being
* augmented. It also provides a State class, which is used internally by Attribute,
* but can also be used independently to provide a name/property/value data structure to
* store state.
*
* @module attribute
*/
/**
* The `attribute-observable` submodule provides augmentable attribute change event support
* for AttributeCore based implementations.
*
* @module attribute
* @submodule attribute-observable
*/
var EventTarget = Y.EventTarget,
CHANGE = "Change",
BROADCAST = "broadcast";
/**
* Provides an augmentable implementation of attribute change events for
* AttributeCore.
*
* @class AttributeObservable
* @extensionfor AttributeCore
* @uses EventTarget
*/
function AttributeObservable() {
// Perf tweak - avoid creating event literals if not required.
this._ATTR_E_FACADE = {};
EventTarget.call(this, {emitFacade:true});
}
AttributeObservable._ATTR_CFG = [BROADCAST];
AttributeObservable.prototype = {
/**
* Sets the value of an attribute.
*
* @method set
* @chainable
*
* @param {String} name The name of the attribute. If the
* current value of the attribute is an Object, dot notation can be used
* to set the value of a property within the object (e.g. <code>set("x.y.z", 5)</code>).
*
* @param {Any} value The value to set the attribute to.
*
* @param {Object} opts (Optional) Optional event data to be mixed into
* the event facade passed to subscribers of the attribute's change event. This
* can be used as a flexible way to identify the source of a call to set, allowing
* the developer to distinguish between set called internally by the host, vs.
* set called externally by the application developer.
*
* @return {Object} A reference to the host object.
*/
set : function(name, val, opts) {
return this._setAttr(name, val, opts);
},
/**
* Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details.
*
* @method _set
* @protected
* @chainable
*
* @param {String} name The name of the attribute.
* @param {Any} val The value to set the attribute to.
* @param {Object} opts (Optional) Optional event data to be mixed into
* the event facade passed to subscribers of the attribute's change event.
* @return {Object} A reference to the host object.
*/
_set : function(name, val, opts) {
return this._setAttr(name, val, opts, true);
},
/**
* Sets multiple attribute values.
*
* @method setAttrs
* @param {Object} attrs An object with attributes name/value pairs.
* @param {Object} opts Properties to mix into the event payload. These are shared and mixed into each set
* @return {Object} A reference to the host object.
* @chainable
*/
setAttrs : function(attrs, opts) {
return this._setAttrs(attrs, opts);
},
/**
* Implementation behind the public setAttrs method, to set multiple attribute values.
*
* @method _setAttrs
* @protected
* @param {Object} attrs An object with attributes name/value pairs.
* @param {Object} opts Properties to mix into the event payload. These are shared and mixed into each set
* @return {Object} A reference to the host object.
* @chainable
*/
_setAttrs : function(attrs, opts) {
var attr;
for (attr in attrs) {
if ( attrs.hasOwnProperty(attr) ) {
this.set(attr, attrs[attr], opts);
}
}
return this;
},
/**
* Utility method to help setup the event payload and fire the attribute change event.
*
* @method _fireAttrChange
* @private
* @param {String} attrName The name of the attribute
* @param {String} subAttrName The full path of the property being changed,
* if this is a sub-attribute value being change. Otherwise null.
* @param {Any} currVal The current value of the attribute
* @param {Any} newVal The new value of the attribute
* @param {Object} opts Any additional event data to mix into the attribute change event's event facade.
* @param {Object} [cfg] The attribute config stored in State, if already available.
*/
_fireAttrChange : function(attrName, subAttrName, currVal, newVal, opts, cfg) {
var host = this,
eventName = this._getFullType(attrName + CHANGE),
state = host._state,
facade,
broadcast,
e;
if (!cfg) {
cfg = state.data[attrName] || {};
}
if (!cfg.published) {
// PERF: Using lower level _publish() for
// critical path performance
e = host._publish(eventName);
e.emitFacade = true;
e.defaultTargetOnly = true;
e.defaultFn = host._defAttrChangeFn;
broadcast = cfg.broadcast;
if (broadcast !== undefined) {
e.broadcast = broadcast;
}
cfg.published = true;
}
if (opts) {
facade = Y.merge(opts);
facade._attrOpts = opts;
} else {
facade = host._ATTR_E_FACADE;
}
// Not using the single object signature for fire({type:..., newVal:...}), since
// we don't want to override type. Changed to the fire(type, {newVal:...}) signature.
facade.attrName = attrName;
facade.subAttrName = subAttrName;
facade.prevVal = currVal;
facade.newVal = newVal;
if (host._hasPotentialSubscribers(eventName)) {
host.fire(eventName, facade);
} else {
this._setAttrVal(attrName, subAttrName, currVal, newVal, opts, cfg);
}
},
/**
* Default function for attribute change events.
*
* @private
* @method _defAttrChangeFn
* @param {EventFacade} e The event object for attribute change events.
* @param {boolean} eventFastPath Whether or not we're using this as a fast path in the case of no listeners or not
*/
_defAttrChangeFn : function(e, eventFastPath) {
var opts = e._attrOpts;
if (opts) {
delete e._attrOpts;
}
if (!this._setAttrVal(e.attrName, e.subAttrName, e.prevVal, e.newVal, opts)) {
if (!eventFastPath) {
// Prevent "after" listeners from being invoked since nothing changed.
e.stopImmediatePropagation();
}
} else {
if (!eventFastPath) {
e.newVal = this.get(e.attrName);
}
}
}
};
// Basic prototype augment - no lazy constructor invocation.
Y.mix(AttributeObservable, EventTarget, false, null, 1);
Y.AttributeObservable = AttributeObservable;
/**
The `AttributeEvents` class extension was deprecated in YUI 3.8.0 and is now
an alias for the `AttributeObservable` class extension. Use that class
extnesion instead. This alias will be removed in a future version of YUI.
@class AttributeEvents
@uses EventTarget
@deprecated Use `AttributeObservable` instead.
@see AttributeObservable
**/
Y.AttributeEvents = AttributeObservable;
}, '3.18.1', {"requires": ["event-custom"]});
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,136 @@
YUI.add('autocomplete-filters-accentfold', function (Y, NAME) {
/**
Provides pre-built accent-folding result matching filters for AutoComplete.
These filters are similar to the ones provided by the `autocomplete-filters`
module, but use accent-aware comparisons. For example, "resume" and "résumé"
will be considered equal when using the accent-folding filters.
@module autocomplete
@submodule autocomplete-filters-accentfold
**/
/**
@class AutoCompleteFilters
@static
**/
var AccentFold = Y.Text.AccentFold,
WordBreak = Y.Text.WordBreak,
YArray = Y.Array,
YObject = Y.Object;
Y.mix(Y.namespace('AutoCompleteFilters'), {
/**
Accent folding version of `charMatch()`.
@method charMatchFold
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
charMatchFold: function (query, results) {
if (!query) { return results; }
var queryChars = YArray.unique(AccentFold.fold(query).split(''));
return YArray.filter(results, function (result) {
var text = AccentFold.fold(result.text);
return YArray.every(queryChars, function (chr) {
return text.indexOf(chr) !== -1;
});
});
},
/**
Accent folding version of `phraseMatch()`.
@method phraseMatchFold
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
phraseMatchFold: function (query, results) {
if (!query) { return results; }
query = AccentFold.fold(query);
return YArray.filter(results, function (result) {
return AccentFold.fold(result.text).indexOf(query) !== -1;
});
},
/**
Accent folding version of `startsWith()`.
@method startsWithFold
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
startsWithFold: function (query, results) {
if (!query) { return results; }
query = AccentFold.fold(query);
return YArray.filter(results, function (result) {
return AccentFold.fold(result.text).indexOf(query) === 0;
});
},
/**
Accent folding version of `subWordMatch()`.
@method subWordMatchFold
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
subWordMatchFold: function (query, results) {
if (!query) { return results; }
var queryWords = WordBreak.getUniqueWords(AccentFold.fold(query));
return YArray.filter(results, function (result) {
var resultText = AccentFold.fold(result.text);
return YArray.every(queryWords, function (queryWord) {
return resultText.indexOf(queryWord) !== -1;
});
});
},
/**
Accent folding version of `wordMatch()`.
@method wordMatchFold
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
wordMatchFold: function (query, results) {
if (!query) { return results; }
var queryWords = WordBreak.getUniqueWords(AccentFold.fold(query));
return YArray.filter(results, function (result) {
// Convert resultWords array to a hash for fast lookup.
var resultWords = YArray.hash(WordBreak.getUniqueWords(
AccentFold.fold(result.text)));
return YArray.every(queryWords, function (word) {
return YObject.owns(resultWords, word);
});
});
}
});
}, '3.18.1', {"requires": ["array-extras", "text-accentfold", "text-wordbreak"]});
@@ -0,0 +1 @@
YUI.add("autocomplete-filters-accentfold",function(e,t){var n=e.Text.AccentFold,r=e.Text.WordBreak,i=e.Array,s=e.Object;e.mix(e.namespace("AutoCompleteFilters"),{charMatchFold:function(e,t){if(!e)return t;var r=i.unique(n.fold(e).split(""));return i.filter(t,function(e){var t=n.fold(e.text);return i.every(r,function(e){return t.indexOf(e)!==-1})})},phraseMatchFold:function(e,t){return e?(e=n.fold(e),i.filter(t,function(t){return n.fold(t.text).indexOf(e)!==-1})):t},startsWithFold:function(e,t){return e?(e=n.fold(e),i.filter(t,function(t){return n.fold(t.text).indexOf(e)===0})):t},subWordMatchFold:function(e,t){if(!e)return t;var s=r.getUniqueWords(n.fold(e));return i.filter(t,function(e){var t=n.fold(e.text);return i.every(s,function(e){return t.indexOf(e)!==-1})})},wordMatchFold:function(e,t){if(!e)return t;var o=r.getUniqueWords(n.fold(e));return i.filter(t,function(e){var t=i.hash(r.getUniqueWords(n.fold(e.text)));return i.every(o,function(e){return s.owns(t,e)})})}})},"3.18.1",{requires:["array-extras","text-accentfold","text-wordbreak"]});
@@ -0,0 +1,136 @@
YUI.add('autocomplete-filters-accentfold', function (Y, NAME) {
/**
Provides pre-built accent-folding result matching filters for AutoComplete.
These filters are similar to the ones provided by the `autocomplete-filters`
module, but use accent-aware comparisons. For example, "resume" and "résumé"
will be considered equal when using the accent-folding filters.
@module autocomplete
@submodule autocomplete-filters-accentfold
**/
/**
@class AutoCompleteFilters
@static
**/
var AccentFold = Y.Text.AccentFold,
WordBreak = Y.Text.WordBreak,
YArray = Y.Array,
YObject = Y.Object;
Y.mix(Y.namespace('AutoCompleteFilters'), {
/**
Accent folding version of `charMatch()`.
@method charMatchFold
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
charMatchFold: function (query, results) {
if (!query) { return results; }
var queryChars = YArray.unique(AccentFold.fold(query).split(''));
return YArray.filter(results, function (result) {
var text = AccentFold.fold(result.text);
return YArray.every(queryChars, function (chr) {
return text.indexOf(chr) !== -1;
});
});
},
/**
Accent folding version of `phraseMatch()`.
@method phraseMatchFold
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
phraseMatchFold: function (query, results) {
if (!query) { return results; }
query = AccentFold.fold(query);
return YArray.filter(results, function (result) {
return AccentFold.fold(result.text).indexOf(query) !== -1;
});
},
/**
Accent folding version of `startsWith()`.
@method startsWithFold
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
startsWithFold: function (query, results) {
if (!query) { return results; }
query = AccentFold.fold(query);
return YArray.filter(results, function (result) {
return AccentFold.fold(result.text).indexOf(query) === 0;
});
},
/**
Accent folding version of `subWordMatch()`.
@method subWordMatchFold
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
subWordMatchFold: function (query, results) {
if (!query) { return results; }
var queryWords = WordBreak.getUniqueWords(AccentFold.fold(query));
return YArray.filter(results, function (result) {
var resultText = AccentFold.fold(result.text);
return YArray.every(queryWords, function (queryWord) {
return resultText.indexOf(queryWord) !== -1;
});
});
},
/**
Accent folding version of `wordMatch()`.
@method wordMatchFold
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
wordMatchFold: function (query, results) {
if (!query) { return results; }
var queryWords = WordBreak.getUniqueWords(AccentFold.fold(query));
return YArray.filter(results, function (result) {
// Convert resultWords array to a hash for fast lookup.
var resultWords = YArray.hash(WordBreak.getUniqueWords(
AccentFold.fold(result.text)));
return YArray.every(queryWords, function (word) {
return YObject.owns(resultWords, word);
});
});
}
});
}, '3.18.1', {"requires": ["array-extras", "text-accentfold", "text-wordbreak"]});
@@ -0,0 +1,239 @@
YUI.add('autocomplete-filters', function (Y, NAME) {
/**
Provides pre-built result matching filters for AutoComplete.
@module autocomplete
@submodule autocomplete-filters
@class AutoCompleteFilters
@static
**/
var YArray = Y.Array,
YObject = Y.Object,
WordBreak = Y.Text.WordBreak,
Filters = Y.mix(Y.namespace('AutoCompleteFilters'), {
// -- Public Methods -------------------------------------------------------
/**
Returns an array of results that contain all of the characters in the query,
in any order (not necessarily consecutive). Case-insensitive.
@method charMatch
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
charMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// charMatchCase(). It's intentionally undocumented.
if (!query) { return results; }
var queryChars = YArray.unique((caseSensitive ? query :
query.toLowerCase()).split(''));
return YArray.filter(results, function (result) {
result = result.text;
if (!caseSensitive) {
result = result.toLowerCase();
}
return YArray.every(queryChars, function (chr) {
return result.indexOf(chr) !== -1;
});
});
},
/**
Case-sensitive version of `charMatch()`.
@method charMatchCase
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
charMatchCase: function (query, results) {
return Filters.charMatch(query, results, true);
},
/**
Returns an array of results that contain the complete query as a phrase.
Case-insensitive.
@method phraseMatch
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
phraseMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// phraseMatchCase(). It's intentionally undocumented.
if (!query) { return results; }
if (!caseSensitive) {
query = query.toLowerCase();
}
return YArray.filter(results, function (result) {
return (caseSensitive ? result.text : result.text.toLowerCase()).indexOf(query) !== -1;
});
},
/**
Case-sensitive version of `phraseMatch()`.
@method phraseMatchCase
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
phraseMatchCase: function (query, results) {
return Filters.phraseMatch(query, results, true);
},
/**
Returns an array of results that start with the complete query as a phrase.
Case-insensitive.
@method startsWith
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
startsWith: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// startsWithCase(). It's intentionally undocumented.
if (!query) { return results; }
if (!caseSensitive) {
query = query.toLowerCase();
}
return YArray.filter(results, function (result) {
return (caseSensitive ? result.text : result.text.toLowerCase()).indexOf(query) === 0;
});
},
/**
Case-sensitive version of `startsWith()`.
@method startsWithCase
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
startsWithCase: function (query, results) {
return Filters.startsWith(query, results, true);
},
/**
Returns an array of results in which all the words of the query match either
whole words or parts of words in the result. Non-word characters like
whitespace and certain punctuation are ignored. Case-insensitive.
This is basically a combination of `wordMatch()` (by ignoring whitespace and
word order) and `phraseMatch()` (by allowing partial matching instead of
requiring the entire word to match).
Example use case: Trying to find personal names independently of name order
(Western or Eastern order) and supporting immediate feedback by allowing
partial occurences. So queries like "J. Doe", "Doe, John", and "J. D." would
all match "John Doe".
@method subWordMatch
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
subWordMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// subWordMatchCase(). It's intentionally undocumented.
if (!query) { return results; }
var queryWords = WordBreak.getUniqueWords(query, {
ignoreCase: !caseSensitive
});
return YArray.filter(results, function (result) {
var resultText = caseSensitive ? result.text :
result.text.toLowerCase();
return YArray.every(queryWords, function (queryWord) {
return resultText.indexOf(queryWord) !== -1;
});
});
},
/**
Case-sensitive version of `subWordMatch()`.
@method subWordMatchCase
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
subWordMatchCase: function (query, results) {
return Filters.subWordMatch(query, results, true);
},
/**
Returns an array of results that contain all of the words in the query, in
any order. Non-word characters like whitespace and certain punctuation are
ignored. Case-insensitive.
@method wordMatch
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
wordMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// wordMatchCase(). It's intentionally undocumented.
if (!query) { return results; }
var options = {ignoreCase: !caseSensitive},
queryWords = WordBreak.getUniqueWords(query, options);
return YArray.filter(results, function (result) {
// Convert resultWords array to a hash for fast lookup.
var resultWords = YArray.hash(WordBreak.getUniqueWords(result.text,
options));
return YArray.every(queryWords, function (word) {
return YObject.owns(resultWords, word);
});
});
},
/**
Case-sensitive version of `wordMatch()`.
@method wordMatchCase
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
wordMatchCase: function (query, results) {
return Filters.wordMatch(query, results, true);
}
});
}, '3.18.1', {"requires": ["array-extras", "text-wordbreak"]});
@@ -0,0 +1 @@
YUI.add("autocomplete-filters",function(e,t){var n=e.Array,r=e.Object,i=e.Text.WordBreak,s=e.mix(e.namespace("AutoCompleteFilters"),{charMatch:function(e,t,r){if(!e)return t;var i=n.unique((r?e:e.toLowerCase()).split(""));return n.filter(t,function(e){return e=e.text,r||(e=e.toLowerCase()),n.every(i,function(t){return e.indexOf(t)!==-1})})},charMatchCase:function(e,t){return s.charMatch(e,t,!0)},phraseMatch:function(e,t,r){return e?(r||(e=e.toLowerCase()),n.filter(t,function(t){return(r?t.text:t.text.toLowerCase()).indexOf(e)!==-1})):t},phraseMatchCase:function(e,t){return s.phraseMatch(e,t,!0)},startsWith:function(e,t,r){return e?(r||(e=e.toLowerCase()),n.filter(t,function(t){return(r?t.text:t.text.toLowerCase()).indexOf(e)===0})):t},startsWithCase:function(e,t){return s.startsWith(e,t,!0)},subWordMatch:function(e,t,r){if(!e)return t;var s=i.getUniqueWords(e,{ignoreCase:!r});return n.filter(t,function(e){var t=r?e.text:e.text.toLowerCase();return n.every(s,function(e){return t.indexOf(e)!==-1})})},subWordMatchCase:function(e,t){return s.subWordMatch(e,t,!0)},wordMatch:function(e,t,s){if(!e)return t;var o={ignoreCase:!s},u=i.getUniqueWords(e,o);return n.filter(t,function(e){var t=n.hash(i.getUniqueWords(e.text,o));return n.every(u,function(e){return r.owns(t,e)})})},wordMatchCase:function(e,t){return s.wordMatch(e,t,!0)}})},"3.18.1",{requires:["array-extras","text-wordbreak"]});
@@ -0,0 +1,239 @@
YUI.add('autocomplete-filters', function (Y, NAME) {
/**
Provides pre-built result matching filters for AutoComplete.
@module autocomplete
@submodule autocomplete-filters
@class AutoCompleteFilters
@static
**/
var YArray = Y.Array,
YObject = Y.Object,
WordBreak = Y.Text.WordBreak,
Filters = Y.mix(Y.namespace('AutoCompleteFilters'), {
// -- Public Methods -------------------------------------------------------
/**
Returns an array of results that contain all of the characters in the query,
in any order (not necessarily consecutive). Case-insensitive.
@method charMatch
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
charMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// charMatchCase(). It's intentionally undocumented.
if (!query) { return results; }
var queryChars = YArray.unique((caseSensitive ? query :
query.toLowerCase()).split(''));
return YArray.filter(results, function (result) {
result = result.text;
if (!caseSensitive) {
result = result.toLowerCase();
}
return YArray.every(queryChars, function (chr) {
return result.indexOf(chr) !== -1;
});
});
},
/**
Case-sensitive version of `charMatch()`.
@method charMatchCase
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
charMatchCase: function (query, results) {
return Filters.charMatch(query, results, true);
},
/**
Returns an array of results that contain the complete query as a phrase.
Case-insensitive.
@method phraseMatch
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
phraseMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// phraseMatchCase(). It's intentionally undocumented.
if (!query) { return results; }
if (!caseSensitive) {
query = query.toLowerCase();
}
return YArray.filter(results, function (result) {
return (caseSensitive ? result.text : result.text.toLowerCase()).indexOf(query) !== -1;
});
},
/**
Case-sensitive version of `phraseMatch()`.
@method phraseMatchCase
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
phraseMatchCase: function (query, results) {
return Filters.phraseMatch(query, results, true);
},
/**
Returns an array of results that start with the complete query as a phrase.
Case-insensitive.
@method startsWith
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
startsWith: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// startsWithCase(). It's intentionally undocumented.
if (!query) { return results; }
if (!caseSensitive) {
query = query.toLowerCase();
}
return YArray.filter(results, function (result) {
return (caseSensitive ? result.text : result.text.toLowerCase()).indexOf(query) === 0;
});
},
/**
Case-sensitive version of `startsWith()`.
@method startsWithCase
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
startsWithCase: function (query, results) {
return Filters.startsWith(query, results, true);
},
/**
Returns an array of results in which all the words of the query match either
whole words or parts of words in the result. Non-word characters like
whitespace and certain punctuation are ignored. Case-insensitive.
This is basically a combination of `wordMatch()` (by ignoring whitespace and
word order) and `phraseMatch()` (by allowing partial matching instead of
requiring the entire word to match).
Example use case: Trying to find personal names independently of name order
(Western or Eastern order) and supporting immediate feedback by allowing
partial occurences. So queries like "J. Doe", "Doe, John", and "J. D." would
all match "John Doe".
@method subWordMatch
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
subWordMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// subWordMatchCase(). It's intentionally undocumented.
if (!query) { return results; }
var queryWords = WordBreak.getUniqueWords(query, {
ignoreCase: !caseSensitive
});
return YArray.filter(results, function (result) {
var resultText = caseSensitive ? result.text :
result.text.toLowerCase();
return YArray.every(queryWords, function (queryWord) {
return resultText.indexOf(queryWord) !== -1;
});
});
},
/**
Case-sensitive version of `subWordMatch()`.
@method subWordMatchCase
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
subWordMatchCase: function (query, results) {
return Filters.subWordMatch(query, results, true);
},
/**
Returns an array of results that contain all of the words in the query, in
any order. Non-word characters like whitespace and certain punctuation are
ignored. Case-insensitive.
@method wordMatch
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
wordMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// wordMatchCase(). It's intentionally undocumented.
if (!query) { return results; }
var options = {ignoreCase: !caseSensitive},
queryWords = WordBreak.getUniqueWords(query, options);
return YArray.filter(results, function (result) {
// Convert resultWords array to a hash for fast lookup.
var resultWords = YArray.hash(WordBreak.getUniqueWords(result.text,
options));
return YArray.every(queryWords, function (word) {
return YObject.owns(resultWords, word);
});
});
},
/**
Case-sensitive version of `wordMatch()`.
@method wordMatchCase
@param {String} query Query to match
@param {Array} results Results to filter
@return {Array} Filtered results
@static
**/
wordMatchCase: function (query, results) {
return Filters.wordMatch(query, results, true);
}
});
}, '3.18.1', {"requires": ["array-extras", "text-wordbreak"]});
@@ -0,0 +1,107 @@
YUI.add('autocomplete-highlighters-accentfold', function (Y, NAME) {
/**
Provides pre-built accent-folding result highlighters for AutoComplete.
These highlighters are similar to the ones provided by the `autocomplete-
highlighters` module, but use accent-aware comparisons. For example, "resume"
and "résumé" will be considered equal when using the accent-folding
highlighters.
@module autocomplete
@submodule autocomplete-highlighters-accentfold
**/
/**
@class AutoCompleteHighlighters
@static
**/
var Highlight = Y.Highlight,
YArray = Y.Array;
Y.mix(Y.namespace('AutoCompleteHighlighters'), {
/**
Accent-folding version of `charMatch()`.
@method charMatchFold
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
charMatchFold: function (query, results) {
var queryChars = YArray.unique(query.split(''));
return YArray.map(results, function (result) {
return Highlight.allFold(result.text, queryChars);
});
},
/**
Accent-folding version of `phraseMatch()`.
@method phraseMatchFold
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
phraseMatchFold: function (query, results) {
return YArray.map(results, function (result) {
return Highlight.allFold(result.text, [query]);
});
},
/**
Accent-folding version of `startsWith()`.
@method startsWithFold
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
startsWithFold: function (query, results) {
return YArray.map(results, function (result) {
return Highlight.allFold(result.text, [query], {
startsWith: true
});
});
},
/**
Accent-folding version of `subWordMatch()`.
@method subWordMatchFold
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
subWordMatchFold: function (query, results) {
var queryWords = Y.Text.WordBreak.getUniqueWords(query);
return YArray.map(results, function (result) {
return Highlight.allFold(result.text, queryWords);
});
},
/**
Accent-folding version of `wordMatch()`.
@method wordMatchFold
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
wordMatchFold: function (query, results) {
return YArray.map(results, function (result) {
return Highlight.wordsFold(result.text, query);
});
}
});
}, '3.18.1', {"requires": ["array-extras", "highlight-accentfold"]});
@@ -0,0 +1 @@
YUI.add("autocomplete-highlighters-accentfold",function(e,t){var n=e.Highlight,r=e.Array;e.mix(e.namespace("AutoCompleteHighlighters"),{charMatchFold:function(e,t){var i=r.unique(e.split(""));return r.map(t,function(e){return n.allFold(e.text,i)})},phraseMatchFold:function(e,t){return r.map(t,function(t){return n.allFold(t.text,[e])})},startsWithFold:function(e,t){return r.map(t,function(t){return n.allFold(t.text,[e],{startsWith:!0})})},subWordMatchFold:function(t,i){var s=e.Text.WordBreak.getUniqueWords(t);return r.map(i,function(e){return n.allFold(e.text,s)})},wordMatchFold:function(e,t){return r.map(t,function(t){return n.wordsFold(t.text,e)})}})},"3.18.1",{requires:["array-extras","highlight-accentfold"]});
@@ -0,0 +1,107 @@
YUI.add('autocomplete-highlighters-accentfold', function (Y, NAME) {
/**
Provides pre-built accent-folding result highlighters for AutoComplete.
These highlighters are similar to the ones provided by the `autocomplete-
highlighters` module, but use accent-aware comparisons. For example, "resume"
and "résumé" will be considered equal when using the accent-folding
highlighters.
@module autocomplete
@submodule autocomplete-highlighters-accentfold
**/
/**
@class AutoCompleteHighlighters
@static
**/
var Highlight = Y.Highlight,
YArray = Y.Array;
Y.mix(Y.namespace('AutoCompleteHighlighters'), {
/**
Accent-folding version of `charMatch()`.
@method charMatchFold
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
charMatchFold: function (query, results) {
var queryChars = YArray.unique(query.split(''));
return YArray.map(results, function (result) {
return Highlight.allFold(result.text, queryChars);
});
},
/**
Accent-folding version of `phraseMatch()`.
@method phraseMatchFold
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
phraseMatchFold: function (query, results) {
return YArray.map(results, function (result) {
return Highlight.allFold(result.text, [query]);
});
},
/**
Accent-folding version of `startsWith()`.
@method startsWithFold
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
startsWithFold: function (query, results) {
return YArray.map(results, function (result) {
return Highlight.allFold(result.text, [query], {
startsWith: true
});
});
},
/**
Accent-folding version of `subWordMatch()`.
@method subWordMatchFold
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
subWordMatchFold: function (query, results) {
var queryWords = Y.Text.WordBreak.getUniqueWords(query);
return YArray.map(results, function (result) {
return Highlight.allFold(result.text, queryWords);
});
},
/**
Accent-folding version of `wordMatch()`.
@method wordMatchFold
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
wordMatchFold: function (query, results) {
return YArray.map(results, function (result) {
return Highlight.wordsFold(result.text, query);
});
}
});
}, '3.18.1', {"requires": ["array-extras", "highlight-accentfold"]});
@@ -0,0 +1,199 @@
YUI.add('autocomplete-highlighters', function (Y, NAME) {
/**
Provides pre-built result highlighters for AutoComplete.
@module autocomplete
@submodule autocomplete-highlighters
@class AutoCompleteHighlighters
@static
**/
var YArray = Y.Array,
Highlight = Y.Highlight,
Highlighters = Y.mix(Y.namespace('AutoCompleteHighlighters'), {
// -- Public Methods -------------------------------------------------------
/**
Highlights any individual query character that occurs anywhere in a result.
Case-insensitive.
@method charMatch
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
charMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// charMatchCase(). It's intentionally undocumented.
var queryChars = YArray.unique((caseSensitive ? query :
query.toLowerCase()).split(''));
return YArray.map(results, function (result) {
return Highlight.all(result.text, queryChars, {
caseSensitive: caseSensitive
});
});
},
/**
Case-sensitive version of `charMatch()`.
@method charMatchCase
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
charMatchCase: function (query, results) {
return Highlighters.charMatch(query, results, true);
},
/**
Highlights the complete query as a phrase anywhere within a result. Case-
insensitive.
@method phraseMatch
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
phraseMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// phraseMatchCase(). It's intentionally undocumented.
return YArray.map(results, function (result) {
return Highlight.all(result.text, [query], {
caseSensitive: caseSensitive
});
});
},
/**
Case-sensitive version of `phraseMatch()`.
@method phraseMatchCase
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
phraseMatchCase: function (query, results) {
return Highlighters.phraseMatch(query, results, true);
},
/**
Highlights the complete query as a phrase at the beginning of a result.
Case-insensitive.
@method startsWith
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
startsWith: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// startsWithCase(). It's intentionally undocumented.
return YArray.map(results, function (result) {
return Highlight.all(result.text, [query], {
caseSensitive: caseSensitive,
startsWith : true
});
});
},
/**
Case-sensitive version of `startsWith()`.
@method startsWithCase
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
startsWithCase: function (query, results) {
return Highlighters.startsWith(query, results, true);
},
/**
Highlights portions of results in which words from the query match either
whole words or parts of words in the result. Non-word characters like
whitespace and certain punctuation are ignored. Case-insensitive.
@method subWordMatch
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
subWordMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// subWordMatchCase(). It's intentionally undocumented.
var queryWords = Y.Text.WordBreak.getUniqueWords(query, {
ignoreCase: !caseSensitive
});
return YArray.map(results, function (result) {
return Highlight.all(result.text, queryWords, {
caseSensitive: caseSensitive
});
});
},
/**
Case-sensitive version of `subWordMatch()`.
@method subWordMatchCase
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
subWordMatchCase: function (query, results) {
return Highlighters.subWordMatch(query, results, true);
},
/**
Highlights individual words in results that are also in the query. Non-word
characters like punctuation are ignored. Case-insensitive.
@method wordMatch
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
wordMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// wordMatchCase(). It's intentionally undocumented.
return YArray.map(results, function (result) {
return Highlight.words(result.text, query, {
caseSensitive: caseSensitive
});
});
},
/**
Case-sensitive version of `wordMatch()`.
@method wordMatchCase
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
wordMatchCase: function (query, results) {
return Highlighters.wordMatch(query, results, true);
}
});
}, '3.18.1', {"requires": ["array-extras", "highlight-base"]});
@@ -0,0 +1 @@
YUI.add("autocomplete-highlighters",function(e,t){var n=e.Array,r=e.Highlight,i=e.mix(e.namespace("AutoCompleteHighlighters"),{charMatch:function(e,t,i){var s=n.unique((i?e:e.toLowerCase()).split(""));return n.map(t,function(e){return r.all(e.text,s,{caseSensitive:i})})},charMatchCase:function(e,t){return i.charMatch(e,t,!0)},phraseMatch:function(e,t,i){return n.map(t,function(t){return r.all(t.text,[e],{caseSensitive:i})})},phraseMatchCase:function(e,t){return i.phraseMatch(e,t,!0)},startsWith:function(e,t,i){return n.map(t,function(t){return r.all(t.text,[e],{caseSensitive:i,startsWith:!0})})},startsWithCase:function(e,t){return i.startsWith(e,t,!0)},subWordMatch:function(t,i,s){var o=e.Text.WordBreak.getUniqueWords(t,{ignoreCase:!s});return n.map(i,function(e){return r.all(e.text,o,{caseSensitive:s})})},subWordMatchCase:function(e,t){return i.subWordMatch(e,t,!0)},wordMatch:function(e,t,i){return n.map(t,function(t){return r.words(t.text,e,{caseSensitive:i})})},wordMatchCase:function(e,t){return i.wordMatch(e,t,!0)}})},"3.18.1",{requires:["array-extras","highlight-base"]});
@@ -0,0 +1,199 @@
YUI.add('autocomplete-highlighters', function (Y, NAME) {
/**
Provides pre-built result highlighters for AutoComplete.
@module autocomplete
@submodule autocomplete-highlighters
@class AutoCompleteHighlighters
@static
**/
var YArray = Y.Array,
Highlight = Y.Highlight,
Highlighters = Y.mix(Y.namespace('AutoCompleteHighlighters'), {
// -- Public Methods -------------------------------------------------------
/**
Highlights any individual query character that occurs anywhere in a result.
Case-insensitive.
@method charMatch
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
charMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// charMatchCase(). It's intentionally undocumented.
var queryChars = YArray.unique((caseSensitive ? query :
query.toLowerCase()).split(''));
return YArray.map(results, function (result) {
return Highlight.all(result.text, queryChars, {
caseSensitive: caseSensitive
});
});
},
/**
Case-sensitive version of `charMatch()`.
@method charMatchCase
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
charMatchCase: function (query, results) {
return Highlighters.charMatch(query, results, true);
},
/**
Highlights the complete query as a phrase anywhere within a result. Case-
insensitive.
@method phraseMatch
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
phraseMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// phraseMatchCase(). It's intentionally undocumented.
return YArray.map(results, function (result) {
return Highlight.all(result.text, [query], {
caseSensitive: caseSensitive
});
});
},
/**
Case-sensitive version of `phraseMatch()`.
@method phraseMatchCase
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
phraseMatchCase: function (query, results) {
return Highlighters.phraseMatch(query, results, true);
},
/**
Highlights the complete query as a phrase at the beginning of a result.
Case-insensitive.
@method startsWith
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
startsWith: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// startsWithCase(). It's intentionally undocumented.
return YArray.map(results, function (result) {
return Highlight.all(result.text, [query], {
caseSensitive: caseSensitive,
startsWith : true
});
});
},
/**
Case-sensitive version of `startsWith()`.
@method startsWithCase
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
startsWithCase: function (query, results) {
return Highlighters.startsWith(query, results, true);
},
/**
Highlights portions of results in which words from the query match either
whole words or parts of words in the result. Non-word characters like
whitespace and certain punctuation are ignored. Case-insensitive.
@method subWordMatch
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
subWordMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// subWordMatchCase(). It's intentionally undocumented.
var queryWords = Y.Text.WordBreak.getUniqueWords(query, {
ignoreCase: !caseSensitive
});
return YArray.map(results, function (result) {
return Highlight.all(result.text, queryWords, {
caseSensitive: caseSensitive
});
});
},
/**
Case-sensitive version of `subWordMatch()`.
@method subWordMatchCase
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
subWordMatchCase: function (query, results) {
return Highlighters.subWordMatch(query, results, true);
},
/**
Highlights individual words in results that are also in the query. Non-word
characters like punctuation are ignored. Case-insensitive.
@method wordMatch
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
wordMatch: function (query, results, caseSensitive) {
// The caseSensitive parameter is only intended for use by
// wordMatchCase(). It's intentionally undocumented.
return YArray.map(results, function (result) {
return Highlight.words(result.text, query, {
caseSensitive: caseSensitive
});
});
},
/**
Case-sensitive version of `wordMatch()`.
@method wordMatchCase
@param {String} query Query to match
@param {Array} results Results to highlight
@return {Array} Highlighted results
@static
**/
wordMatchCase: function (query, results) {
return Highlighters.wordMatch(query, results, true);
}
});
}, '3.18.1', {"requires": ["array-extras", "highlight-base"]});
@@ -0,0 +1,186 @@
YUI.add('autocomplete-list-keys', function (Y, NAME) {
/**
Mixes keyboard support into AutoCompleteList. By default, this module is not
loaded for iOS and Android devices.
@module autocomplete
@submodule autocomplete-list-keys
**/
// keyCode constants.
var KEY_DOWN = 40,
KEY_ENTER = 13,
KEY_ESC = 27,
KEY_TAB = 9,
KEY_UP = 38;
function ListKeys() {
Y.after(this._bindKeys, this, 'bindUI');
this._initKeys();
}
ListKeys.prototype = {
// -- Lifecycle Methods ----------------------------------------------------
/**
Initializes keyboard command mappings.
@method _initKeys
@protected
@for AutoCompleteList
**/
_initKeys: function () {
var keys = {},
keysVisible = {};
// Register keyboard command handlers. _keys contains handlers that will
// always be called; _keysVisible contains handlers that will only be
// called when the list is visible.
keys[KEY_DOWN] = this._keyDown;
keysVisible[KEY_ENTER] = this._keyEnter;
keysVisible[KEY_ESC] = this._keyEsc;
keysVisible[KEY_TAB] = this._keyTab;
keysVisible[KEY_UP] = this._keyUp;
this._keys = keys;
this._keysVisible = keysVisible;
},
destructor: function () {
this._unbindKeys();
},
/**
Binds keyboard events.
@method _bindKeys
@protected
**/
_bindKeys: function () {
this._keyEvents = this._inputNode.on('keydown', this._onInputKey, this);
},
/**
Unbinds keyboard events.
@method _unbindKeys
@protected
**/
_unbindKeys: function () {
this._keyEvents && this._keyEvents.detach();
this._keyEvents = null;
},
// -- Protected Methods ----------------------------------------------------
/**
Called when the down arrow key is pressed.
@method _keyDown
@protected
**/
_keyDown: function () {
if (this.get('visible')) {
this._activateNextItem();
} else {
this.show();
}
},
/**
Called when the enter key is pressed.
@method _keyEnter
@protected
**/
_keyEnter: function (e) {
var item = this.get('activeItem');
if (item) {
this.selectItem(item, e);
} else {
// Don't prevent form submission when there's no active item.
return false;
}
},
/**
Called when the escape key is pressed.
@method _keyEsc
@protected
**/
_keyEsc: function () {
this.hide();
},
/**
Called when the tab key is pressed.
@method _keyTab
@protected
**/
_keyTab: function (e) {
var item;
if (this.get('tabSelect')) {
item = this.get('activeItem');
if (item) {
this.selectItem(item, e);
return true;
}
}
return false;
},
/**
Called when the up arrow key is pressed.
@method _keyUp
@protected
**/
_keyUp: function () {
this._activatePrevItem();
},
// -- Protected Event Handlers ---------------------------------------------
/**
Handles `inputNode` key events.
@method _onInputKey
@param {EventTarget} e
@protected
**/
_onInputKey: function (e) {
var handler,
keyCode = e.keyCode;
this._lastInputKey = keyCode;
if (this.get('results').length) {
handler = this._keys[keyCode];
if (!handler && this.get('visible')) {
handler = this._keysVisible[keyCode];
}
if (handler) {
// A handler may return false to indicate that it doesn't wish
// to prevent the default key behavior.
if (handler.call(this, e) !== false) {
e.preventDefault();
}
}
}
}
};
Y.Base.mix(Y.AutoCompleteList, [ListKeys]);
}, '3.18.1', {"requires": ["autocomplete-list", "base-build"]});
@@ -0,0 +1 @@
YUI.add("autocomplete-list-keys",function(e,t){function u(){e.after(this._bindKeys,this,"bindUI"),this._initKeys()}var n=40,r=13,i=27,s=9,o=38;u.prototype={_initKeys:function(){var e={},t={};e[n]=this._keyDown,t[r]=this._keyEnter,t[i]=this._keyEsc,t[s]=this._keyTab,t[o]=this._keyUp,this._keys=e,this._keysVisible=t},destructor:function(){this._unbindKeys()},_bindKeys:function(){this._keyEvents=this._inputNode.on("keydown",this._onInputKey,this)},_unbindKeys:function(){this._keyEvents&&this._keyEvents.detach(),this._keyEvents=null},_keyDown:function(){this.get("visible")?this._activateNextItem():this.show()},_keyEnter:function(e){var t=this.get("activeItem");if(!t)return!1;this.selectItem(t,e)},_keyEsc:function(){this.hide()},_keyTab:function(e){var t;if(this.get("tabSelect")){t=this.get("activeItem");if(t)return this.selectItem(t,e),!0}return!1},_keyUp:function(){this._activatePrevItem()},_onInputKey:function(e){var t,n=e.keyCode;this._lastInputKey=n,this.get("results").length&&(t=this._keys[n],!t&&this.get("visible")&&(t=this._keysVisible[n]),t&&t.call(this,e)!==!1&&e.preventDefault())}},e.Base.mix(e.AutoCompleteList,[u])},"3.18.1",{requires:["autocomplete-list","base-build"]});
@@ -0,0 +1,186 @@
YUI.add('autocomplete-list-keys', function (Y, NAME) {
/**
Mixes keyboard support into AutoCompleteList. By default, this module is not
loaded for iOS and Android devices.
@module autocomplete
@submodule autocomplete-list-keys
**/
// keyCode constants.
var KEY_DOWN = 40,
KEY_ENTER = 13,
KEY_ESC = 27,
KEY_TAB = 9,
KEY_UP = 38;
function ListKeys() {
Y.after(this._bindKeys, this, 'bindUI');
this._initKeys();
}
ListKeys.prototype = {
// -- Lifecycle Methods ----------------------------------------------------
/**
Initializes keyboard command mappings.
@method _initKeys
@protected
@for AutoCompleteList
**/
_initKeys: function () {
var keys = {},
keysVisible = {};
// Register keyboard command handlers. _keys contains handlers that will
// always be called; _keysVisible contains handlers that will only be
// called when the list is visible.
keys[KEY_DOWN] = this._keyDown;
keysVisible[KEY_ENTER] = this._keyEnter;
keysVisible[KEY_ESC] = this._keyEsc;
keysVisible[KEY_TAB] = this._keyTab;
keysVisible[KEY_UP] = this._keyUp;
this._keys = keys;
this._keysVisible = keysVisible;
},
destructor: function () {
this._unbindKeys();
},
/**
Binds keyboard events.
@method _bindKeys
@protected
**/
_bindKeys: function () {
this._keyEvents = this._inputNode.on('keydown', this._onInputKey, this);
},
/**
Unbinds keyboard events.
@method _unbindKeys
@protected
**/
_unbindKeys: function () {
this._keyEvents && this._keyEvents.detach();
this._keyEvents = null;
},
// -- Protected Methods ----------------------------------------------------
/**
Called when the down arrow key is pressed.
@method _keyDown
@protected
**/
_keyDown: function () {
if (this.get('visible')) {
this._activateNextItem();
} else {
this.show();
}
},
/**
Called when the enter key is pressed.
@method _keyEnter
@protected
**/
_keyEnter: function (e) {
var item = this.get('activeItem');
if (item) {
this.selectItem(item, e);
} else {
// Don't prevent form submission when there's no active item.
return false;
}
},
/**
Called when the escape key is pressed.
@method _keyEsc
@protected
**/
_keyEsc: function () {
this.hide();
},
/**
Called when the tab key is pressed.
@method _keyTab
@protected
**/
_keyTab: function (e) {
var item;
if (this.get('tabSelect')) {
item = this.get('activeItem');
if (item) {
this.selectItem(item, e);
return true;
}
}
return false;
},
/**
Called when the up arrow key is pressed.
@method _keyUp
@protected
**/
_keyUp: function () {
this._activatePrevItem();
},
// -- Protected Event Handlers ---------------------------------------------
/**
Handles `inputNode` key events.
@method _onInputKey
@param {EventTarget} e
@protected
**/
_onInputKey: function (e) {
var handler,
keyCode = e.keyCode;
this._lastInputKey = keyCode;
if (this.get('results').length) {
handler = this._keys[keyCode];
if (!handler && this.get('visible')) {
handler = this._keysVisible[keyCode];
}
if (handler) {
// A handler may return false to indicate that it doesn't wish
// to prevent the default key behavior.
if (handler.call(this, e) !== false) {
e.preventDefault();
}
}
}
}
};
Y.Base.mix(Y.AutoCompleteList, [ListKeys]);
}, '3.18.1', {"requires": ["autocomplete-list", "base-build"]});
@@ -0,0 +1,27 @@
.yui3-aclist {
position: absolute;
z-index: 1;
}
.yui3-aclist-hidden { visibility: hidden; }
.yui3-aclist-aria {
/* Hide from sighted users, show to screen readers. */
left: -9999px;
position: absolute;
}
.yui3-aclist-list {
list-style: none;
margin: 0;
overflow: hidden;
padding: 0;
}
.yui3-aclist-item {
cursor: pointer;
list-style: none;
padding: 2px 5px;
}
.yui3-aclist-item-active { outline: #afafaf dotted thin; }
@@ -0,0 +1,51 @@
.yui3-skin-night [for=ac-input] { /* autocomplete label color */
color: #CBCBCB;
}
.yui3-skin-night .yui3-aclist-content {
font-size: 100%;
background-color: #151515;
color: #ccc;
border: 1px solid #303030;
-moz-box-shadow: 0 0 17px rgba(0,0,0,0.58);
-webkit-box-shadow: 0 0 17px rgba(0,0,0,0.58);
box-shadow: 0 0 17px rgba(0,0,0,0.58);
}
.yui3-skin-night .yui3-aclist-item-active {
background-color: #2F3030;
background: -moz-linear-gradient(
0% 100% 90deg,
#252626 0%,
#333434 100%
);
background: -webkit-gradient(
linear,
left top,
left bottom,
from(#333434),
to(#252626)
);
}
.yui3-skin-night .yui3-aclist-item-hover {
background-color: #262727;
background: -moz-linear-gradient(
0% 100% 90deg,
#202121 0%,
#282929 100%
);
background: -webkit-gradient(
linear,
left top,
left bottom,
from(#282929),
to(#202121)
);
}
.yui3-skin-night .yui3-aclist-item {
padding: 0 1em; /*0.4em 1em 0.6em*/
line-height: 2.25;
}
.yui3-skin-night .yui3-aclist-item-active { outline: none; }
.yui3-skin-night .yui3-highlight { color:#EFEFEF; }
@@ -0,0 +1 @@
.yui3-aclist{position:absolute;z-index:1}.yui3-aclist-hidden{visibility:hidden}.yui3-aclist-aria{left:-9999px;position:absolute}.yui3-aclist-list{list-style:none;margin:0;overflow:hidden;padding:0}.yui3-aclist-item{cursor:pointer;list-style:none;padding:2px 5px}.yui3-aclist-item-active{outline:#afafaf dotted thin}.yui3-skin-night [for=ac-input]{color:#cbcbcb}.yui3-skin-night .yui3-aclist-content{font-size:100%;background-color:#151515;color:#ccc;border:1px solid #303030;-moz-box-shadow:0 0 17px rgba(0,0,0,0.58);-webkit-box-shadow:0 0 17px rgba(0,0,0,0.58);box-shadow:0 0 17px rgba(0,0,0,0.58)}.yui3-skin-night .yui3-aclist-item-active{background-color:#2f3030;background:-moz-linear-gradient(0% 100% 90deg,#252626 0,#333434 100%);background:-webkit-gradient(linear,left top,left bottom,from(#333434),to(#252626))}.yui3-skin-night .yui3-aclist-item-hover{background-color:#262727;background:-moz-linear-gradient(0% 100% 90deg,#202121 0,#282929 100%);background:-webkit-gradient(linear,left top,left bottom,from(#282929),to(#202121))}.yui3-skin-night .yui3-aclist-item{padding:0 1em;line-height:2.25}.yui3-skin-night .yui3-aclist-item-active{outline:0}.yui3-skin-night .yui3-highlight{color:#efefef}#yui3-css-stamp.skin-night-autocomplete-list{display:none}
@@ -0,0 +1,17 @@
.yui3-skin-sam .yui3-aclist-content {
background: #fff;
border: 1px solid #afafaf;
-moz-box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.58);
-webkit-box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.58);
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.58);
}
.yui3-skin-sam .yui3-aclist-item-hover {
background: #bfdaff;
}
.yui3-skin-sam .yui3-aclist-item-active {
background: #2647a0;
color: #fff;
outline: none;
}
@@ -0,0 +1 @@
.yui3-aclist{position:absolute;z-index:1}.yui3-aclist-hidden{visibility:hidden}.yui3-aclist-aria{left:-9999px;position:absolute}.yui3-aclist-list{list-style:none;margin:0;overflow:hidden;padding:0}.yui3-aclist-item{cursor:pointer;list-style:none;padding:2px 5px}.yui3-aclist-item-active{outline:#afafaf dotted thin}.yui3-skin-sam .yui3-aclist-content{background:#fff;border:1px solid #afafaf;-moz-box-shadow:1px 1px 4px rgba(0,0,0,0.58);-webkit-box-shadow:1px 1px 4px rgba(0,0,0,0.58);box-shadow:1px 1px 4px rgba(0,0,0,0.58)}.yui3-skin-sam .yui3-aclist-item-hover{background:#bfdaff}.yui3-skin-sam .yui3-aclist-item-active{background:#2647a0;color:#fff;outline:0}#yui3-css-stamp.skin-sam-autocomplete-list{display:none}

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