transition-native.js revision 7f03c81c9c42b32e09a911682e00adb57f0985b9
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein* Provides the transition method for Node.
4a14ce5ba00ab7bc55c99ffdcf59c7a4ab902721Automatic Updater* Transition has no API of its own, but adds the transition method to Node.
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington* @module transition
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein* @requires node-style
9016767f4e15191b7c763b8a4ad36a57dc2705a2Mark Andrews TRANSITION_PROPERTY_CAMEL = 'WebkitTransitionProperty',
9016767f4e15191b7c763b8a4ad36a57dc2705a2Mark Andrews TRANSITION_PROPERTY = '-webkit-transition-property',
9016767f4e15191b7c763b8a4ad36a57dc2705a2Mark Andrews TRANSITION_DURATION = '-webkit-transition-duration',
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington TRANSITION_TIMING_FUNCTION = '-webkit-transition-timing-function',
ea94d370123a5892f6c47a97f21d1b28d44bb168Tinderbox User TRANSITION_DELAY = '-webkit-transition-delay',
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * A class for constructing transition instances.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Adds the "transition" method to Node.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @class Transition
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @constructor
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein property = property.replace(/-([a-z])/gi, function(m0, m1) {
5fa6a064b8301e4f274bd132fd577def59e4fb4cTinderbox User property = property.replace(/([A-Z]?)([a-z]+)([A-Z]?)/g, function(m0, m1, m2, m3) {
8e821eea5f57ac47a94305aa7ab0c3570d92a311Automatic UpdaterTransition._reKeywords = /^(?:node|duration|iterations|easing|delay|on|onstart|onend)$/i;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinif (TRANSITION in Y.config.doc.documentElement.style) {
731cc132f22dbc9e0ecd7035dce314a61076d31bAutomatic Updater Transition.supported = true; // TODO: remove
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater node._transition = anim; // cache for reuse
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater config.duration: anim.constructor.DEFAULT_DURATION;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein anim._easing = config.easing || anim.constructor.DEFAULT_EASING;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein anim._count = 0; // track number of animated properties
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater // might just be a value
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater if (config && config.value !== undefined) {
6ea2385360e9e2167e65f9286447da9eea189457Tinderbox User // take control if another transition owns this property
6ea2385360e9e2167e65f9286447da9eea189457Tinderbox User attr.transition._count--; // remapping attr to this transition
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // make 0 async and fire events
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein dur = ((typeof config.duration != 'undefined') ? config.duration :
f8e3e03cacd16ffb923a9603fca23a9e1a1fee07Automatic Updater delay: (typeof config.delay != 'undefined') ? config.delay :
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // native end event doesnt fire when setting to same value
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // supplementing with timer
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // val may be a string or number (height: 0, etc), but computedStyle is always string
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein compareVal = (typeof val === 'string') ? computed : parseFloat(computed);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if (Transition.useNative && compareVal === val) {
a3f8c8e20780e488141d200acdfea6c5f3303513Automatic Updater attrs = Transition._nodeAttrs[Y.stamp(anim._node)];
575e15fed997a3ad1cb35c5b9ef34ab24ce47e72Automatic Updater if (config.transform && !config[TRANSFORM_CAMEL]) {
575e15fed997a3ad1cb35c5b9ef34ab24ce47e72Automatic Updater config[TRANSFORM_CAMEL] = config.transform;
575e15fed997a3ad1cb35c5b9ef34ab24ce47e72Automatic Updater if (config.hasOwnProperty(attr) && !Transition._reKeywords.test(attr)) {
575e15fed997a3ad1cb35c5b9ef34ab24ce47e72Automatic Updater // when size is auto or % webkit starts from zero instead of computed
575e15fed997a3ad1cb35c5b9ef34ab24ce47e72Automatic Updater // (https://bugs.webkit.org/show_bug.cgi?id=16020)
575e15fed997a3ad1cb35c5b9ef34ab24ce47e72Automatic Updater // TODO: selective set
575e15fed997a3ad1cb35c5b9ef34ab24ce47e72Automatic Updater Y.DOM.setStyle(node, attr, Y.DOM.getComputedStyle(node, attr));
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Starts or an animation.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method run
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @chainable
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //anim._node.fire('transition:start', data);
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater easing = TRANSITION_TIMING_FUNCTION + ': ',
2895f101b5585a19015ac2c2c1e1812ac467fa12Automatic Updater // preserve existing transitions
bbbf2e27d3a981163dab139497d6b2dc85449db0Tinderbox User duration += computed[TRANSITION_DURATION] + ',';
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater easing += computed[TRANSITION_TIMING_FUNCTION] + ',';
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater delay += computed[TRANSITION_DELAY] + ',';
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater // run transitions mapped to this instance
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater if (attrs.hasOwnProperty(name) && attr.transition === anim) {
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater if (name in node.style) { // only native styles allowed
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater duration += anim._prepDur(attr.duration) + ',';
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater transitionText = transitionText.replace(/,$/, ';');
f8e3e03cacd16ffb923a9603fca23a9e1a1fee07Automatic Updater // only one native end event per node
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater //anim._detach = Y.on(TRANSITION_END, anim._onNativeEnd, node);
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater //node[ON_TRANSITION_END] = anim._onNativeEnd;
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater node.addEventListener(TRANSITION_END, anim._onNativeEnd, false);
3acf5eb97cebc2ba868e6ac4a4e01e6d1be0c892Automatic Updater //setTimeout(function() { // allow updates to apply (size fix, onstart, etc)
3acf5eb97cebc2ba868e6ac4a4e01e6d1be0c892Automatic Updater style.cssText += transitionText + duration + easing + delay + cssText;
0a7ed88633a680bb881868b75ded4d09a7bbbc50Automatic Updater setTimeout(function() { // IE: allow previous update to finish
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // nested to ensure proper fire order
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein } else if (callback) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein setTimeout(function() { // IE: allow previous update to finish
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //node.fire('transition:end', data);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein value = node.ownerDocument.defaultView.getComputedStyle(node, '')[TRANSITION_PROPERTY];
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein value = value.replace(new RegExp('(?:^|,\\s)' + name + ',?'), ',');
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _onNativeEnd: function(e) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //node.fire('transition:propertyEnd', data);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if (anim._count <= 0) { // after propertyEnd fires
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein destroy: function() {
5fa6a064b8301e4f274bd132fd577def59e4fb4cTinderbox User if (anim._detach) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein anim._detach.detach();
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //anim._node[ON_TRANSITION_END] = null;
8e821eea5f57ac47a94305aa7ab0c3570d92a311Automatic Updater node.removeEventListener(TRANSITION_END, anim._onNativeEnd, false);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Animate one or more css properties to a given value. Requires the "transition" module.
* @param {Object} config An object containing one or more style properties, a duration and an easing.
prop;
config = null;
if (typeof name !== 'string' && !name.push) { // named effect or array of effects supercedes default
if (fn) {
if (callback) {
config = null;
if (typeof name !== 'string' && !name.push) { // named effect or array of effects supercedes default
this._hide();
* @param {Object} config An object containing one or more style properties, a duration and an easing.
* @param {Function} callback A function to run after the transition has completed. The callback fires
node;
name = null;
if (on) {
this._show();
node;
fadeOut: {
fadeIn: {
sizeOut: {
sizeIn: {
on: {
start: function() {
end: function() {