]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/javascript/yui/build/progressbar/progressbar.js
Release 6.2.0beta4
[Github/sugarcrm.git] / include / javascript / yui / build / progressbar / progressbar.js
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.8.0r4
6 */
7 /**
8  *
9  * @module progressbar
10  * @requires yahoo, dom, event, element
11  * @optional animation
12  * @title ProgressBar Widget
13  */
14
15 (function () {
16         var Dom = YAHOO.util.Dom,
17                 Lang = YAHOO.lang,
18                 // ClassNames
19                 CLASS_PROGBAR = 'yui-pb',
20                 CLASS_MASK = CLASS_PROGBAR + '-mask',
21                 CLASS_BAR = CLASS_PROGBAR + '-bar',
22                 CLASS_ANIM = CLASS_PROGBAR + '-anim',
23                 CLASS_TL = CLASS_PROGBAR + '-tl',
24                 CLASS_TR = CLASS_PROGBAR + '-tr',
25                 CLASS_BL = CLASS_PROGBAR + '-bl',
26                 CLASS_BR = CLASS_PROGBAR + '-br',
27                 
28                 // Configuration attributes
29                 WIDTH = 'width',
30                 HEIGHT = 'height',
31                 MIN_VALUE = 'minValue',
32                 MAX_VALUE = 'maxValue',
33                 VALUE = 'value',
34                 ANIM = 'anim',
35                 DIRECTION = 'direction',
36                 DIRECTION_LTR = 'ltr',
37                 DIRECTION_RTL = 'rtl',
38                 DIRECTION_TTB = 'ttb',
39                 DIRECTION_BTT = 'btt',
40                 BAR_EL = 'barEl',
41                 MASK_EL = 'maskEl',
42                 ARIA_TEXT_TEMPLATE = 'ariaTextTemplate',
43                 
44                 // Events
45                 START = 'start',
46                 PROGRESS = 'progress',
47                 COMPLETE = 'complete';
48         
49         /**
50          * The ProgressBar widget provides an easy way to draw a bar depicting progress of an operation,
51          * a level meter, rating or any such simple linear measure.
52          * It allows for highly customized styles including animation, vertical or horizontal and forward or reverse.
53          * @namespace YAHOO.widget
54          * @class ProgressBar
55          * @extends YAHOO.util.Element
56          * @param oConfigs {object} An object containing any configuration attributes to be set 
57          * @constructor
58          */        
59         var Prog = function(oConfigs) {
60         
61                 Prog.superclass.constructor.call(this, document.createElement('div') , oConfigs);
62                 this._init(oConfigs);
63                 
64         };
65         
66         YAHOO.widget.ProgressBar = Prog;
67
68     /**
69      * String containing the HTML string which is the basis for the Progress Bar.
70      *
71      * @property ProgressBar.MARKUP
72      * @type String
73      * @static
74      * @final
75      * @default (too long)
76      */
77         Prog.MARKUP = [
78                 '<div class="',
79                 CLASS_BAR,
80                 '"></div><div class="',
81                 CLASS_MASK,
82                 '"><div class="',
83                 CLASS_TL,
84                 '"></div><div class="',
85                 CLASS_TR,
86                 '"></div><div class="',
87                 CLASS_BL,
88                 '"></div><div class="',
89                 CLASS_BR,
90                 '"></div></div>'
91         ].join('');
92
93         
94         Lang.extend(Prog, YAHOO.util.Element, {
95                 /**
96                  * Initialization code for the widget, separate from the constructor to allow for overriding/patching.
97                  * It is called after <a href="#method_initAttributes">initAttributes</a>
98                  *
99                  * @method _init
100                  * @param oConfigs {Object} (Optional) Object literal definition of configuration values.  
101                  * @protected
102                  */     
103                  _init: function (oConfigs) {
104                         /**
105                          * Fires when the value is about to change.  It reports the starting value
106                          * @event start
107                          * @type CustomEvent
108                          * @param value {Number} the current (initial) value
109                          */
110                         // No actual creation required, event will be created when subscribed to
111                         //this.createEvent(START);
112                         /**
113                          * If animation is active, it will trigger several times during the animation providing intermediate values
114                          * If animation is not active, it will fire only once providing the end value
115                          * @event progress
116                          * @type CustomEvent
117                          * @param  value{Number} the current, changing value
118                          */
119                         // No actual creation required, event will be created when subscribed to
120                         //this.createEvent(PROGRESS);
121                         /**
122                          * Fires at the end of the animation or immediately upon changing values if animation is not loaded
123                          * @event complete
124                          * @type CustomEvent
125                          * @param value {Number} the current (final)  value
126                          */
127                         // No actual creation required, event will be created when listened to
128                         //this.createEvent(COMPLETE);
129                         
130
131                 },
132                 /**
133                  * Implementation of Element's abstract method. Sets up config values.
134                  *
135                  * @method initAttributes
136                  * @param oConfigs {Object} (Optional) Object literal definition of configuration values.
137                  * @private
138                  */     
139                 initAttributes: function (oConfigs) {
140
141                     Prog.superclass.initAttributes.call(this, oConfigs);
142                         this.set('innerHTML',Prog.MARKUP);
143                         this.addClass(CLASS_PROGBAR);
144                         
145                         // I need to apply at least the following styles, if present in oConfigs, 
146                         // to the ProgressBar so when it later reads the width and height, 
147                         // they are already set to the correct values.
148                         // id is important because it can be used as a CSS selector.
149                         var key, presets = ['id',WIDTH,HEIGHT,'class','style'];
150                         while((key = presets.pop())) {
151                                 if (key in oConfigs) {
152                                         this.set(key,oConfigs[key]);
153                                 }
154                         }
155                         
156
157                         /**
158                          * @attribute barEl
159                          * @description Reference to the HTML object that makes the moving bar (read-only)
160                          * @type HTMLElement (div)
161                          * @readonly
162                          */                     
163                     this.setAttributeConfig(BAR_EL, {
164                         readOnly: true,
165                         value: this.getElementsByClassName(CLASS_BAR)[0]
166                     });
167                         /**
168                          * @attribute maskEl
169                          * @description Reference to the HTML object that overlays the bar providing the mask. (read-only)
170                          * @type HTMLElement (table)
171                          * @readonly
172                          */                     
173                     this.setAttributeConfig(MASK_EL, {
174                         readOnly: true,
175                         value: this.getElementsByClassName(CLASS_MASK)[0]
176                     });
177                         
178                         
179                         /**
180                          * @attribute direction
181                          * @description Direction of movement of the bar.  
182                          *    It can be any of 'ltr' (left to right), 'rtl' (the reverse) , 'ttb' (top to bottom) or 'btt'.
183                          *    Can only be set once and only before rendering.
184                          * @default 'ltr'
185                          * @type String (any of "ltr", "rtl", "ttb" or "btt")
186                          */                     
187                         this.setAttributeConfig(DIRECTION, {
188                                 value:DIRECTION_LTR,
189                                 validator:function(value) {
190                                         if (this._rendered) { return false; }
191                                         switch (value) {
192                                                 case DIRECTION_LTR:
193                                                 case DIRECTION_RTL:
194                                                 case DIRECTION_TTB:
195                                                 case DIRECTION_BTT:
196                                                         return true;
197                                                 default:
198                                                         return false;
199                                         }
200                                 },
201                                 method: function(value) {
202                                         this._barSizeFunction = this._barSizeFunctions[this.get(ANIM)?1:0][value];
203                                 }
204                         });
205                         
206                         /**
207                          * @attribute maxValue
208                          * @description Represents the top value for the bar. 
209                          *   The bar will be fully extended when reaching this value.  
210                          *   Values higher than this will be ignored. 
211                          * @default 100
212                          * @type Number
213                          */                                 
214                     this.setAttributeConfig(MAX_VALUE, {
215                         value: 100,
216                                 validator: Lang.isNumber,
217                                 method: function (value) {
218                                         this.get('element').setAttribute('aria-valuemax',value);
219                                         if (this.get(VALUE) > value) { this.set(VALUE,value); }
220                                 }
221                     });
222                         
223                         /**
224                          * @attribute minValue
225                          * @description Represents the lowest value for the bar. 
226                          *   The bar will be totally collapsed when reaching this value.  
227                          *    Values lower than this will be ignored. 
228                          * @default 0
229                          * @type Number
230                          */                             
231
232                     this.setAttributeConfig(MIN_VALUE, {
233                         value: 0,
234                                 validator: Lang.isNumber,
235                                 method: function (value) {
236                                         this.get('element').setAttribute('aria-valuemin',value);
237                                         if (this.get(VALUE) < value) { this.set(VALUE,value); }
238                                 }
239                     });
240                         /**
241                          * @attribute width
242                          * @description Width of the ProgressBar.
243                          *     If a number, it will be assumed to be in pixels.  
244                          *     If a string it should be a valid setting for the CSS width attribute.  
245                          *     It will always be returned as a string including units.
246                          * @default "200px"
247                          * @type Number or String
248                          */                             
249
250                     this.setAttributeConfig(WIDTH, {
251                                 getter: function() {
252                                         return this.getStyle(WIDTH);
253                                 },
254                                 method: this._widthChange
255                     });
256                 
257
258                         /**
259                          * @attribute height
260                          * @description Height of the ProgressBar.
261                          *     If a number, it will be assumed to be in pixels.  
262                          *     If a string it should be a valid setting for the CSS height attribute.  
263                          *     It will always be returned as a string including units.
264                          * @default "20px"
265                          * @type Number or String
266                          */                             
267                     this.setAttributeConfig(HEIGHT, {
268                                 getter:function() {
269                                         return this.getStyle(HEIGHT);
270                                 },
271                                 method: this._heightChange
272                     });
273                         
274                         
275         
276                         /**
277                          * @attribute ariaTextTemplate 
278                          * @description Text to be voiced by screen readers.
279                          *     The text is processed by <a href="YAHOO.lang.html#method_substitute">YAHOO.lang.substitute</a>.  
280                          *     It can use the placeholders {value}, {minValue} and {maxValue}
281                          * @default "{value}"
282                          * @type String
283                          */                             
284                         this.setAttributeConfig(ARIA_TEXT_TEMPLATE, {
285                                 value:'{value}'
286                         });
287                         
288                         /**
289                          * @attribute value
290                          * @description The value for the bar.  
291                          *     Valid values are in between the minValue and maxValue attributes.
292                          * @default 0
293                          * @type Number
294                          */                     
295                         this.setAttributeConfig(VALUE, {
296                                 value: 0,
297                                 validator: function(value) {
298                                         return Lang.isNumber(value) && value >= this.get(MIN_VALUE) && value <= this.get(MAX_VALUE);
299                                 },
300                                 method: this._valueChange
301                     });
302                         
303                         /**
304                          * @attribute anim
305                          * @description it accepts either a boolean (recommended) or an instance of <a href="YAHOO.util.Anim.html">YAHOO.util.Anim</a>.
306                          *   If a boolean, it will enable/disable animation creating its own instance of the animation utility.  
307                          *   If given an instance of <a href="YAHOO.util.Anim.html">YAHOO.util.Anim</a> it will use that instance.
308                          *   The <a href="YAHOO.util.Anim.html">animation</a> utility needs to be loaded.
309                          *   When read, it returns the instance of the animation utility in use or null if none.  
310                          *   It can be used to set the animation parameters such as easing methods or duration.
311                          * @default null
312                          * @type {boolean} or {instance of YAHOO.util.Anim}
313                          */                                             
314                         this.setAttributeConfig(ANIM, {
315                                 validator: function(value) {
316                                         return !!YAHOO.util.Anim;
317                                 },
318                                 setter: this._animSetter
319                         });
320                         
321                         
322                 },
323                 /** 
324                  *  Renders the ProgressBar into the given container.  
325                  *  If the container has other content, the ProgressBar will be appended to it.
326                  *  If the second argument is provided, the ProgressBar will be inserted before the given child.
327                  * The method is chainable since it returns a reference to this instance.
328                  * @method render
329                  * @param el {HTML Element}  HTML element that will contain the ProgressBar
330                  * @param before {HTML Element}  (optional) If present, the ProgressBar will be inserted before this element.
331                  * @return {YAHOO.widget.ProgressBar}
332                  * @chainable
333                  */
334                 render: function(parent,before) {
335
336                         if (this._rendered) { return; }
337                         this._rendered = true;
338                         
339                         var direction = this.get(DIRECTION);
340
341                         // If the developer set a className attribute on initialization, 
342                         // Element would have wiped out my own classNames
343                         // So I need to insist on them, plus add the one for direction.
344                         this.addClass(CLASS_PROGBAR);
345                         this.addClass(CLASS_PROGBAR + '-' + direction);
346
347                         var container = this.get('element');
348                         container.tabIndex = 0;
349                         container.setAttribute('role','progressbar');
350                         container.setAttribute('aria-valuemin',this.get(MIN_VALUE));
351                         container.setAttribute('aria-valuemax',this.get(MAX_VALUE));
352
353                         this.appendTo(parent,before);
354                         
355                                         
356                         // I need to use the non-animated bar resizing function for initial redraw
357                         this._barSizeFunction = this._barSizeFunctions[0][direction];
358                         this.redraw();
359                         this._previousValue = this.get(VALUE);
360                         this._fixEdges();
361                         // I can now set the correct bar resizer
362                         if (this.get(ANIM)) {
363                                 this._barSizeFunction = this._barSizeFunctions[1][direction];
364                         }
365
366                         this.on('minValueChange',this.redraw);
367                         this.on('maxValueChange',this.redraw);
368
369                         return this;
370                 },
371
372                 /** 
373                  * Recalculates the bar size and position and redraws it
374                  * @method redraw
375                  * @return  void
376                  */
377                 redraw: function () {
378                         this._recalculateConstants();
379                         this._valueChange(this.get(VALUE));
380                 },
381                         
382                 /** 
383                  * Destroys the ProgressBar, related objects and unsubscribes from all events
384                  * @method destroy
385                  * @return  void
386                  */
387                 destroy: function() {
388                         this.set(ANIM,false);
389                         this.unsubscribeAll();
390                         var el = this.get('element');
391                         if (el.parentNode) { el.parentNode.removeChild(el); }
392                 },
393                 /**
394                  * The previous value setting for the bar.  Used mostly as information to event listeners
395                  * @property _previousValue
396                  * @type Number
397                  * @private
398                  * @default  0
399                  */
400                 _previousValue:0,
401                 /**
402                  * The actual space (in pixels) available for the bar within the mask (excludes margins)
403                  * @property _barSpace
404                  * @type Number
405                  * @private
406                  * @default  100
407                  */
408                 _barSpace:100,
409                 /**
410                  * The factor to convert the actual value of the bar into pixels
411                  * @property _barSpace
412                  * @type Number
413                  * @private
414                  * @default  1
415                  */
416                 _barFactor:1,
417                 
418                 /**
419                  * A flag to signal that rendering has already happened
420                  * @property _rendered
421                  * @type boolean
422                  * @private
423                  * @default  false
424                  */
425                 _rendered:false,
426                 
427                 /**
428                  * Function to be used to calculate bar size.  
429                  * It is picked from <a href="#property_barSizeFunctions">_barSizeFunctions</a>
430                  * depending on direction and whether animation is active.
431                  * @property _barSizeFunction
432                  * @type {function}
433                  * @default null
434                  * @private
435                  */             
436                 _barSizeFunction: null,
437                 
438                 /** 
439                  * Method called when the height attribute is changed
440                  * @method _heightChange
441                  * @param {int or string} value New height, in pixels if int or string including units
442                  * @return void
443                  * @private
444                  */
445                 _heightChange: function(value) {
446                         if (Lang.isNumber(value)) {
447                                 value += 'px';
448                         }
449                         this.setStyle(HEIGHT,value);
450                         this._fixEdges();
451                         this.redraw();
452                 },
453
454                 /** 
455                  * Method called when the height attribute is changed
456                  * @method _widthChange
457                  * @param {int or string} value New width, in pixels if int or string including units
458                  * @return void
459                  * @private
460                  */
461                 _widthChange: function(value) {
462                         if (Lang.isNumber(value)) {
463                                 value += 'px';
464                         }
465                         this.setStyle(WIDTH,value);
466                         this._fixEdges();
467                         this.redraw();
468                 },
469                 
470                 /** 
471                  * Due to rounding differences, some browsers fail to cover the whole area 
472                  * with the mask quadrants when the width or height is odd.  This method
473                  * stretches the lower and/or right quadrants to make the difference.
474                  * @method _fixEdges
475                  * @return void
476                  * @private
477                  */
478                 _fixEdges:function() {
479                         if (!this._rendered || YAHOO.env.ua.ie || YAHOO.env.ua.gecko ) { return; }
480                         var maskEl = this.get(MASK_EL),
481                                 tlEl = Dom.getElementsByClassName(CLASS_TL,undefined,maskEl)[0],
482                                 trEl = Dom.getElementsByClassName(CLASS_TR,undefined,maskEl)[0],
483                                 blEl = Dom.getElementsByClassName(CLASS_BL,undefined,maskEl)[0],
484                                 brEl = Dom.getElementsByClassName(CLASS_BR,undefined,maskEl)[0],
485                                 newSize = (parseInt(Dom.getStyle(maskEl,HEIGHT),10) -
486                                 parseInt(Dom.getStyle(tlEl,HEIGHT),10)) + 'px';
487                                 
488                         Dom.setStyle(blEl,HEIGHT,newSize);
489                         Dom.setStyle(brEl,HEIGHT,newSize);
490                         newSize = (parseInt(Dom.getStyle(maskEl,WIDTH),10) -
491                                 parseInt(Dom.getStyle(tlEl,WIDTH),10)) + 'px';
492                         Dom.setStyle(trEl,WIDTH,newSize);
493                         Dom.setStyle(brEl,WIDTH,newSize);
494                 },
495                                         
496                                 
497                 
498                 /** 
499                  * Calculates some auxiliary values to make the rendering faster
500                  * @method _recalculateConstants
501                  * @return  void
502                  * @private
503                  */             
504                 _recalculateConstants: function() {
505                         var barEl = this.get(BAR_EL);
506
507                         switch (this.get(DIRECTION)) {
508                                 case DIRECTION_LTR:
509                                 case DIRECTION_RTL:
510                                         this._barSpace = parseInt(this.get(WIDTH),10) - 
511                                                 (parseInt(Dom.getStyle(barEl,'marginLeft'),10) || 0) -
512                                                 (parseInt(Dom.getStyle(barEl,'marginRight'),10) || 0);
513                                         break;
514                                 case DIRECTION_TTB:
515                                 case DIRECTION_BTT:
516                                         this._barSpace = parseInt(this.get(HEIGHT),10) -
517                                                 (parseInt(Dom.getStyle(barEl,'marginTop'),10) || 0)-
518                                                 (parseInt(Dom.getStyle(barEl,'marginBottom'),10) || 0); 
519                                         break;
520                         }
521                         this._barFactor = this._barSpace / (this.get(MAX_VALUE) - (this.get(MIN_VALUE) || 0))  || 1;
522                 },
523                 
524                 /** 
525                  * Called in response to a change in the <a href="#config_anim">anim</a> attribute.
526                  * It creates and sets up or destroys the instance of the animation utility that will move the bar
527                  * @method _animSetter
528                  * @return  void
529                  * @private
530                  */             
531                 _animSetter: function (value) {
532                         var anim, barEl = this.get(BAR_EL);
533                         if (value) {
534                                 if (value instanceof YAHOO.util.Anim) {
535                                         anim = value;
536                                 } else {
537                                         anim = new YAHOO.util.Anim(barEl);
538                                 }
539                                 anim.onTween.subscribe(this._animOnTween,this,true);
540                                 anim.onComplete.subscribe(this._animComplete,this,true);
541                                 
542                                 // Temporary solution until http://yuilibrary.com/projects/yui2/ticket/2528222 gets solved:
543                                 var oldSetAttribute = anim.setAttribute,
544                                         pb = this;
545                                 switch(this.get(DIRECTION)) {
546                                         case DIRECTION_BTT:
547                                                 anim.setAttribute = function(attr , val , unit) {
548                                                         val = Math.round(val);
549                                                         oldSetAttribute.call(this,attr,val,unit);
550                                                         Dom.setStyle(barEl,'top',(pb._barSpace - val) + 'px');
551                                                 };
552                                                 break;
553                                         case DIRECTION_RTL:
554                                                 anim.setAttribute = function(attr , val , unit) {
555                                                         val = Math.round(val);
556                                                         oldSetAttribute.call(this,attr,val,unit);
557                                                         Dom.setStyle(barEl,'left',(pb._barSpace - val) + 'px');
558                                                 };
559                                                 break;
560                                 }
561                                 // up to here
562
563                         } else {
564                                 anim = this.get(ANIM);
565                                 if (anim) {
566                                         anim.onTween.unsubscribeAll();
567                                         anim.onComplete.unsubscribeAll();
568                                 }
569                                 anim = null;
570                         }
571                         this._barSizeFunction = this._barSizeFunctions[anim?1:0][this.get(DIRECTION)];
572                         return anim;
573                 },
574                 
575                 _animComplete: function() {
576                         var value = this.get(VALUE);
577                         this._previousValue = value;
578                         this.fireEvent(PROGRESS,value);
579                         this.fireEvent(COMPLETE, value);
580                         Dom.removeClass(this.get(BAR_EL),CLASS_ANIM);
581                 },
582                 _animOnTween:function (name,oArgs) {
583                         var value = Math.floor(this._tweenFactor * oArgs[0].currentFrame + this._previousValue);
584                         this.fireEvent(PROGRESS,value);
585                 },
586                 
587                 /** 
588                  * Called in response to a change in the <a href="#config_value">value</a> attribute.
589                  * Moves the bar to reflect the new value
590                  * @method _valueChange
591                  * @return  void
592                  * @private
593                  */             
594                 _valueChange: function (value) {
595                         var anim = this.get(ANIM),
596                                 pixelValue = Math.floor((value - this.get(MIN_VALUE)) * this._barFactor),
597                                 barEl = this.get(BAR_EL);
598                         
599                         this._setAriaText(value);
600                         if (this._rendered) {
601                                 if (anim) {
602                                         anim.stop();
603                                         if (anim.isAnimated()) { anim._onComplete.fire(); } // see: http://yuilibrary.com/projects/yui2/ticket/2528217
604                                 }
605                                 this.fireEvent(START,this._previousValue);
606                                 this._barSizeFunction(value, pixelValue, barEl, anim);
607                         }
608                 },
609
610                 /** 
611                  * Utility method to set the ARIA value attributes
612                  * @method _setAriaText
613                  * @return  void
614                  * @private
615                  */
616                  _setAriaText: function(value) {
617
618                         var container = this.get('element'),
619                                 text = Lang.substitute(this.get(ARIA_TEXT_TEMPLATE),{
620                                         value:value,
621                                         minValue:this.get(MIN_VALUE),
622                                         maxValue:this.get(MAX_VALUE)
623                                 });
624                         container.setAttribute('aria-valuenow',value);
625                         container.setAttribute('aria-valuetext',text);
626                 }
627         });
628         /**
629          * Collection of functions used by to calculate the size of the bar.
630          * One of this will be used depending on direction and whether animation is active.
631          * @property _barSizeFunctions
632          * @type {collection of functions}
633          * @private
634          */
635         var b = [{},{}];
636         Prog.prototype._barSizeFunctions = b;
637         
638         b[0][DIRECTION_LTR] = function(value, pixelValue, barEl, anim) {
639                 Dom.setStyle(barEl,WIDTH,  pixelValue + 'px');
640                 this.fireEvent(PROGRESS,value);
641                 this.fireEvent(COMPLETE,value);
642         };
643         b[0][DIRECTION_RTL] = function(value, pixelValue, barEl, anim) {
644                 Dom.setStyle(barEl,WIDTH,  pixelValue + 'px');
645                 Dom.setStyle(barEl,'left',(this._barSpace - pixelValue) + 'px');
646                 this.fireEvent(PROGRESS,value);
647                 this.fireEvent(COMPLETE,value);
648         };
649         b[0][DIRECTION_TTB] = function(value, pixelValue, barEl, anim) {
650                 Dom.setStyle(barEl,HEIGHT,  pixelValue + 'px');
651                 this.fireEvent(PROGRESS,value);
652                 this.fireEvent(COMPLETE,value);
653         };
654         b[0][DIRECTION_BTT] = function(value, pixelValue, barEl, anim) {
655                 Dom.setStyle(barEl,HEIGHT,  pixelValue + 'px');
656                 Dom.setStyle(barEl,'top',  (this._barSpace - pixelValue) + 'px');
657                 this.fireEvent(PROGRESS,value);
658                 this.fireEvent(COMPLETE,value);
659         };
660         b[1][DIRECTION_LTR] = function(value, pixelValue, barEl, anim) {
661                 Dom.addClass(barEl,CLASS_ANIM);
662                 this._tweenFactor = (value - this._previousValue) / anim.totalFrames  / anim.duration;
663                 anim.attributes = {width:{ to: pixelValue }}; 
664                 anim.animate();
665         };
666         b[1][DIRECTION_RTL] =  b[1][DIRECTION_LTR];
667         b[1][DIRECTION_TTB] =  function(value, pixelValue, barEl, anim) {
668                 Dom.addClass(barEl,CLASS_ANIM);
669                 this._tweenFactor = (value - this._previousValue) / anim.totalFrames  / anim.duration;
670                 anim.attributes = {height:{to: pixelValue}};
671                 anim.animate();
672         };
673         b[1][DIRECTION_BTT] =  b[1][DIRECTION_TTB];
674                                 
675 })();
676
677 YAHOO.register("progressbar", YAHOO.widget.ProgressBar, {version: "2.8.0r4", build: "2449"});