/src/main/resources/org/apache/struts2/static/animation/animation.js

http://struts2yuiplugin.googlecode.com/ · JavaScript · 1390 lines · 653 code · 187 blank · 550 comment · 162 complexity · 02802f2d1b66d61e46d5a02e33d8e81c MD5 · raw file

  1. /*
  2. Copyright (c) 2009, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.net/yui/license.txt
  5. version: 2.7.0
  6. */
  7. (function() {
  8. var Y = YAHOO.util;
  9. /*
  10. Copyright (c) 2006, Yahoo! Inc. All rights reserved.
  11. Code licensed under the BSD License:
  12. http://developer.yahoo.net/yui/license.txt
  13. */
  14. /**
  15. * The animation module provides allows effects to be added to HTMLElements.
  16. * @module animation
  17. * @requires yahoo, event, dom
  18. */
  19. /**
  20. *
  21. * Base animation class that provides the interface for building animated effects.
  22. * <p>Usage: var myAnim = new YAHOO.util.Anim(el, { width: { from: 10, to: 100 } }, 1, YAHOO.util.Easing.easeOut);</p>
  23. * @class Anim
  24. * @namespace YAHOO.util
  25. * @requires YAHOO.util.AnimMgr
  26. * @requires YAHOO.util.Easing
  27. * @requires YAHOO.util.Dom
  28. * @requires YAHOO.util.Event
  29. * @requires YAHOO.util.CustomEvent
  30. * @constructor
  31. * @param {String | HTMLElement} el Reference to the element that will be animated
  32. * @param {Object} attributes The attribute(s) to be animated.
  33. * Each attribute is an object with at minimum a "to" or "by" member defined.
  34. * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
  35. * All attribute names use camelCase.
  36. * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  37. * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
  38. */
  39. var Anim = function(el, attributes, duration, method) {
  40. if (!el) {
  41. }
  42. this.init(el, attributes, duration, method);
  43. };
  44. Anim.NAME = 'Anim';
  45. Anim.prototype = {
  46. /**
  47. * Provides a readable name for the Anim instance.
  48. * @method toString
  49. * @return {String}
  50. */
  51. toString: function() {
  52. var el = this.getEl() || {};
  53. var id = el.id || el.tagName;
  54. return (this.constructor.NAME + ': ' + id);
  55. },
  56. patterns: { // cached for performance
  57. noNegatives: /width|height|opacity|padding/i, // keep at zero or above
  58. offsetAttribute: /^((width|height)|(top|left))$/, // use offsetValue as default
  59. defaultUnit: /width|height|top$|bottom$|left$|right$/i, // use 'px' by default
  60. offsetUnit: /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i // IE may return these, so convert these to offset
  61. },
  62. /**
  63. * Returns the value computed by the animation's "method".
  64. * @method doMethod
  65. * @param {String} attr The name of the attribute.
  66. * @param {Number} start The value this attribute should start from for this animation.
  67. * @param {Number} end The value this attribute should end at for this animation.
  68. * @return {Number} The Value to be applied to the attribute.
  69. */
  70. doMethod: function(attr, start, end) {
  71. return this.method(this.currentFrame, start, end - start, this.totalFrames);
  72. },
  73. /**
  74. * Applies a value to an attribute.
  75. * @method setAttribute
  76. * @param {String} attr The name of the attribute.
  77. * @param {Number} val The value to be applied to the attribute.
  78. * @param {String} unit The unit ('px', '%', etc.) of the value.
  79. */
  80. setAttribute: function(attr, val, unit) {
  81. var el = this.getEl();
  82. if ( this.patterns.noNegatives.test(attr) ) {
  83. val = (val > 0) ? val : 0;
  84. }
  85. if ('style' in el) {
  86. Y.Dom.setStyle(el, attr, val + unit);
  87. } else if (attr in el) {
  88. el[attr] = val;
  89. }
  90. },
  91. /**
  92. * Returns current value of the attribute.
  93. * @method getAttribute
  94. * @param {String} attr The name of the attribute.
  95. * @return {Number} val The current value of the attribute.
  96. */
  97. getAttribute: function(attr) {
  98. var el = this.getEl();
  99. var val = Y.Dom.getStyle(el, attr);
  100. if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
  101. return parseFloat(val);
  102. }
  103. var a = this.patterns.offsetAttribute.exec(attr) || [];
  104. var pos = !!( a[3] ); // top or left
  105. var box = !!( a[2] ); // width or height
  106. if ('style' in el) {
  107. // use offsets for width/height and abs pos top/left
  108. if ( box || (Y.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
  109. val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
  110. } else { // default to zero for other 'auto'
  111. val = 0;
  112. }
  113. } else if (attr in el) {
  114. val = el[attr];
  115. }
  116. return val;
  117. },
  118. /**
  119. * Returns the unit to use when none is supplied.
  120. * @method getDefaultUnit
  121. * @param {attr} attr The name of the attribute.
  122. * @return {String} The default unit to be used.
  123. */
  124. getDefaultUnit: function(attr) {
  125. if ( this.patterns.defaultUnit.test(attr) ) {
  126. return 'px';
  127. }
  128. return '';
  129. },
  130. /**
  131. * Sets the actual values to be used during the animation. Should only be needed for subclass use.
  132. * @method setRuntimeAttribute
  133. * @param {Object} attr The attribute object
  134. * @private
  135. */
  136. setRuntimeAttribute: function(attr) {
  137. var start;
  138. var end;
  139. var attributes = this.attributes;
  140. this.runtimeAttributes[attr] = {};
  141. var isset = function(prop) {
  142. return (typeof prop !== 'undefined');
  143. };
  144. if ( !isset(attributes[attr]['to']) && !isset(attributes[attr]['by']) ) {
  145. return false; // note return; nothing to animate to
  146. }
  147. start = ( isset(attributes[attr]['from']) ) ? attributes[attr]['from'] : this.getAttribute(attr);
  148. // To beats by, per SMIL 2.1 spec
  149. if ( isset(attributes[attr]['to']) ) {
  150. end = attributes[attr]['to'];
  151. } else if ( isset(attributes[attr]['by']) ) {
  152. if (start.constructor == Array) {
  153. end = [];
  154. for (var i = 0, len = start.length; i < len; ++i) {
  155. end[i] = start[i] + attributes[attr]['by'][i] * 1; // times 1 to cast "by"
  156. }
  157. } else {
  158. end = start + attributes[attr]['by'] * 1;
  159. }
  160. }
  161. this.runtimeAttributes[attr].start = start;
  162. this.runtimeAttributes[attr].end = end;
  163. // set units if needed
  164. this.runtimeAttributes[attr].unit = ( isset(attributes[attr].unit) ) ?
  165. attributes[attr]['unit'] : this.getDefaultUnit(attr);
  166. return true;
  167. },
  168. /**
  169. * Constructor for Anim instance.
  170. * @method init
  171. * @param {String | HTMLElement} el Reference to the element that will be animated
  172. * @param {Object} attributes The attribute(s) to be animated.
  173. * Each attribute is an object with at minimum a "to" or "by" member defined.
  174. * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
  175. * All attribute names use camelCase.
  176. * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  177. * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
  178. */
  179. init: function(el, attributes, duration, method) {
  180. /**
  181. * Whether or not the animation is running.
  182. * @property isAnimated
  183. * @private
  184. * @type Boolean
  185. */
  186. var isAnimated = false;
  187. /**
  188. * A Date object that is created when the animation begins.
  189. * @property startTime
  190. * @private
  191. * @type Date
  192. */
  193. var startTime = null;
  194. /**
  195. * The number of frames this animation was able to execute.
  196. * @property actualFrames
  197. * @private
  198. * @type Int
  199. */
  200. var actualFrames = 0;
  201. /**
  202. * The element to be animated.
  203. * @property el
  204. * @private
  205. * @type HTMLElement
  206. */
  207. el = Y.Dom.get(el);
  208. /**
  209. * The collection of attributes to be animated.
  210. * Each attribute must have at least a "to" or "by" defined in order to animate.
  211. * If "to" is supplied, the animation will end with the attribute at that value.
  212. * If "by" is supplied, the animation will end at that value plus its starting value.
  213. * If both are supplied, "to" is used, and "by" is ignored.
  214. * Optional additional member include "from" (the value the attribute should start animating from, defaults to current value), and "unit" (the units to apply to the values).
  215. * @property attributes
  216. * @type Object
  217. */
  218. this.attributes = attributes || {};
  219. /**
  220. * The length of the animation. Defaults to "1" (second).
  221. * @property duration
  222. * @type Number
  223. */
  224. this.duration = !YAHOO.lang.isUndefined(duration) ? duration : 1;
  225. /**
  226. * The method that will provide values to the attribute(s) during the animation.
  227. * Defaults to "YAHOO.util.Easing.easeNone".
  228. * @property method
  229. * @type Function
  230. */
  231. this.method = method || Y.Easing.easeNone;
  232. /**
  233. * Whether or not the duration should be treated as seconds.
  234. * Defaults to true.
  235. * @property useSeconds
  236. * @type Boolean
  237. */
  238. this.useSeconds = true; // default to seconds
  239. /**
  240. * The location of the current animation on the timeline.
  241. * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
  242. * @property currentFrame
  243. * @type Int
  244. */
  245. this.currentFrame = 0;
  246. /**
  247. * The total number of frames to be executed.
  248. * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
  249. * @property totalFrames
  250. * @type Int
  251. */
  252. this.totalFrames = Y.AnimMgr.fps;
  253. /**
  254. * Changes the animated element
  255. * @method setEl
  256. */
  257. this.setEl = function(element) {
  258. el = Y.Dom.get(element);
  259. };
  260. /**
  261. * Returns a reference to the animated element.
  262. * @method getEl
  263. * @return {HTMLElement}
  264. */
  265. this.getEl = function() { return el; };
  266. /**
  267. * Checks whether the element is currently animated.
  268. * @method isAnimated
  269. * @return {Boolean} current value of isAnimated.
  270. */
  271. this.isAnimated = function() {
  272. return isAnimated;
  273. };
  274. /**
  275. * Returns the animation start time.
  276. * @method getStartTime
  277. * @return {Date} current value of startTime.
  278. */
  279. this.getStartTime = function() {
  280. return startTime;
  281. };
  282. this.runtimeAttributes = {};
  283. /**
  284. * Starts the animation by registering it with the animation manager.
  285. * @method animate
  286. */
  287. this.animate = function() {
  288. if ( this.isAnimated() ) {
  289. return false;
  290. }
  291. this.currentFrame = 0;
  292. this.totalFrames = ( this.useSeconds ) ? Math.ceil(Y.AnimMgr.fps * this.duration) : this.duration;
  293. if (this.duration === 0 && this.useSeconds) { // jump to last frame if zero second duration
  294. this.totalFrames = 1;
  295. }
  296. Y.AnimMgr.registerElement(this);
  297. return true;
  298. };
  299. /**
  300. * Stops the animation. Normally called by AnimMgr when animation completes.
  301. * @method stop
  302. * @param {Boolean} finish (optional) If true, animation will jump to final frame.
  303. */
  304. this.stop = function(finish) {
  305. if (!this.isAnimated()) { // nothing to stop
  306. return false;
  307. }
  308. if (finish) {
  309. this.currentFrame = this.totalFrames;
  310. this._onTween.fire();
  311. }
  312. Y.AnimMgr.stop(this);
  313. };
  314. var onStart = function() {
  315. this.onStart.fire();
  316. this.runtimeAttributes = {};
  317. for (var attr in this.attributes) {
  318. this.setRuntimeAttribute(attr);
  319. }
  320. isAnimated = true;
  321. actualFrames = 0;
  322. startTime = new Date();
  323. };
  324. /**
  325. * Feeds the starting and ending values for each animated attribute to doMethod once per frame, then applies the resulting value to the attribute(s).
  326. * @private
  327. */
  328. var onTween = function() {
  329. var data = {
  330. duration: new Date() - this.getStartTime(),
  331. currentFrame: this.currentFrame
  332. };
  333. data.toString = function() {
  334. return (
  335. 'duration: ' + data.duration +
  336. ', currentFrame: ' + data.currentFrame
  337. );
  338. };
  339. this.onTween.fire(data);
  340. var runtimeAttributes = this.runtimeAttributes;
  341. for (var attr in runtimeAttributes) {
  342. this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit);
  343. }
  344. actualFrames += 1;
  345. };
  346. var onComplete = function() {
  347. var actual_duration = (new Date() - startTime) / 1000 ;
  348. var data = {
  349. duration: actual_duration,
  350. frames: actualFrames,
  351. fps: actualFrames / actual_duration
  352. };
  353. data.toString = function() {
  354. return (
  355. 'duration: ' + data.duration +
  356. ', frames: ' + data.frames +
  357. ', fps: ' + data.fps
  358. );
  359. };
  360. isAnimated = false;
  361. actualFrames = 0;
  362. this.onComplete.fire(data);
  363. };
  364. /**
  365. * Custom event that fires after onStart, useful in subclassing
  366. * @private
  367. */
  368. this._onStart = new Y.CustomEvent('_start', this, true);
  369. /**
  370. * Custom event that fires when animation begins
  371. * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)
  372. * @event onStart
  373. */
  374. this.onStart = new Y.CustomEvent('start', this);
  375. /**
  376. * Custom event that fires between each frame
  377. * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)
  378. * @event onTween
  379. */
  380. this.onTween = new Y.CustomEvent('tween', this);
  381. /**
  382. * Custom event that fires after onTween
  383. * @private
  384. */
  385. this._onTween = new Y.CustomEvent('_tween', this, true);
  386. /**
  387. * Custom event that fires when animation ends
  388. * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)
  389. * @event onComplete
  390. */
  391. this.onComplete = new Y.CustomEvent('complete', this);
  392. /**
  393. * Custom event that fires after onComplete
  394. * @private
  395. */
  396. this._onComplete = new Y.CustomEvent('_complete', this, true);
  397. this._onStart.subscribe(onStart);
  398. this._onTween.subscribe(onTween);
  399. this._onComplete.subscribe(onComplete);
  400. }
  401. };
  402. Y.Anim = Anim;
  403. })();
  404. /**
  405. * Handles animation queueing and threading.
  406. * Used by Anim and subclasses.
  407. * @class AnimMgr
  408. * @namespace YAHOO.util
  409. */
  410. YAHOO.util.AnimMgr = new function() {
  411. /**
  412. * Reference to the animation Interval.
  413. * @property thread
  414. * @private
  415. * @type Int
  416. */
  417. var thread = null;
  418. /**
  419. * The current queue of registered animation objects.
  420. * @property queue
  421. * @private
  422. * @type Array
  423. */
  424. var queue = [];
  425. /**
  426. * The number of active animations.
  427. * @property tweenCount
  428. * @private
  429. * @type Int
  430. */
  431. var tweenCount = 0;
  432. /**
  433. * Base frame rate (frames per second).
  434. * Arbitrarily high for better x-browser calibration (slower browsers drop more frames).
  435. * @property fps
  436. * @type Int
  437. *
  438. */
  439. this.fps = 1000;
  440. /**
  441. * Interval delay in milliseconds, defaults to fastest possible.
  442. * @property delay
  443. * @type Int
  444. *
  445. */
  446. this.delay = 1;
  447. /**
  448. * Adds an animation instance to the animation queue.
  449. * All animation instances must be registered in order to animate.
  450. * @method registerElement
  451. * @param {object} tween The Anim instance to be be registered
  452. */
  453. this.registerElement = function(tween) {
  454. queue[queue.length] = tween;
  455. tweenCount += 1;
  456. tween._onStart.fire();
  457. this.start();
  458. };
  459. /**
  460. * removes an animation instance from the animation queue.
  461. * All animation instances must be registered in order to animate.
  462. * @method unRegister
  463. * @param {object} tween The Anim instance to be be registered
  464. * @param {Int} index The index of the Anim instance
  465. * @private
  466. */
  467. this.unRegister = function(tween, index) {
  468. index = index || getIndex(tween);
  469. if (!tween.isAnimated() || index == -1) {
  470. return false;
  471. }
  472. tween._onComplete.fire();
  473. queue.splice(index, 1);
  474. tweenCount -= 1;
  475. if (tweenCount <= 0) {
  476. this.stop();
  477. }
  478. return true;
  479. };
  480. /**
  481. * Starts the animation thread.
  482. * Only one thread can run at a time.
  483. * @method start
  484. */
  485. this.start = function() {
  486. if (thread === null) {
  487. thread = setInterval(this.run, this.delay);
  488. }
  489. };
  490. /**
  491. * Stops the animation thread or a specific animation instance.
  492. * @method stop
  493. * @param {object} tween A specific Anim instance to stop (optional)
  494. * If no instance given, Manager stops thread and all animations.
  495. */
  496. this.stop = function(tween) {
  497. if (!tween) {
  498. clearInterval(thread);
  499. for (var i = 0, len = queue.length; i < len; ++i) {
  500. this.unRegister(queue[0], 0);
  501. }
  502. queue = [];
  503. thread = null;
  504. tweenCount = 0;
  505. }
  506. else {
  507. this.unRegister(tween);
  508. }
  509. };
  510. /**
  511. * Called per Interval to handle each animation frame.
  512. * @method run
  513. */
  514. this.run = function() {
  515. for (var i = 0, len = queue.length; i < len; ++i) {
  516. var tween = queue[i];
  517. if ( !tween || !tween.isAnimated() ) { continue; }
  518. if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
  519. {
  520. tween.currentFrame += 1;
  521. if (tween.useSeconds) {
  522. correctFrame(tween);
  523. }
  524. tween._onTween.fire();
  525. }
  526. else { YAHOO.util.AnimMgr.stop(tween, i); }
  527. }
  528. };
  529. var getIndex = function(anim) {
  530. for (var i = 0, len = queue.length; i < len; ++i) {
  531. if (queue[i] == anim) {
  532. return i; // note return;
  533. }
  534. }
  535. return -1;
  536. };
  537. /**
  538. * On the fly frame correction to keep animation on time.
  539. * @method correctFrame
  540. * @private
  541. * @param {Object} tween The Anim instance being corrected.
  542. */
  543. var correctFrame = function(tween) {
  544. var frames = tween.totalFrames;
  545. var frame = tween.currentFrame;
  546. var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
  547. var elapsed = (new Date() - tween.getStartTime());
  548. var tweak = 0;
  549. if (elapsed < tween.duration * 1000) { // check if falling behind
  550. tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
  551. } else { // went over duration, so jump to end
  552. tweak = frames - (frame + 1);
  553. }
  554. if (tweak > 0 && isFinite(tweak)) { // adjust if needed
  555. if (tween.currentFrame + tweak >= frames) {// dont go past last frame
  556. tweak = frames - (frame + 1);
  557. }
  558. tween.currentFrame += tweak;
  559. }
  560. };
  561. };
  562. /**
  563. * Used to calculate Bezier splines for any number of control points.
  564. * @class Bezier
  565. * @namespace YAHOO.util
  566. *
  567. */
  568. YAHOO.util.Bezier = new function() {
  569. /**
  570. * Get the current position of the animated element based on t.
  571. * Each point is an array of "x" and "y" values (0 = x, 1 = y)
  572. * At least 2 points are required (start and end).
  573. * First point is start. Last point is end.
  574. * Additional control points are optional.
  575. * @method getPosition
  576. * @param {Array} points An array containing Bezier points
  577. * @param {Number} t A number between 0 and 1 which is the basis for determining current position
  578. * @return {Array} An array containing int x and y member data
  579. */
  580. this.getPosition = function(points, t) {
  581. var n = points.length;
  582. var tmp = [];
  583. for (var i = 0; i < n; ++i){
  584. tmp[i] = [points[i][0], points[i][1]]; // save input
  585. }
  586. for (var j = 1; j < n; ++j) {
  587. for (i = 0; i < n - j; ++i) {
  588. tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
  589. tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
  590. }
  591. }
  592. return [ tmp[0][0], tmp[0][1] ];
  593. };
  594. };
  595. (function() {
  596. /**
  597. * Anim subclass for color transitions.
  598. * <p>Usage: <code>var myAnim = new Y.ColorAnim(el, { backgroundColor: { from: '#FF0000', to: '#FFFFFF' } }, 1, Y.Easing.easeOut);</code> Color values can be specified with either 112233, #112233,
  599. * [255,255,255], or rgb(255,255,255)</p>
  600. * @class ColorAnim
  601. * @namespace YAHOO.util
  602. * @requires YAHOO.util.Anim
  603. * @requires YAHOO.util.AnimMgr
  604. * @requires YAHOO.util.Easing
  605. * @requires YAHOO.util.Bezier
  606. * @requires YAHOO.util.Dom
  607. * @requires YAHOO.util.Event
  608. * @constructor
  609. * @extends YAHOO.util.Anim
  610. * @param {HTMLElement | String} el Reference to the element that will be animated
  611. * @param {Object} attributes The attribute(s) to be animated.
  612. * Each attribute is an object with at minimum a "to" or "by" member defined.
  613. * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
  614. * All attribute names use camelCase.
  615. * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  616. * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
  617. */
  618. var ColorAnim = function(el, attributes, duration, method) {
  619. ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
  620. };
  621. ColorAnim.NAME = 'ColorAnim';
  622. ColorAnim.DEFAULT_BGCOLOR = '#fff';
  623. // shorthand
  624. var Y = YAHOO.util;
  625. YAHOO.extend(ColorAnim, Y.Anim);
  626. var superclass = ColorAnim.superclass;
  627. var proto = ColorAnim.prototype;
  628. proto.patterns.color = /color$/i;
  629. proto.patterns.rgb = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
  630. proto.patterns.hex = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
  631. proto.patterns.hex3 = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
  632. proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/; // need rgba for safari
  633. /**
  634. * Attempts to parse the given string and return a 3-tuple.
  635. * @method parseColor
  636. * @param {String} s The string to parse.
  637. * @return {Array} The 3-tuple of rgb values.
  638. */
  639. proto.parseColor = function(s) {
  640. if (s.length == 3) { return s; }
  641. var c = this.patterns.hex.exec(s);
  642. if (c && c.length == 4) {
  643. return [ parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16) ];
  644. }
  645. c = this.patterns.rgb.exec(s);
  646. if (c && c.length == 4) {
  647. return [ parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10) ];
  648. }
  649. c = this.patterns.hex3.exec(s);
  650. if (c && c.length == 4) {
  651. return [ parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16) ];
  652. }
  653. return null;
  654. };
  655. proto.getAttribute = function(attr) {
  656. var el = this.getEl();
  657. if (this.patterns.color.test(attr) ) {
  658. var val = YAHOO.util.Dom.getStyle(el, attr);
  659. var that = this;
  660. if (this.patterns.transparent.test(val)) { // bgcolor default
  661. var parent = YAHOO.util.Dom.getAncestorBy(el, function(node) {
  662. return !that.patterns.transparent.test(val);
  663. });
  664. if (parent) {
  665. val = Y.Dom.getStyle(parent, attr);
  666. } else {
  667. val = ColorAnim.DEFAULT_BGCOLOR;
  668. }
  669. }
  670. } else {
  671. val = superclass.getAttribute.call(this, attr);
  672. }
  673. return val;
  674. };
  675. proto.doMethod = function(attr, start, end) {
  676. var val;
  677. if ( this.patterns.color.test(attr) ) {
  678. val = [];
  679. for (var i = 0, len = start.length; i < len; ++i) {
  680. val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);
  681. }
  682. val = 'rgb('+Math.floor(val[0])+','+Math.floor(val[1])+','+Math.floor(val[2])+')';
  683. }
  684. else {
  685. val = superclass.doMethod.call(this, attr, start, end);
  686. }
  687. return val;
  688. };
  689. proto.setRuntimeAttribute = function(attr) {
  690. superclass.setRuntimeAttribute.call(this, attr);
  691. if ( this.patterns.color.test(attr) ) {
  692. var attributes = this.attributes;
  693. var start = this.parseColor(this.runtimeAttributes[attr].start);
  694. var end = this.parseColor(this.runtimeAttributes[attr].end);
  695. // fix colors if going "by"
  696. if ( typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined' ) {
  697. end = this.parseColor(attributes[attr].by);
  698. for (var i = 0, len = start.length; i < len; ++i) {
  699. end[i] = start[i] + end[i];
  700. }
  701. }
  702. this.runtimeAttributes[attr].start = start;
  703. this.runtimeAttributes[attr].end = end;
  704. }
  705. };
  706. Y.ColorAnim = ColorAnim;
  707. })();
  708. /*!
  709. TERMS OF USE - EASING EQUATIONS
  710. Open source under the BSD License.
  711. Copyright 2001 Robert Penner All rights reserved.
  712. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  713. * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  714. * 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.
  715. * 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.
  716. 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.
  717. */
  718. /**
  719. * Singleton that determines how an animation proceeds from start to end.
  720. * @class Easing
  721. * @namespace YAHOO.util
  722. */
  723. YAHOO.util.Easing = {
  724. /**
  725. * Uniform speed between points.
  726. * @method easeNone
  727. * @param {Number} t Time value used to compute current value
  728. * @param {Number} b Starting value
  729. * @param {Number} c Delta between start and end values
  730. * @param {Number} d Total length of animation
  731. * @return {Number} The computed value for the current animation frame
  732. */
  733. easeNone: function (t, b, c, d) {
  734. return c*t/d + b;
  735. },
  736. /**
  737. * Begins slowly and accelerates towards end.
  738. * @method easeIn
  739. * @param {Number} t Time value used to compute current value
  740. * @param {Number} b Starting value
  741. * @param {Number} c Delta between start and end values
  742. * @param {Number} d Total length of animation
  743. * @return {Number} The computed value for the current animation frame
  744. */
  745. easeIn: function (t, b, c, d) {
  746. return c*(t/=d)*t + b;
  747. },
  748. /**
  749. * Begins quickly and decelerates towards end.
  750. * @method easeOut
  751. * @param {Number} t Time value used to compute current value
  752. * @param {Number} b Starting value
  753. * @param {Number} c Delta between start and end values
  754. * @param {Number} d Total length of animation
  755. * @return {Number} The computed value for the current animation frame
  756. */
  757. easeOut: function (t, b, c, d) {
  758. return -c *(t/=d)*(t-2) + b;
  759. },
  760. /**
  761. * Begins slowly and decelerates towards end.
  762. * @method easeBoth
  763. * @param {Number} t Time value used to compute current value
  764. * @param {Number} b Starting value
  765. * @param {Number} c Delta between start and end values
  766. * @param {Number} d Total length of animation
  767. * @return {Number} The computed value for the current animation frame
  768. */
  769. easeBoth: function (t, b, c, d) {
  770. if ((t/=d/2) < 1) {
  771. return c/2*t*t + b;
  772. }
  773. return -c/2 * ((--t)*(t-2) - 1) + b;
  774. },
  775. /**
  776. * Begins slowly and accelerates towards end.
  777. * @method easeInStrong
  778. * @param {Number} t Time value used to compute current value
  779. * @param {Number} b Starting value
  780. * @param {Number} c Delta between start and end values
  781. * @param {Number} d Total length of animation
  782. * @return {Number} The computed value for the current animation frame
  783. */
  784. easeInStrong: function (t, b, c, d) {
  785. return c*(t/=d)*t*t*t + b;
  786. },
  787. /**
  788. * Begins quickly and decelerates towards end.
  789. * @method easeOutStrong
  790. * @param {Number} t Time value used to compute current value
  791. * @param {Number} b Starting value
  792. * @param {Number} c Delta between start and end values
  793. * @param {Number} d Total length of animation
  794. * @return {Number} The computed value for the current animation frame
  795. */
  796. easeOutStrong: function (t, b, c, d) {
  797. return -c * ((t=t/d-1)*t*t*t - 1) + b;
  798. },
  799. /**
  800. * Begins slowly and decelerates towards end.
  801. * @method easeBothStrong
  802. * @param {Number} t Time value used to compute current value
  803. * @param {Number} b Starting value
  804. * @param {Number} c Delta between start and end values
  805. * @param {Number} d Total length of animation
  806. * @return {Number} The computed value for the current animation frame
  807. */
  808. easeBothStrong: function (t, b, c, d) {
  809. if ((t/=d/2) < 1) {
  810. return c/2*t*t*t*t + b;
  811. }
  812. return -c/2 * ((t-=2)*t*t*t - 2) + b;
  813. },
  814. /**
  815. * Snap in elastic effect.
  816. * @method elasticIn
  817. * @param {Number} t Time value used to compute current value
  818. * @param {Number} b Starting value
  819. * @param {Number} c Delta between start and end values
  820. * @param {Number} d Total length of animation
  821. * @param {Number} a Amplitude (optional)
  822. * @param {Number} p Period (optional)
  823. * @return {Number} The computed value for the current animation frame
  824. */
  825. elasticIn: function (t, b, c, d, a, p) {
  826. if (t == 0) {
  827. return b;
  828. }
  829. if ( (t /= d) == 1 ) {
  830. return b+c;
  831. }
  832. if (!p) {
  833. p=d*.3;
  834. }
  835. if (!a || a < Math.abs(c)) {
  836. a = c;
  837. var s = p/4;
  838. }
  839. else {
  840. var s = p/(2*Math.PI) * Math.asin (c/a);
  841. }
  842. return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
  843. },
  844. /**
  845. * Snap out elastic effect.
  846. * @method elasticOut
  847. * @param {Number} t Time value used to compute current value
  848. * @param {Number} b Starting value
  849. * @param {Number} c Delta between start and end values
  850. * @param {Number} d Total length of animation
  851. * @param {Number} a Amplitude (optional)
  852. * @param {Number} p Period (optional)
  853. * @return {Number} The computed value for the current animation frame
  854. */
  855. elasticOut: function (t, b, c, d, a, p) {
  856. if (t == 0) {
  857. return b;
  858. }
  859. if ( (t /= d) == 1 ) {
  860. return b+c;
  861. }
  862. if (!p) {
  863. p=d*.3;
  864. }
  865. if (!a || a < Math.abs(c)) {
  866. a = c;
  867. var s = p / 4;
  868. }
  869. else {
  870. var s = p/(2*Math.PI) * Math.asin (c/a);
  871. }
  872. return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
  873. },
  874. /**
  875. * Snap both elastic effect.
  876. * @method elasticBoth
  877. * @param {Number} t Time value used to compute current value
  878. * @param {Number} b Starting value
  879. * @param {Number} c Delta between start and end values
  880. * @param {Number} d Total length of animation
  881. * @param {Number} a Amplitude (optional)
  882. * @param {Number} p Period (optional)
  883. * @return {Number} The computed value for the current animation frame
  884. */
  885. elasticBoth: function (t, b, c, d, a, p) {
  886. if (t == 0) {
  887. return b;
  888. }
  889. if ( (t /= d/2) == 2 ) {
  890. return b+c;
  891. }
  892. if (!p) {
  893. p = d*(.3*1.5);
  894. }
  895. if ( !a || a < Math.abs(c) ) {
  896. a = c;
  897. var s = p/4;
  898. }
  899. else {
  900. var s = p/(2*Math.PI) * Math.asin (c/a);
  901. }
  902. if (t < 1) {
  903. return -.5*(a*Math.pow(2,10*(t-=1)) *
  904. Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
  905. }
  906. return a*Math.pow(2,-10*(t-=1)) *
  907. Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
  908. },
  909. /**
  910. * Backtracks slightly, then reverses direction and moves to end.
  911. * @method backIn
  912. * @param {Number} t Time value used to compute current value
  913. * @param {Number} b Starting value
  914. * @param {Number} c Delta between start and end values
  915. * @param {Number} d Total length of animation
  916. * @param {Number} s Overshoot (optional)
  917. * @return {Number} The computed value for the current animation frame
  918. */
  919. backIn: function (t, b, c, d, s) {
  920. if (typeof s == 'undefined') {
  921. s = 1.70158;
  922. }
  923. return c*(t/=d)*t*((s+1)*t - s) + b;
  924. },
  925. /**
  926. * Overshoots end, then reverses and comes back to end.
  927. * @method backOut
  928. * @param {Number} t Time value used to compute current value
  929. * @param {Number} b Starting value
  930. * @param {Number} c Delta between start and end values
  931. * @param {Number} d Total length of animation
  932. * @param {Number} s Overshoot (optional)
  933. * @return {Number} The computed value for the current animation frame
  934. */
  935. backOut: function (t, b, c, d, s) {
  936. if (typeof s == 'undefined') {
  937. s = 1.70158;
  938. }
  939. return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
  940. },
  941. /**
  942. * Backtracks slightly, then reverses direction, overshoots end,
  943. * then reverses and comes back to end.
  944. * @method backBoth
  945. * @param {Number} t Time value used to compute current value
  946. * @param {Number} b Starting value
  947. * @param {Number} c Delta between start and end values
  948. * @param {Number} d Total length of animation
  949. * @param {Number} s Overshoot (optional)
  950. * @return {Number} The computed value for the current animation frame
  951. */
  952. backBoth: function (t, b, c, d, s) {
  953. if (typeof s == 'undefined') {
  954. s = 1.70158;
  955. }
  956. if ((t /= d/2 ) < 1) {
  957. return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
  958. }
  959. return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
  960. },
  961. /**
  962. * Bounce off of start.
  963. * @method bounceIn
  964. * @param {Number} t Time value used to compute current value
  965. * @param {Number} b Starting value
  966. * @param {Number} c Delta between start and end values
  967. * @param {Number} d Total length of animation
  968. * @return {Number} The computed value for the current animation frame
  969. */
  970. bounceIn: function (t, b, c, d) {
  971. return c - YAHOO.util.Easing.bounceOut(d-t, 0, c, d) + b;
  972. },
  973. /**
  974. * Bounces off end.
  975. * @method bounceOut
  976. * @param {Number} t Time value used to compute current value
  977. * @param {Number} b Starting value
  978. * @param {Number} c Delta between start and end values
  979. * @param {Number} d Total length of animation
  980. * @return {Number} The computed value for the current animation frame
  981. */
  982. bounceOut: function (t, b, c, d) {
  983. if ((t/=d) < (1/2.75)) {
  984. return c*(7.5625*t*t) + b;
  985. } else if (t < (2/2.75)) {
  986. return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
  987. } else if (t < (2.5/2.75)) {
  988. return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
  989. }
  990. return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
  991. },
  992. /**
  993. * Bounces off start and end.
  994. * @method bounceBoth
  995. * @param {Number} t Time value used to compute current value
  996. * @param {Number} b Starting value
  997. * @param {Number} c Delta between start and end values
  998. * @param {Number} d Total length of animation
  999. * @return {Number} The computed value for the current animation frame
  1000. */
  1001. bounceBoth: function (t, b, c, d) {
  1002. if (t < d/2) {
  1003. return YAHOO.util.Easing.bounceIn(t*2, 0, c, d) * .5 + b;
  1004. }
  1005. return YAHOO.util.Easing.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
  1006. }
  1007. };
  1008. (function() {
  1009. /**
  1010. * Anim subclass for moving elements along a path defined by the "points"
  1011. * member of "attributes". All "points" are arrays with x, y coordinates.
  1012. * <p>Usage: <code>var myAnim = new YAHOO.util.Motion(el, { points: { to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
  1013. * @class Motion
  1014. * @namespace YAHOO.util
  1015. * @requires YAHOO.util.Anim
  1016. * @requires YAHOO.util.AnimMgr
  1017. * @requires YAHOO.util.Easing
  1018. * @requires YAHOO.util.Bezier
  1019. * @requires YAHOO.util.Dom
  1020. * @requires YAHOO.util.Event
  1021. * @requires YAHOO.util.CustomEvent
  1022. * @constructor
  1023. * @extends YAHOO.util.ColorAnim
  1024. * @param {String | HTMLElement} el Reference to the element that will be animated
  1025. * @param {Object} attributes The attribute(s) to be animated.
  1026. * Each attribute is an object with at minimum a "to" or "by" member defined.
  1027. * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
  1028. * All attribute names use camelCase.
  1029. * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  1030. * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
  1031. */
  1032. var Motion = function(el, attributes, duration, method) {
  1033. if (el) { // dont break existing subclasses not using YAHOO.extend
  1034. Motion.superclass.constructor.call(this, el, attributes, duration, method);
  1035. }
  1036. };
  1037. Motion.NAME = 'Motion';
  1038. // shorthand
  1039. var Y = YAHOO.util;
  1040. YAHOO.extend(Motion, Y.ColorAnim);
  1041. var superclass = Motion.superclass;
  1042. var proto = Motion.prototype;
  1043. proto.patterns.points = /^points$/i;
  1044. proto.setAttribute = function(attr, val, unit) {
  1045. if ( this.patterns.points.test(attr) ) {
  1046. unit = unit || 'px';
  1047. superclass.setAttribute.call(this, 'left', val[0], unit);
  1048. superclass.setAttribute.call(this, 'top', val[1], unit);
  1049. } else {
  1050. superclass.setAttribute.call(this, attr, val, unit);
  1051. }
  1052. };
  1053. proto.getAttribute = function(attr) {
  1054. if ( this.patterns.points.test(attr) ) {
  1055. var val = [
  1056. superclass.getAttribute.call(this, 'left'),
  1057. superclass.getAttribute.call(this, 'top')
  1058. ];
  1059. } else {
  1060. val = superclass.getAttribute.call(this, attr);
  1061. }
  1062. return val;
  1063. };
  1064. proto.doMethod = function(attr, start, end) {
  1065. var val = null;
  1066. if ( this.patterns.points.test(attr) ) {
  1067. var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;
  1068. val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);
  1069. } else {
  1070. val = superclass.doMethod.call(this, attr, start, end);
  1071. }
  1072. return val;
  1073. };
  1074. proto.setRuntimeAttribute = function(attr) {
  1075. if ( this.patterns.points.test(attr) ) {
  1076. var el = this.getEl();
  1077. var attributes = this.attributes;
  1078. var start;
  1079. var control = attributes['points']['control'] || [];
  1080. var end;
  1081. var i, len;
  1082. if (control.length > 0 && !(control[0] instanceof Array) ) { // could be single point or array of points
  1083. control = [control];
  1084. } else { // break reference to attributes.points.control
  1085. var tmp = [];
  1086. for (i = 0, len = control.length; i< len; ++i) {
  1087. tmp[i] = control[i];
  1088. }
  1089. control = tmp;
  1090. }
  1091. if (Y.Dom.getStyle(el, 'position') == 'static') { // default to relative
  1092. Y.Dom.setStyle(el, 'position', 'relative');
  1093. }
  1094. if ( isset(attributes['points']['from']) ) {
  1095. Y.Dom.setXY(el, attributes['points']['from']); // set position to from point
  1096. }
  1097. else { Y.Dom.setXY( el, Y.Dom.getXY(el) ); } // set it to current position
  1098. start = this.getAttribute('points'); // get actual top & left
  1099. // TO beats BY, per SMIL 2.1 spec
  1100. if ( isset(attributes['points']['to']) ) {
  1101. end = translateValues.call(this, attributes['points']['to'], start);
  1102. var pageXY = Y.Dom.getXY(this.getEl());
  1103. for (i = 0, len = control.length; i < len; ++i) {
  1104. control[i] = translateValues.call(this, control[i], start);
  1105. }
  1106. } else if ( isset(attributes['points']['by']) ) {
  1107. end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1] ];
  1108. for (i = 0, len = control.length; i < len; ++i) {
  1109. control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
  1110. }
  1111. }
  1112. this.runtimeAttributes[attr] = [start];
  1113. if (control.length > 0) {
  1114. this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control);
  1115. }
  1116. this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;
  1117. }
  1118. else {
  1119. superclass.setRuntimeAttribute.call(this, attr);
  1120. }
  1121. };
  1122. var translateValues = function(val, start) {
  1123. var pageXY = Y.Dom.getXY(this.getEl());
  1124. val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];
  1125. return val;
  1126. };
  1127. var isset = function(prop) {
  1128. return (typeof prop !== 'undefined');
  1129. };
  1130. Y.Motion = Motion;
  1131. })();
  1132. (function() {
  1133. /**
  1134. * Anim subclass for scrolling elements to a position defined by the "scroll"
  1135. * member of "attributes". All "scroll" members are arrays with x, y scroll positions.
  1136. * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
  1137. * @class Scroll
  1138. * @namespace YAHOO.util
  1139. * @requires YAHOO.util.Anim
  1140. * @requires YAHOO.util.AnimMgr
  1141. * @requires YAHOO.util.Easing
  1142. * @requires YAHOO.util.Bezier
  1143. * @requires YAHOO.util.Dom
  1144. * @requires YAHOO.util.Event
  1145. * @requires YAHOO.util.CustomEvent
  1146. * @extends YAHOO.util.ColorAnim
  1147. * @constructor
  1148. * @param {String or HTMLElement} el Reference to the element that will be animated
  1149. * @param {Object} attributes The attribute(s) to be animated.
  1150. * Each attribute is an object with at minimum a "to" or "by" member defined.
  1151. * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
  1152. * All attribute names use camelCase.
  1153. * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  1154. * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
  1155. */
  1156. var Scroll = function(el, attributes, duration, method) {
  1157. if (el) { // dont break existing subclasses not using YAHOO.extend
  1158. Scroll.superclass.constructor.call(this, el, attributes, duration, method);
  1159. }
  1160. };
  1161. Scroll.NAME = 'Scroll';
  1162. // shorthand
  1163. var Y = YAHOO.util;
  1164. YAHOO.extend(Scroll, Y.ColorAnim);
  1165. var superclass = Scroll.superclass;
  1166. var proto = Scroll.prototype;
  1167. proto.doMethod = function(attr, start, end) {
  1168. var val = null;
  1169. if (attr == 'scroll') {
  1170. val = [
  1171. this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),
  1172. this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)
  1173. ];
  1174. } else {
  1175. val = superclass.doMethod.call(this, attr, start, end);
  1176. }
  1177. return val;
  1178. };
  1179. proto.getAttribute = function(attr) {
  1180. var val = null;
  1181. var el = this.getEl();
  1182. if (attr == 'scroll') {
  1183. val = [ el.scrollLeft, el.scrollTop ];
  1184. } else {
  1185. val = superclass.getAttribute.call(this, attr);
  1186. }
  1187. return val;
  1188. };
  1189. proto.setAttribute = function(attr, val, unit) {
  1190. var el = this.getEl();
  1191. if (attr == 'scroll') {
  1192. el.scrollLeft = val[0];
  1193. el.scrollTop = val[1];
  1194. } else {
  1195. superclass.setAttribute.call(this, attr, val, unit);
  1196. }
  1197. };
  1198. Y.Scroll = Scroll;
  1199. })();
  1200. YAHOO.register("animation", YAHOO.util.Anim, {version: "2.7.0", build: "1799"});