View | Details | Raw Unified | Return to bug 13614
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/lib/yui/animation/animation-debug.js (-1396 lines)
Lines 1-1396 Link Here
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
(function() {
8
9
var Y = YAHOO.util;
10
11
/*
12
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
13
Code licensed under the BSD License:
14
http://developer.yahoo.net/yui/license.txt
15
*/
16
17
/**
18
 * The animation module provides allows effects to be added to HTMLElements.
19
 * @module animation
20
 * @requires yahoo, event, dom
21
 */
22
23
/**
24
 *
25
 * Base animation class that provides the interface for building animated effects.
26
 * <p>Usage: var myAnim = new YAHOO.util.Anim(el, { width: { from: 10, to: 100 } }, 1, YAHOO.util.Easing.easeOut);</p>
27
 * @class Anim
28
 * @namespace YAHOO.util
29
 * @requires YAHOO.util.AnimMgr
30
 * @requires YAHOO.util.Easing
31
 * @requires YAHOO.util.Dom
32
 * @requires YAHOO.util.Event
33
 * @requires YAHOO.util.CustomEvent
34
 * @constructor
35
 * @param {String | HTMLElement} el Reference to the element that will be animated
36
 * @param {Object} attributes The attribute(s) to be animated.  
37
 * Each attribute is an object with at minimum a "to" or "by" member defined.  
38
 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
39
 * All attribute names use camelCase.
40
 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
41
 * @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)
42
 */
43
44
var Anim = function(el, attributes, duration, method) {
45
    if (!el) {
46
        YAHOO.log('element required to create Anim instance', 'error', 'Anim');
47
    }
48
    this.init(el, attributes, duration, method); 
49
};
50
51
Anim.NAME = 'Anim';
52
53
Anim.prototype = {
54
    /**
55
     * Provides a readable name for the Anim instance.
56
     * @method toString
57
     * @return {String}
58
     */
59
    toString: function() {
60
        var el = this.getEl() || {};
61
        var id = el.id || el.tagName;
62
        return (this.constructor.NAME + ': ' + id);
63
    },
64
    
65
    patterns: { // cached for performance
66
        noNegatives:        /width|height|opacity|padding/i, // keep at zero or above
67
        offsetAttribute:  /^((width|height)|(top|left))$/, // use offsetValue as default
68
        defaultUnit:        /width|height|top$|bottom$|left$|right$/i, // use 'px' by default
69
        offsetUnit:         /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i // IE may return these, so convert these to offset
70
    },
71
    
72
    /**
73
     * Returns the value computed by the animation's "method".
74
     * @method doMethod
75
     * @param {String} attr The name of the attribute.
76
     * @param {Number} start The value this attribute should start from for this animation.
77
     * @param {Number} end  The value this attribute should end at for this animation.
78
     * @return {Number} The Value to be applied to the attribute.
79
     */
80
    doMethod: function(attr, start, end) {
81
        return this.method(this.currentFrame, start, end - start, this.totalFrames);
82
    },
83
    
84
    /**
85
     * Applies a value to an attribute.
86
     * @method setAttribute
87
     * @param {String} attr The name of the attribute.
88
     * @param {Number} val The value to be applied to the attribute.
89
     * @param {String} unit The unit ('px', '%', etc.) of the value.
90
     */
91
    setAttribute: function(attr, val, unit) {
92
        var el = this.getEl();
93
        if ( this.patterns.noNegatives.test(attr) ) {
94
            val = (val > 0) ? val : 0;
95
        }
96
97
        if (attr in el && !('style' in el && attr in el.style)) {
98
            el[attr] = val;
99
        } else {
100
            Y.Dom.setStyle(el, attr, val + unit);
101
        }
102
    },                        
103
    
104
    /**
105
     * Returns current value of the attribute.
106
     * @method getAttribute
107
     * @param {String} attr The name of the attribute.
108
     * @return {Number} val The current value of the attribute.
109
     */
110
    getAttribute: function(attr) {
111
        var el = this.getEl();
112
        var val = Y.Dom.getStyle(el, attr);
113
114
        if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
115
            return parseFloat(val);
116
        }
117
        
118
        var a = this.patterns.offsetAttribute.exec(attr) || [];
119
        var pos = !!( a[3] ); // top or left
120
        var box = !!( a[2] ); // width or height
121
        
122
        if ('style' in el) {
123
            // use offsets for width/height and abs pos top/left
124
            if ( box || (Y.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
125
                val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
126
            } else { // default to zero for other 'auto'
127
                val = 0;
128
            }
129
        } else if (attr in el) {
130
            val = el[attr];
131
        }
132
133
        return val;
134
    },
135
    
136
    /**
137
     * Returns the unit to use when none is supplied.
138
     * @method getDefaultUnit
139
     * @param {attr} attr The name of the attribute.
140
     * @return {String} The default unit to be used.
141
     */
142
    getDefaultUnit: function(attr) {
143
         if ( this.patterns.defaultUnit.test(attr) ) {
144
            return 'px';
145
         }
146
         
147
         return '';
148
    },
149
        
150
    /**
151
     * Sets the actual values to be used during the animation.  Should only be needed for subclass use.
152
     * @method setRuntimeAttribute
153
     * @param {Object} attr The attribute object
154
     * @private 
155
     */
156
    setRuntimeAttribute: function(attr) {
157
        var start;
158
        var end;
159
        var attributes = this.attributes;
160
161
        this.runtimeAttributes[attr] = {};
162
        
163
        var isset = function(prop) {
164
            return (typeof prop !== 'undefined');
165
        };
166
        
167
        if ( !isset(attributes[attr]['to']) && !isset(attributes[attr]['by']) ) {
168
            return false; // note return; nothing to animate to
169
        }
170
        
171
        start = ( isset(attributes[attr]['from']) ) ? attributes[attr]['from'] : this.getAttribute(attr);
172
173
        // To beats by, per SMIL 2.1 spec
174
        if ( isset(attributes[attr]['to']) ) {
175
            end = attributes[attr]['to'];
176
        } else if ( isset(attributes[attr]['by']) ) {
177
            if (start.constructor == Array) {
178
                end = [];
179
                for (var i = 0, len = start.length; i < len; ++i) {
180
                    end[i] = start[i] + attributes[attr]['by'][i] * 1; // times 1 to cast "by" 
181
                }
182
            } else {
183
                end = start + attributes[attr]['by'] * 1;
184
            }
185
        }
186
        
187
        this.runtimeAttributes[attr].start = start;
188
        this.runtimeAttributes[attr].end = end;
189
190
        // set units if needed
191
        this.runtimeAttributes[attr].unit = ( isset(attributes[attr].unit) ) ?
192
                attributes[attr]['unit'] : this.getDefaultUnit(attr);
193
        return true;
194
    },
195
196
    /**
197
     * Constructor for Anim instance.
198
     * @method init
199
     * @param {String | HTMLElement} el Reference to the element that will be animated
200
     * @param {Object} attributes The attribute(s) to be animated.  
201
     * Each attribute is an object with at minimum a "to" or "by" member defined.  
202
     * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
203
     * All attribute names use camelCase.
204
     * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
205
     * @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)
206
     */ 
207
    init: function(el, attributes, duration, method) {
208
        /**
209
         * Whether or not the animation is running.
210
         * @property isAnimated
211
         * @private
212
         * @type Boolean
213
         */
214
        var isAnimated = false;
215
        
216
        /**
217
         * A Date object that is created when the animation begins.
218
         * @property startTime
219
         * @private
220
         * @type Date
221
         */
222
        var startTime = null;
223
        
224
        /**
225
         * The number of frames this animation was able to execute.
226
         * @property actualFrames
227
         * @private
228
         * @type Int
229
         */
230
        var actualFrames = 0; 
231
232
        /**
233
         * The element to be animated.
234
         * @property el
235
         * @private
236
         * @type HTMLElement
237
         */
238
        el = Y.Dom.get(el);
239
        
240
        /**
241
         * The collection of attributes to be animated.  
242
         * Each attribute must have at least a "to" or "by" defined in order to animate.  
243
         * If "to" is supplied, the animation will end with the attribute at that value.  
244
         * If "by" is supplied, the animation will end at that value plus its starting value. 
245
         * If both are supplied, "to" is used, and "by" is ignored. 
246
         * 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).
247
         * @property attributes
248
         * @type Object
249
         */
250
        this.attributes = attributes || {};
251
        
252
        /**
253
         * The length of the animation.  Defaults to "1" (second).
254
         * @property duration
255
         * @type Number
256
         */
257
        this.duration = !YAHOO.lang.isUndefined(duration) ? duration : 1;
258
        
259
        /**
260
         * The method that will provide values to the attribute(s) during the animation. 
261
         * Defaults to "YAHOO.util.Easing.easeNone".
262
         * @property method
263
         * @type Function
264
         */
265
        this.method = method || Y.Easing.easeNone;
266
267
        /**
268
         * Whether or not the duration should be treated as seconds.
269
         * Defaults to true.
270
         * @property useSeconds
271
         * @type Boolean
272
         */
273
        this.useSeconds = true; // default to seconds
274
        
275
        /**
276
         * The location of the current animation on the timeline.
277
         * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
278
         * @property currentFrame
279
         * @type Int
280
         */
281
        this.currentFrame = 0;
282
        
283
        /**
284
         * The total number of frames to be executed.
285
         * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
286
         * @property totalFrames
287
         * @type Int
288
         */
289
        this.totalFrames = Y.AnimMgr.fps;
290
        
291
        /**
292
         * Changes the animated element
293
         * @method setEl
294
         */
295
        this.setEl = function(element) {
296
            el = Y.Dom.get(element);
297
        };
298
        
299
        /**
300
         * Returns a reference to the animated element.
301
         * @method getEl
302
         * @return {HTMLElement}
303
         */
304
        this.getEl = function() { return el; };
305
        
306
        /**
307
         * Checks whether the element is currently animated.
308
         * @method isAnimated
309
         * @return {Boolean} current value of isAnimated.     
310
         */
311
        this.isAnimated = function() {
312
            return isAnimated;
313
        };
314
        
315
        /**
316
         * Returns the animation start time.
317
         * @method getStartTime
318
         * @return {Date} current value of startTime.      
319
         */
320
        this.getStartTime = function() {
321
            return startTime;
322
        };        
323
        
324
        this.runtimeAttributes = {};
325
        
326
        var logger = {};
327
        logger.log = function() {YAHOO.log.apply(window, arguments)};
328
        
329
        logger.log('creating new instance of ' + this);
330
        
331
        /**
332
         * Starts the animation by registering it with the animation manager. 
333
         * @method animate  
334
         */
335
        this.animate = function() {
336
            if ( this.isAnimated() ) {
337
                return false;
338
            }
339
            
340
            this.currentFrame = 0;
341
            
342
            this.totalFrames = ( this.useSeconds ) ? Math.ceil(Y.AnimMgr.fps * this.duration) : this.duration;
343
    
344
            if (this.duration === 0 && this.useSeconds) { // jump to last frame if zero second duration 
345
                this.totalFrames = 1; 
346
            }
347
            Y.AnimMgr.registerElement(this);
348
            return true;
349
        };
350
          
351
        /**
352
         * Stops the animation.  Normally called by AnimMgr when animation completes.
353
         * @method stop
354
         * @param {Boolean} finish (optional) If true, animation will jump to final frame.
355
         */ 
356
        this.stop = function(finish) {
357
            if (!this.isAnimated()) { // nothing to stop
358
                return false;
359
            }
360
361
            if (finish) {
362
                 this.currentFrame = this.totalFrames;
363
                 this._onTween.fire();
364
            }
365
            Y.AnimMgr.stop(this);
366
        };
367
        
368
        var onStart = function() {            
369
            this.onStart.fire();
370
            
371
            this.runtimeAttributes = {};
372
            for (var attr in this.attributes) {
373
                this.setRuntimeAttribute(attr);
374
            }
375
            
376
            isAnimated = true;
377
            actualFrames = 0;
378
            startTime = new Date(); 
379
        };
380
        
381
        /**
382
         * Feeds the starting and ending values for each animated attribute to doMethod once per frame, then applies the resulting value to the attribute(s).
383
         * @private
384
         */
385
         
386
        var onTween = function() {
387
            var data = {
388
                duration: new Date() - this.getStartTime(),
389
                currentFrame: this.currentFrame
390
            };
391
            
392
            data.toString = function() {
393
                return (
394
                    'duration: ' + data.duration +
395
                    ', currentFrame: ' + data.currentFrame
396
                );
397
            };
398
            
399
            this.onTween.fire(data);
400
            
401
            var runtimeAttributes = this.runtimeAttributes;
402
            
403
            for (var attr in runtimeAttributes) {
404
                this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit); 
405
            }
406
            
407
            actualFrames += 1;
408
        };
409
        
410
        var onComplete = function() {
411
            var actual_duration = (new Date() - startTime) / 1000 ;
412
            
413
            var data = {
414
                duration: actual_duration,
415
                frames: actualFrames,
416
                fps: actualFrames / actual_duration
417
            };
418
            
419
            data.toString = function() {
420
                return (
421
                    'duration: ' + data.duration +
422
                    ', frames: ' + data.frames +
423
                    ', fps: ' + data.fps
424
                );
425
            };
426
            
427
            isAnimated = false;
428
            actualFrames = 0;
429
            this.onComplete.fire(data);
430
        };
431
        
432
        /**
433
         * Custom event that fires after onStart, useful in subclassing
434
         * @private
435
         */    
436
        this._onStart = new Y.CustomEvent('_start', this, true);
437
438
        /**
439
         * Custom event that fires when animation begins
440
         * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)
441
         * @event onStart
442
         */    
443
        this.onStart = new Y.CustomEvent('start', this);
444
        
445
        /**
446
         * Custom event that fires between each frame
447
         * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)
448
         * @event onTween
449
         */
450
        this.onTween = new Y.CustomEvent('tween', this);
451
        
452
        /**
453
         * Custom event that fires after onTween
454
         * @private
455
         */
456
        this._onTween = new Y.CustomEvent('_tween', this, true);
457
        
458
        /**
459
         * Custom event that fires when animation ends
460
         * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)
461
         * @event onComplete
462
         */
463
        this.onComplete = new Y.CustomEvent('complete', this);
464
        /**
465
         * Custom event that fires after onComplete
466
         * @private
467
         */
468
        this._onComplete = new Y.CustomEvent('_complete', this, true);
469
470
        this._onStart.subscribe(onStart);
471
        this._onTween.subscribe(onTween);
472
        this._onComplete.subscribe(onComplete);
473
    }
474
};
475
476
    Y.Anim = Anim;
477
})();
478
/**
479
 * Handles animation queueing and threading.
480
 * Used by Anim and subclasses.
481
 * @class AnimMgr
482
 * @namespace YAHOO.util
483
 */
484
YAHOO.util.AnimMgr = new function() {
485
    /** 
486
     * Reference to the animation Interval.
487
     * @property thread
488
     * @private
489
     * @type Int
490
     */
491
    var thread = null;
492
    
493
    /** 
494
     * The current queue of registered animation objects.
495
     * @property queue
496
     * @private
497
     * @type Array
498
     */    
499
    var queue = [];
500
501
    /** 
502
     * The number of active animations.
503
     * @property tweenCount
504
     * @private
505
     * @type Int
506
     */        
507
    var tweenCount = 0;
508
509
    /** 
510
     * Base frame rate (frames per second). 
511
     * Arbitrarily high for better x-browser calibration (slower browsers drop more frames).
512
     * @property fps
513
     * @type Int
514
     * 
515
     */
516
    this.fps = 1000;
517
518
    /** 
519
     * Interval delay in milliseconds, defaults to fastest possible.
520
     * @property delay
521
     * @type Int
522
     * 
523
     */
524
    this.delay = 1;
525
526
    /**
527
     * Adds an animation instance to the animation queue.
528
     * All animation instances must be registered in order to animate.
529
     * @method registerElement
530
     * @param {object} tween The Anim instance to be be registered
531
     */
532
    this.registerElement = function(tween) {
533
        queue[queue.length] = tween;
534
        tweenCount += 1;
535
        tween._onStart.fire();
536
        this.start();
537
    };
538
    
539
    /**
540
     * removes an animation instance from the animation queue.
541
     * All animation instances must be registered in order to animate.
542
     * @method unRegister
543
     * @param {object} tween The Anim instance to be be registered
544
     * @param {Int} index The index of the Anim instance
545
     * @private
546
     */
547
    this.unRegister = function(tween, index) {
548
        index = index || getIndex(tween);
549
        if (!tween.isAnimated() || index === -1) {
550
            return false;
551
        }
552
        
553
        tween._onComplete.fire();
554
        queue.splice(index, 1);
555
556
        tweenCount -= 1;
557
        if (tweenCount <= 0) {
558
            this.stop();
559
        }
560
561
        return true;
562
    };
563
    
564
    /**
565
     * Starts the animation thread.
566
	* Only one thread can run at a time.
567
     * @method start
568
     */    
569
    this.start = function() {
570
        if (thread === null) {
571
            thread = setInterval(this.run, this.delay);
572
        }
573
    };
574
575
    /**
576
     * Stops the animation thread or a specific animation instance.
577
     * @method stop
578
     * @param {object} tween A specific Anim instance to stop (optional)
579
     * If no instance given, Manager stops thread and all animations.
580
     */    
581
    this.stop = function(tween) {
582
        if (!tween) {
583
            clearInterval(thread);
584
            
585
            for (var i = 0, len = queue.length; i < len; ++i) {
586
                this.unRegister(queue[0], 0);  
587
            }
588
589
            queue = [];
590
            thread = null;
591
            tweenCount = 0;
592
        }
593
        else {
594
            this.unRegister(tween);
595
        }
596
    };
597
    
598
    /**
599
     * Called per Interval to handle each animation frame.
600
     * @method run
601
     */    
602
    this.run = function() {
603
        for (var i = 0, len = queue.length; i < len; ++i) {
604
            var tween = queue[i];
605
            if ( !tween || !tween.isAnimated() ) { continue; }
606
607
            if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
608
            {
609
                tween.currentFrame += 1;
610
                
611
                if (tween.useSeconds) {
612
                    correctFrame(tween);
613
                }
614
                tween._onTween.fire();          
615
            }
616
            else { YAHOO.util.AnimMgr.stop(tween, i); }
617
        }
618
    };
619
    
620
    var getIndex = function(anim) {
621
        for (var i = 0, len = queue.length; i < len; ++i) {
622
            if (queue[i] === anim) {
623
                return i; // note return;
624
            }
625
        }
626
        return -1;
627
    };
628
    
629
    /**
630
     * On the fly frame correction to keep animation on time.
631
     * @method correctFrame
632
     * @private
633
     * @param {Object} tween The Anim instance being corrected.
634
     */
635
    var correctFrame = function(tween) {
636
        var frames = tween.totalFrames;
637
        var frame = tween.currentFrame;
638
        var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
639
        var elapsed = (new Date() - tween.getStartTime());
640
        var tweak = 0;
641
        
642
        if (elapsed < tween.duration * 1000) { // check if falling behind
643
            tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
644
        } else { // went over duration, so jump to end
645
            tweak = frames - (frame + 1); 
646
        }
647
        if (tweak > 0 && isFinite(tweak)) { // adjust if needed
648
            if (tween.currentFrame + tweak >= frames) {// dont go past last frame
649
                tweak = frames - (frame + 1);
650
            }
651
            
652
            tween.currentFrame += tweak;      
653
        }
654
    };
655
    this._queue = queue;
656
    this._getIndex = getIndex;
657
};
658
/**
659
 * Used to calculate Bezier splines for any number of control points.
660
 * @class Bezier
661
 * @namespace YAHOO.util
662
 *
663
 */
664
YAHOO.util.Bezier = new function() {
665
    /**
666
     * Get the current position of the animated element based on t.
667
     * Each point is an array of "x" and "y" values (0 = x, 1 = y)
668
     * At least 2 points are required (start and end).
669
     * First point is start. Last point is end.
670
     * Additional control points are optional.     
671
     * @method getPosition
672
     * @param {Array} points An array containing Bezier points
673
     * @param {Number} t A number between 0 and 1 which is the basis for determining current position
674
     * @return {Array} An array containing int x and y member data
675
     */
676
    this.getPosition = function(points, t) {  
677
        var n = points.length;
678
        var tmp = [];
679
680
        for (var i = 0; i < n; ++i){
681
            tmp[i] = [points[i][0], points[i][1]]; // save input
682
        }
683
        
684
        for (var j = 1; j < n; ++j) {
685
            for (i = 0; i < n - j; ++i) {
686
                tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
687
                tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1]; 
688
            }
689
        }
690
    
691
        return [ tmp[0][0], tmp[0][1] ]; 
692
    
693
    };
694
};
695
(function() {
696
/**
697
 * Anim subclass for color transitions.
698
 * <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, 
699
 * [255,255,255], or rgb(255,255,255)</p>
700
 * @class ColorAnim
701
 * @namespace YAHOO.util
702
 * @requires YAHOO.util.Anim
703
 * @requires YAHOO.util.AnimMgr
704
 * @requires YAHOO.util.Easing
705
 * @requires YAHOO.util.Bezier
706
 * @requires YAHOO.util.Dom
707
 * @requires YAHOO.util.Event
708
 * @constructor
709
 * @extends YAHOO.util.Anim
710
 * @param {HTMLElement | String} el Reference to the element that will be animated
711
 * @param {Object} attributes The attribute(s) to be animated.
712
 * Each attribute is an object with at minimum a "to" or "by" member defined.
713
 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
714
 * All attribute names use camelCase.
715
 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
716
 * @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)
717
 */
718
    var ColorAnim = function(el, attributes, duration,  method) {
719
        ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
720
    };
721
    
722
    ColorAnim.NAME = 'ColorAnim';
723
724
    ColorAnim.DEFAULT_BGCOLOR = '#fff';
725
    // shorthand
726
    var Y = YAHOO.util;
727
    YAHOO.extend(ColorAnim, Y.Anim);
728
729
    var superclass = ColorAnim.superclass;
730
    var proto = ColorAnim.prototype;
731
    
732
    proto.patterns.color = /color$/i;
733
    proto.patterns.rgb            = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
734
    proto.patterns.hex            = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
735
    proto.patterns.hex3          = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
736
    proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/; // need rgba for safari
737
    
738
    /**
739
     * Attempts to parse the given string and return a 3-tuple.
740
     * @method parseColor
741
     * @param {String} s The string to parse.
742
     * @return {Array} The 3-tuple of rgb values.
743
     */
744
    proto.parseColor = function(s) {
745
        if (s.length == 3) { return s; }
746
    
747
        var c = this.patterns.hex.exec(s);
748
        if (c && c.length == 4) {
749
            return [ parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16) ];
750
        }
751
    
752
        c = this.patterns.rgb.exec(s);
753
        if (c && c.length == 4) {
754
            return [ parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10) ];
755
        }
756
    
757
        c = this.patterns.hex3.exec(s);
758
        if (c && c.length == 4) {
759
            return [ parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16) ];
760
        }
761
        
762
        return null;
763
    };
764
765
    proto.getAttribute = function(attr) {
766
        var el = this.getEl();
767
        if (this.patterns.color.test(attr) ) {
768
            var val = YAHOO.util.Dom.getStyle(el, attr);
769
            
770
            var that = this;
771
            if (this.patterns.transparent.test(val)) { // bgcolor default
772
                var parent = YAHOO.util.Dom.getAncestorBy(el, function(node) {
773
                    return !that.patterns.transparent.test(val);
774
                });
775
776
                if (parent) {
777
                    val = Y.Dom.getStyle(parent, attr);
778
                } else {
779
                    val = ColorAnim.DEFAULT_BGCOLOR;
780
                }
781
            }
782
        } else {
783
            val = superclass.getAttribute.call(this, attr);
784
        }
785
786
        return val;
787
    };
788
    
789
    proto.doMethod = function(attr, start, end) {
790
        var val;
791
    
792
        if ( this.patterns.color.test(attr) ) {
793
            val = [];
794
            for (var i = 0, len = start.length; i < len; ++i) {
795
                val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);
796
            }
797
            
798
            val = 'rgb('+Math.floor(val[0])+','+Math.floor(val[1])+','+Math.floor(val[2])+')';
799
        }
800
        else {
801
            val = superclass.doMethod.call(this, attr, start, end);
802
        }
803
804
        return val;
805
    };
806
807
    proto.setRuntimeAttribute = function(attr) {
808
        superclass.setRuntimeAttribute.call(this, attr);
809
        
810
        if ( this.patterns.color.test(attr) ) {
811
            var attributes = this.attributes;
812
            var start = this.parseColor(this.runtimeAttributes[attr].start);
813
            var end = this.parseColor(this.runtimeAttributes[attr].end);
814
            // fix colors if going "by"
815
            if ( typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined' ) {
816
                end = this.parseColor(attributes[attr].by);
817
            
818
                for (var i = 0, len = start.length; i < len; ++i) {
819
                    end[i] = start[i] + end[i];
820
                }
821
            }
822
            
823
            this.runtimeAttributes[attr].start = start;
824
            this.runtimeAttributes[attr].end = end;
825
        }
826
    };
827
828
    Y.ColorAnim = ColorAnim;
829
})();
830
/*!
831
TERMS OF USE - EASING EQUATIONS
832
Open source under the BSD License.
833
Copyright 2001 Robert Penner All rights reserved.
834
835
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
836
837
 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
838
 * 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.
839
 * 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.
840
841
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.
842
*/
843
844
/**
845
 * Singleton that determines how an animation proceeds from start to end.
846
 * @class Easing
847
 * @namespace YAHOO.util
848
*/
849
850
YAHOO.util.Easing = {
851
852
    /**
853
     * Uniform speed between points.
854
     * @method easeNone
855
     * @param {Number} t Time value used to compute current value
856
     * @param {Number} b Starting value
857
     * @param {Number} c Delta between start and end values
858
     * @param {Number} d Total length of animation
859
     * @return {Number} The computed value for the current animation frame
860
     */
861
    easeNone: function (t, b, c, d) {
862
    	return c*t/d + b;
863
    },
864
    
865
    /**
866
     * Begins slowly and accelerates towards end.
867
     * @method easeIn
868
     * @param {Number} t Time value used to compute current value
869
     * @param {Number} b Starting value
870
     * @param {Number} c Delta between start and end values
871
     * @param {Number} d Total length of animation
872
     * @return {Number} The computed value for the current animation frame
873
     */
874
    easeIn: function (t, b, c, d) {
875
    	return c*(t/=d)*t + b;
876
    },
877
878
    /**
879
     * Begins quickly and decelerates towards end.
880
     * @method easeOut
881
     * @param {Number} t Time value used to compute current value
882
     * @param {Number} b Starting value
883
     * @param {Number} c Delta between start and end values
884
     * @param {Number} d Total length of animation
885
     * @return {Number} The computed value for the current animation frame
886
     */
887
    easeOut: function (t, b, c, d) {
888
    	return -c *(t/=d)*(t-2) + b;
889
    },
890
    
891
    /**
892
     * Begins slowly and decelerates towards end.
893
     * @method easeBoth
894
     * @param {Number} t Time value used to compute current value
895
     * @param {Number} b Starting value
896
     * @param {Number} c Delta between start and end values
897
     * @param {Number} d Total length of animation
898
     * @return {Number} The computed value for the current animation frame
899
     */
900
    easeBoth: function (t, b, c, d) {
901
    	if ((t/=d/2) < 1) {
902
            return c/2*t*t + b;
903
        }
904
        
905
    	return -c/2 * ((--t)*(t-2) - 1) + b;
906
    },
907
    
908
    /**
909
     * Begins slowly and accelerates towards end.
910
     * @method easeInStrong
911
     * @param {Number} t Time value used to compute current value
912
     * @param {Number} b Starting value
913
     * @param {Number} c Delta between start and end values
914
     * @param {Number} d Total length of animation
915
     * @return {Number} The computed value for the current animation frame
916
     */
917
    easeInStrong: function (t, b, c, d) {
918
    	return c*(t/=d)*t*t*t + b;
919
    },
920
    
921
    /**
922
     * Begins quickly and decelerates towards end.
923
     * @method easeOutStrong
924
     * @param {Number} t Time value used to compute current value
925
     * @param {Number} b Starting value
926
     * @param {Number} c Delta between start and end values
927
     * @param {Number} d Total length of animation
928
     * @return {Number} The computed value for the current animation frame
929
     */
930
    easeOutStrong: function (t, b, c, d) {
931
    	return -c * ((t=t/d-1)*t*t*t - 1) + b;
932
    },
933
    
934
    /**
935
     * Begins slowly and decelerates towards end.
936
     * @method easeBothStrong
937
     * @param {Number} t Time value used to compute current value
938
     * @param {Number} b Starting value
939
     * @param {Number} c Delta between start and end values
940
     * @param {Number} d Total length of animation
941
     * @return {Number} The computed value for the current animation frame
942
     */
943
    easeBothStrong: function (t, b, c, d) {
944
    	if ((t/=d/2) < 1) {
945
            return c/2*t*t*t*t + b;
946
        }
947
        
948
    	return -c/2 * ((t-=2)*t*t*t - 2) + b;
949
    },
950
951
    /**
952
     * Snap in elastic effect.
953
     * @method elasticIn
954
     * @param {Number} t Time value used to compute current value
955
     * @param {Number} b Starting value
956
     * @param {Number} c Delta between start and end values
957
     * @param {Number} d Total length of animation
958
     * @param {Number} a Amplitude (optional)
959
     * @param {Number} p Period (optional)
960
     * @return {Number} The computed value for the current animation frame
961
     */
962
963
    elasticIn: function (t, b, c, d, a, p) {
964
    	if (t == 0) {
965
            return b;
966
        }
967
        if ( (t /= d) == 1 ) {
968
            return b+c;
969
        }
970
        if (!p) {
971
            p=d*.3;
972
        }
973
        
974
    	if (!a || a < Math.abs(c)) {
975
            a = c; 
976
            var s = p/4;
977
        }
978
    	else {
979
            var s = p/(2*Math.PI) * Math.asin (c/a);
980
        }
981
        
982
    	return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
983
    },
984
985
    /**
986
     * Snap out elastic effect.
987
     * @method elasticOut
988
     * @param {Number} t Time value used to compute current value
989
     * @param {Number} b Starting value
990
     * @param {Number} c Delta between start and end values
991
     * @param {Number} d Total length of animation
992
     * @param {Number} a Amplitude (optional)
993
     * @param {Number} p Period (optional)
994
     * @return {Number} The computed value for the current animation frame
995
     */
996
    elasticOut: function (t, b, c, d, a, p) {
997
    	if (t == 0) {
998
            return b;
999
        }
1000
        if ( (t /= d) == 1 ) {
1001
            return b+c;
1002
        }
1003
        if (!p) {
1004
            p=d*.3;
1005
        }
1006
        
1007
    	if (!a || a < Math.abs(c)) {
1008
            a = c;
1009
            var s = p / 4;
1010
        }
1011
    	else {
1012
            var s = p/(2*Math.PI) * Math.asin (c/a);
1013
        }
1014
        
1015
    	return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
1016
    },
1017
    
1018
    /**
1019
     * Snap both elastic effect.
1020
     * @method elasticBoth
1021
     * @param {Number} t Time value used to compute current value
1022
     * @param {Number} b Starting value
1023
     * @param {Number} c Delta between start and end values
1024
     * @param {Number} d Total length of animation
1025
     * @param {Number} a Amplitude (optional)
1026
     * @param {Number} p Period (optional)
1027
     * @return {Number} The computed value for the current animation frame
1028
     */
1029
    elasticBoth: function (t, b, c, d, a, p) {
1030
    	if (t == 0) {
1031
            return b;
1032
        }
1033
        
1034
        if ( (t /= d/2) == 2 ) {
1035
            return b+c;
1036
        }
1037
        
1038
        if (!p) {
1039
            p = d*(.3*1.5);
1040
        }
1041
        
1042
    	if ( !a || a < Math.abs(c) ) {
1043
            a = c; 
1044
            var s = p/4;
1045
        }
1046
    	else {
1047
            var s = p/(2*Math.PI) * Math.asin (c/a);
1048
        }
1049
        
1050
    	if (t < 1) {
1051
            return -.5*(a*Math.pow(2,10*(t-=1)) * 
1052
                    Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
1053
        }
1054
    	return a*Math.pow(2,-10*(t-=1)) * 
1055
                Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
1056
    },
1057
1058
1059
    /**
1060
     * Backtracks slightly, then reverses direction and moves to end.
1061
     * @method backIn
1062
     * @param {Number} t Time value used to compute current value
1063
     * @param {Number} b Starting value
1064
     * @param {Number} c Delta between start and end values
1065
     * @param {Number} d Total length of animation
1066
     * @param {Number} s Overshoot (optional)
1067
     * @return {Number} The computed value for the current animation frame
1068
     */
1069
    backIn: function (t, b, c, d, s) {
1070
    	if (typeof s == 'undefined') {
1071
            s = 1.70158;
1072
        }
1073
    	return c*(t/=d)*t*((s+1)*t - s) + b;
1074
    },
1075
1076
    /**
1077
     * Overshoots end, then reverses and comes back to end.
1078
     * @method backOut
1079
     * @param {Number} t Time value used to compute current value
1080
     * @param {Number} b Starting value
1081
     * @param {Number} c Delta between start and end values
1082
     * @param {Number} d Total length of animation
1083
     * @param {Number} s Overshoot (optional)
1084
     * @return {Number} The computed value for the current animation frame
1085
     */
1086
    backOut: function (t, b, c, d, s) {
1087
    	if (typeof s == 'undefined') {
1088
            s = 1.70158;
1089
        }
1090
    	return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
1091
    },
1092
    
1093
    /**
1094
     * Backtracks slightly, then reverses direction, overshoots end, 
1095
     * then reverses and comes back to end.
1096
     * @method backBoth
1097
     * @param {Number} t Time value used to compute current value
1098
     * @param {Number} b Starting value
1099
     * @param {Number} c Delta between start and end values
1100
     * @param {Number} d Total length of animation
1101
     * @param {Number} s Overshoot (optional)
1102
     * @return {Number} The computed value for the current animation frame
1103
     */
1104
    backBoth: function (t, b, c, d, s) {
1105
    	if (typeof s == 'undefined') {
1106
            s = 1.70158; 
1107
        }
1108
        
1109
    	if ((t /= d/2 ) < 1) {
1110
            return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
1111
        }
1112
    	return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
1113
    },
1114
1115
    /**
1116
     * Bounce off of start.
1117
     * @method bounceIn
1118
     * @param {Number} t Time value used to compute current value
1119
     * @param {Number} b Starting value
1120
     * @param {Number} c Delta between start and end values
1121
     * @param {Number} d Total length of animation
1122
     * @return {Number} The computed value for the current animation frame
1123
     */
1124
    bounceIn: function (t, b, c, d) {
1125
    	return c - YAHOO.util.Easing.bounceOut(d-t, 0, c, d) + b;
1126
    },
1127
    
1128
    /**
1129
     * Bounces off end.
1130
     * @method bounceOut
1131
     * @param {Number} t Time value used to compute current value
1132
     * @param {Number} b Starting value
1133
     * @param {Number} c Delta between start and end values
1134
     * @param {Number} d Total length of animation
1135
     * @return {Number} The computed value for the current animation frame
1136
     */
1137
    bounceOut: function (t, b, c, d) {
1138
    	if ((t/=d) < (1/2.75)) {
1139
    		return c*(7.5625*t*t) + b;
1140
    	} else if (t < (2/2.75)) {
1141
    		return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
1142
    	} else if (t < (2.5/2.75)) {
1143
    		return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
1144
    	}
1145
        return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
1146
    },
1147
    
1148
    /**
1149
     * Bounces off start and end.
1150
     * @method bounceBoth
1151
     * @param {Number} t Time value used to compute current value
1152
     * @param {Number} b Starting value
1153
     * @param {Number} c Delta between start and end values
1154
     * @param {Number} d Total length of animation
1155
     * @return {Number} The computed value for the current animation frame
1156
     */
1157
    bounceBoth: function (t, b, c, d) {
1158
    	if (t < d/2) {
1159
            return YAHOO.util.Easing.bounceIn(t*2, 0, c, d) * .5 + b;
1160
        }
1161
    	return YAHOO.util.Easing.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
1162
    }
1163
};
1164
1165
(function() {
1166
/**
1167
 * Anim subclass for moving elements along a path defined by the "points" 
1168
 * member of "attributes".  All "points" are arrays with x, y coordinates.
1169
 * <p>Usage: <code>var myAnim = new YAHOO.util.Motion(el, { points: { to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1170
 * @class Motion
1171
 * @namespace YAHOO.util
1172
 * @requires YAHOO.util.Anim
1173
 * @requires YAHOO.util.AnimMgr
1174
 * @requires YAHOO.util.Easing
1175
 * @requires YAHOO.util.Bezier
1176
 * @requires YAHOO.util.Dom
1177
 * @requires YAHOO.util.Event
1178
 * @requires YAHOO.util.CustomEvent 
1179
 * @constructor
1180
 * @extends YAHOO.util.ColorAnim
1181
 * @param {String | HTMLElement} el Reference to the element that will be animated
1182
 * @param {Object} attributes The attribute(s) to be animated.  
1183
 * Each attribute is an object with at minimum a "to" or "by" member defined.  
1184
 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
1185
 * All attribute names use camelCase.
1186
 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1187
 * @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)
1188
 */
1189
    var Motion = function(el, attributes, duration,  method) {
1190
        if (el) { // dont break existing subclasses not using YAHOO.extend
1191
            Motion.superclass.constructor.call(this, el, attributes, duration, method);
1192
        }
1193
    };
1194
1195
1196
    Motion.NAME = 'Motion';
1197
1198
    // shorthand
1199
    var Y = YAHOO.util;
1200
    YAHOO.extend(Motion, Y.ColorAnim);
1201
    
1202
    var superclass = Motion.superclass;
1203
    var proto = Motion.prototype;
1204
1205
    proto.patterns.points = /^points$/i;
1206
    
1207
    proto.setAttribute = function(attr, val, unit) {
1208
        if (  this.patterns.points.test(attr) ) {
1209
            unit = unit || 'px';
1210
            superclass.setAttribute.call(this, 'left', val[0], unit);
1211
            superclass.setAttribute.call(this, 'top', val[1], unit);
1212
        } else {
1213
            superclass.setAttribute.call(this, attr, val, unit);
1214
        }
1215
    };
1216
1217
    proto.getAttribute = function(attr) {
1218
        if (  this.patterns.points.test(attr) ) {
1219
            var val = [
1220
                superclass.getAttribute.call(this, 'left'),
1221
                superclass.getAttribute.call(this, 'top')
1222
            ];
1223
        } else {
1224
            val = superclass.getAttribute.call(this, attr);
1225
        }
1226
1227
        return val;
1228
    };
1229
1230
    proto.doMethod = function(attr, start, end) {
1231
        var val = null;
1232
1233
        if ( this.patterns.points.test(attr) ) {
1234
            var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;				
1235
            val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);
1236
        } else {
1237
            val = superclass.doMethod.call(this, attr, start, end);
1238
        }
1239
        return val;
1240
    };
1241
1242
    proto.setRuntimeAttribute = function(attr) {
1243
        if ( this.patterns.points.test(attr) ) {
1244
            var el = this.getEl();
1245
            var attributes = this.attributes;
1246
            var start;
1247
            var control = attributes['points']['control'] || [];
1248
            var end;
1249
            var i, len;
1250
            
1251
            if (control.length > 0 && !(control[0] instanceof Array) ) { // could be single point or array of points
1252
                control = [control];
1253
            } else { // break reference to attributes.points.control
1254
                var tmp = []; 
1255
                for (i = 0, len = control.length; i< len; ++i) {
1256
                    tmp[i] = control[i];
1257
                }
1258
                control = tmp;
1259
            }
1260
1261
            if (Y.Dom.getStyle(el, 'position') == 'static') { // default to relative
1262
                Y.Dom.setStyle(el, 'position', 'relative');
1263
            }
1264
    
1265
            if ( isset(attributes['points']['from']) ) {
1266
                Y.Dom.setXY(el, attributes['points']['from']); // set position to from point
1267
            } 
1268
            else { Y.Dom.setXY( el, Y.Dom.getXY(el) ); } // set it to current position
1269
            
1270
            start = this.getAttribute('points'); // get actual top & left
1271
            
1272
            // TO beats BY, per SMIL 2.1 spec
1273
            if ( isset(attributes['points']['to']) ) {
1274
                end = translateValues.call(this, attributes['points']['to'], start);
1275
                
1276
                var pageXY = Y.Dom.getXY(this.getEl());
1277
                for (i = 0, len = control.length; i < len; ++i) {
1278
                    control[i] = translateValues.call(this, control[i], start);
1279
                }
1280
1281
                
1282
            } else if ( isset(attributes['points']['by']) ) {
1283
                end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1] ];
1284
                
1285
                for (i = 0, len = control.length; i < len; ++i) {
1286
                    control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
1287
                }
1288
            }
1289
1290
            this.runtimeAttributes[attr] = [start];
1291
            
1292
            if (control.length > 0) {
1293
                this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control); 
1294
            }
1295
1296
            this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;
1297
        }
1298
        else {
1299
            superclass.setRuntimeAttribute.call(this, attr);
1300
        }
1301
    };
1302
    
1303
    var translateValues = function(val, start) {
1304
        var pageXY = Y.Dom.getXY(this.getEl());
1305
        val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];
1306
1307
        return val; 
1308
    };
1309
    
1310
    var isset = function(prop) {
1311
        return (typeof prop !== 'undefined');
1312
    };
1313
1314
    Y.Motion = Motion;
1315
})();
1316
(function() {
1317
/**
1318
 * Anim subclass for scrolling elements to a position defined by the "scroll"
1319
 * member of "attributes".  All "scroll" members are arrays with x, y scroll positions.
1320
 * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1321
 * @class Scroll
1322
 * @namespace YAHOO.util
1323
 * @requires YAHOO.util.Anim
1324
 * @requires YAHOO.util.AnimMgr
1325
 * @requires YAHOO.util.Easing
1326
 * @requires YAHOO.util.Bezier
1327
 * @requires YAHOO.util.Dom
1328
 * @requires YAHOO.util.Event
1329
 * @requires YAHOO.util.CustomEvent 
1330
 * @extends YAHOO.util.ColorAnim
1331
 * @constructor
1332
 * @param {String or HTMLElement} el Reference to the element that will be animated
1333
 * @param {Object} attributes The attribute(s) to be animated.  
1334
 * Each attribute is an object with at minimum a "to" or "by" member defined.  
1335
 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
1336
 * All attribute names use camelCase.
1337
 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1338
 * @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)
1339
 */
1340
    var Scroll = function(el, attributes, duration,  method) {
1341
        if (el) { // dont break existing subclasses not using YAHOO.extend
1342
            Scroll.superclass.constructor.call(this, el, attributes, duration, method);
1343
        }
1344
    };
1345
1346
    Scroll.NAME = 'Scroll';
1347
1348
    // shorthand
1349
    var Y = YAHOO.util;
1350
    YAHOO.extend(Scroll, Y.ColorAnim);
1351
    
1352
    var superclass = Scroll.superclass;
1353
    var proto = Scroll.prototype;
1354
1355
    proto.doMethod = function(attr, start, end) {
1356
        var val = null;
1357
    
1358
        if (attr == 'scroll') {
1359
            val = [
1360
                this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),
1361
                this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)
1362
            ];
1363
            
1364
        } else {
1365
            val = superclass.doMethod.call(this, attr, start, end);
1366
        }
1367
        return val;
1368
    };
1369
1370
    proto.getAttribute = function(attr) {
1371
        var val = null;
1372
        var el = this.getEl();
1373
        
1374
        if (attr == 'scroll') {
1375
            val = [ el.scrollLeft, el.scrollTop ];
1376
        } else {
1377
            val = superclass.getAttribute.call(this, attr);
1378
        }
1379
        
1380
        return val;
1381
    };
1382
1383
    proto.setAttribute = function(attr, val, unit) {
1384
        var el = this.getEl();
1385
        
1386
        if (attr == 'scroll') {
1387
            el.scrollLeft = val[0];
1388
            el.scrollTop = val[1];
1389
        } else {
1390
            superclass.setAttribute.call(this, attr, val, unit);
1391
        }
1392
    };
1393
1394
    Y.Scroll = Scroll;
1395
})();
1396
YAHOO.register("animation", YAHOO.util.Anim, {version: "2.8.0r4", build: "2449"});
(-)a/koha-tmpl/intranet-tmpl/lib/yui/animation/animation-min.js (-23 lines)
Lines 1-23 Link Here
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
(function(){var B=YAHOO.util;var A=function(D,C,E,F){if(!D){}this.init(D,C,E,F);};A.NAME="Anim";A.prototype={toString:function(){var C=this.getEl()||{};var D=C.id||C.tagName;return(this.constructor.NAME+": "+D);},patterns:{noNegatives:/width|height|opacity|padding/i,offsetAttribute:/^((width|height)|(top|left))$/,defaultUnit:/width|height|top$|bottom$|left$|right$/i,offsetUnit:/\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i},doMethod:function(C,E,D){return this.method(this.currentFrame,E,D-E,this.totalFrames);},setAttribute:function(C,F,E){var D=this.getEl();if(this.patterns.noNegatives.test(C)){F=(F>0)?F:0;}if(C in D&&!("style" in D&&C in D.style)){D[C]=F;}else{B.Dom.setStyle(D,C,F+E);}},getAttribute:function(C){var E=this.getEl();var G=B.Dom.getStyle(E,C);if(G!=="auto"&&!this.patterns.offsetUnit.test(G)){return parseFloat(G);}var D=this.patterns.offsetAttribute.exec(C)||[];var H=!!(D[3]);var F=!!(D[2]);if("style" in E){if(F||(B.Dom.getStyle(E,"position")=="absolute"&&H)){G=E["offset"+D[0].charAt(0).toUpperCase()+D[0].substr(1)];}else{G=0;}}else{if(C in E){G=E[C];}}return G;},getDefaultUnit:function(C){if(this.patterns.defaultUnit.test(C)){return"px";}return"";},setRuntimeAttribute:function(D){var I;var E;var F=this.attributes;this.runtimeAttributes[D]={};var H=function(J){return(typeof J!=="undefined");};if(!H(F[D]["to"])&&!H(F[D]["by"])){return false;}I=(H(F[D]["from"]))?F[D]["from"]:this.getAttribute(D);if(H(F[D]["to"])){E=F[D]["to"];}else{if(H(F[D]["by"])){if(I.constructor==Array){E=[];for(var G=0,C=I.length;G<C;++G){E[G]=I[G]+F[D]["by"][G]*1;}}else{E=I+F[D]["by"]*1;}}}this.runtimeAttributes[D].start=I;this.runtimeAttributes[D].end=E;this.runtimeAttributes[D].unit=(H(F[D].unit))?F[D]["unit"]:this.getDefaultUnit(D);return true;},init:function(E,J,I,C){var D=false;var F=null;var H=0;E=B.Dom.get(E);this.attributes=J||{};this.duration=!YAHOO.lang.isUndefined(I)?I:1;this.method=C||B.Easing.easeNone;this.useSeconds=true;this.currentFrame=0;this.totalFrames=B.AnimMgr.fps;this.setEl=function(M){E=B.Dom.get(M);};this.getEl=function(){return E;};this.isAnimated=function(){return D;};this.getStartTime=function(){return F;};this.runtimeAttributes={};this.animate=function(){if(this.isAnimated()){return false;}this.currentFrame=0;this.totalFrames=(this.useSeconds)?Math.ceil(B.AnimMgr.fps*this.duration):this.duration;if(this.duration===0&&this.useSeconds){this.totalFrames=1;}B.AnimMgr.registerElement(this);return true;};this.stop=function(M){if(!this.isAnimated()){return false;}if(M){this.currentFrame=this.totalFrames;this._onTween.fire();}B.AnimMgr.stop(this);};var L=function(){this.onStart.fire();this.runtimeAttributes={};for(var M in this.attributes){this.setRuntimeAttribute(M);}D=true;H=0;F=new Date();};var K=function(){var O={duration:new Date()-this.getStartTime(),currentFrame:this.currentFrame};O.toString=function(){return("duration: "+O.duration+", currentFrame: "+O.currentFrame);};this.onTween.fire(O);var N=this.runtimeAttributes;for(var M in N){this.setAttribute(M,this.doMethod(M,N[M].start,N[M].end),N[M].unit);}H+=1;};var G=function(){var M=(new Date()-F)/1000;var N={duration:M,frames:H,fps:H/M};N.toString=function(){return("duration: "+N.duration+", frames: "+N.frames+", fps: "+N.fps);};D=false;H=0;this.onComplete.fire(N);};this._onStart=new B.CustomEvent("_start",this,true);this.onStart=new B.CustomEvent("start",this);this.onTween=new B.CustomEvent("tween",this);this._onTween=new B.CustomEvent("_tween",this,true);this.onComplete=new B.CustomEvent("complete",this);this._onComplete=new B.CustomEvent("_complete",this,true);this._onStart.subscribe(L);this._onTween.subscribe(K);this._onComplete.subscribe(G);}};B.Anim=A;})();YAHOO.util.AnimMgr=new function(){var C=null;var B=[];var A=0;this.fps=1000;this.delay=1;this.registerElement=function(F){B[B.length]=F;A+=1;F._onStart.fire();this.start();};this.unRegister=function(G,F){F=F||E(G);if(!G.isAnimated()||F===-1){return false;}G._onComplete.fire();B.splice(F,1);A-=1;if(A<=0){this.stop();}return true;};this.start=function(){if(C===null){C=setInterval(this.run,this.delay);}};this.stop=function(H){if(!H){clearInterval(C);for(var G=0,F=B.length;G<F;++G){this.unRegister(B[0],0);}B=[];C=null;A=0;}else{this.unRegister(H);}};this.run=function(){for(var H=0,F=B.length;H<F;++H){var G=B[H];if(!G||!G.isAnimated()){continue;}if(G.currentFrame<G.totalFrames||G.totalFrames===null){G.currentFrame+=1;if(G.useSeconds){D(G);}G._onTween.fire();}else{YAHOO.util.AnimMgr.stop(G,H);}}};var E=function(H){for(var G=0,F=B.length;G<F;++G){if(B[G]===H){return G;}}return -1;};var D=function(G){var J=G.totalFrames;var I=G.currentFrame;var H=(G.currentFrame*G.duration*1000/G.totalFrames);var F=(new Date()-G.getStartTime());var K=0;if(F<G.duration*1000){K=Math.round((F/H-1)*G.currentFrame);}else{K=J-(I+1);}if(K>0&&isFinite(K)){if(G.currentFrame+K>=J){K=J-(I+1);}G.currentFrame+=K;}};this._queue=B;this._getIndex=E;};YAHOO.util.Bezier=new function(){this.getPosition=function(E,D){var F=E.length;var C=[];for(var B=0;B<F;++B){C[B]=[E[B][0],E[B][1]];}for(var A=1;A<F;++A){for(B=0;B<F-A;++B){C[B][0]=(1-D)*C[B][0]+D*C[parseInt(B+1,10)][0];C[B][1]=(1-D)*C[B][1]+D*C[parseInt(B+1,10)][1];}}return[C[0][0],C[0][1]];};};(function(){var A=function(F,E,G,H){A.superclass.constructor.call(this,F,E,G,H);};A.NAME="ColorAnim";A.DEFAULT_BGCOLOR="#fff";var C=YAHOO.util;YAHOO.extend(A,C.Anim);var D=A.superclass;var B=A.prototype;B.patterns.color=/color$/i;B.patterns.rgb=/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;B.patterns.hex=/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;B.patterns.hex3=/^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;B.patterns.transparent=/^transparent|rgba\(0, 0, 0, 0\)$/;B.parseColor=function(E){if(E.length==3){return E;}var F=this.patterns.hex.exec(E);if(F&&F.length==4){return[parseInt(F[1],16),parseInt(F[2],16),parseInt(F[3],16)];}F=this.patterns.rgb.exec(E);if(F&&F.length==4){return[parseInt(F[1],10),parseInt(F[2],10),parseInt(F[3],10)];}F=this.patterns.hex3.exec(E);if(F&&F.length==4){return[parseInt(F[1]+F[1],16),parseInt(F[2]+F[2],16),parseInt(F[3]+F[3],16)];
8
}return null;};B.getAttribute=function(E){var G=this.getEl();if(this.patterns.color.test(E)){var I=YAHOO.util.Dom.getStyle(G,E);var H=this;if(this.patterns.transparent.test(I)){var F=YAHOO.util.Dom.getAncestorBy(G,function(J){return !H.patterns.transparent.test(I);});if(F){I=C.Dom.getStyle(F,E);}else{I=A.DEFAULT_BGCOLOR;}}}else{I=D.getAttribute.call(this,E);}return I;};B.doMethod=function(F,J,G){var I;if(this.patterns.color.test(F)){I=[];for(var H=0,E=J.length;H<E;++H){I[H]=D.doMethod.call(this,F,J[H],G[H]);}I="rgb("+Math.floor(I[0])+","+Math.floor(I[1])+","+Math.floor(I[2])+")";}else{I=D.doMethod.call(this,F,J,G);}return I;};B.setRuntimeAttribute=function(F){D.setRuntimeAttribute.call(this,F);if(this.patterns.color.test(F)){var H=this.attributes;var J=this.parseColor(this.runtimeAttributes[F].start);var G=this.parseColor(this.runtimeAttributes[F].end);if(typeof H[F]["to"]==="undefined"&&typeof H[F]["by"]!=="undefined"){G=this.parseColor(H[F].by);for(var I=0,E=J.length;I<E;++I){G[I]=J[I]+G[I];}}this.runtimeAttributes[F].start=J;this.runtimeAttributes[F].end=G;}};C.ColorAnim=A;})();
9
/*
10
TERMS OF USE - EASING EQUATIONS
11
Open source under the BSD License.
12
Copyright 2001 Robert Penner All rights reserved.
13
14
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
15
16
 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
17
 * 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.
18
 * 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.
19
20
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.
21
*/
22
YAHOO.util.Easing={easeNone:function(B,A,D,C){return D*B/C+A;},easeIn:function(B,A,D,C){return D*(B/=C)*B+A;},easeOut:function(B,A,D,C){return -D*(B/=C)*(B-2)+A;},easeBoth:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B+A;}return -D/2*((--B)*(B-2)-1)+A;},easeInStrong:function(B,A,D,C){return D*(B/=C)*B*B*B+A;},easeOutStrong:function(B,A,D,C){return -D*((B=B/C-1)*B*B*B-1)+A;},easeBothStrong:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B*B*B+A;}return -D/2*((B-=2)*B*B*B-2)+A;},elasticIn:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return -(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;},elasticOut:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return B*Math.pow(2,-10*C)*Math.sin((C*F-D)*(2*Math.PI)/E)+G+A;},elasticBoth:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F/2)==2){return A+G;}if(!E){E=F*(0.3*1.5);}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}if(C<1){return -0.5*(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;}return B*Math.pow(2,-10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E)*0.5+G+A;},backIn:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*(B/=D)*B*((C+1)*B-C)+A;},backOut:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*((B=B/D-1)*B*((C+1)*B+C)+1)+A;},backBoth:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}if((B/=D/2)<1){return E/2*(B*B*(((C*=(1.525))+1)*B-C))+A;}return E/2*((B-=2)*B*(((C*=(1.525))+1)*B+C)+2)+A;},bounceIn:function(B,A,D,C){return D-YAHOO.util.Easing.bounceOut(C-B,0,D,C)+A;},bounceOut:function(B,A,D,C){if((B/=C)<(1/2.75)){return D*(7.5625*B*B)+A;}else{if(B<(2/2.75)){return D*(7.5625*(B-=(1.5/2.75))*B+0.75)+A;}else{if(B<(2.5/2.75)){return D*(7.5625*(B-=(2.25/2.75))*B+0.9375)+A;}}}return D*(7.5625*(B-=(2.625/2.75))*B+0.984375)+A;},bounceBoth:function(B,A,D,C){if(B<C/2){return YAHOO.util.Easing.bounceIn(B*2,0,D,C)*0.5+A;}return YAHOO.util.Easing.bounceOut(B*2-C,0,D,C)*0.5+D*0.5+A;}};(function(){var A=function(H,G,I,J){if(H){A.superclass.constructor.call(this,H,G,I,J);}};A.NAME="Motion";var E=YAHOO.util;YAHOO.extend(A,E.ColorAnim);var F=A.superclass;var C=A.prototype;C.patterns.points=/^points$/i;C.setAttribute=function(G,I,H){if(this.patterns.points.test(G)){H=H||"px";F.setAttribute.call(this,"left",I[0],H);F.setAttribute.call(this,"top",I[1],H);}else{F.setAttribute.call(this,G,I,H);}};C.getAttribute=function(G){if(this.patterns.points.test(G)){var H=[F.getAttribute.call(this,"left"),F.getAttribute.call(this,"top")];}else{H=F.getAttribute.call(this,G);}return H;};C.doMethod=function(G,K,H){var J=null;if(this.patterns.points.test(G)){var I=this.method(this.currentFrame,0,100,this.totalFrames)/100;J=E.Bezier.getPosition(this.runtimeAttributes[G],I);}else{J=F.doMethod.call(this,G,K,H);}return J;};C.setRuntimeAttribute=function(P){if(this.patterns.points.test(P)){var H=this.getEl();var J=this.attributes;var G;var L=J["points"]["control"]||[];var I;var M,O;if(L.length>0&&!(L[0] instanceof Array)){L=[L];}else{var K=[];for(M=0,O=L.length;M<O;++M){K[M]=L[M];}L=K;}if(E.Dom.getStyle(H,"position")=="static"){E.Dom.setStyle(H,"position","relative");}if(D(J["points"]["from"])){E.Dom.setXY(H,J["points"]["from"]);
23
}else{E.Dom.setXY(H,E.Dom.getXY(H));}G=this.getAttribute("points");if(D(J["points"]["to"])){I=B.call(this,J["points"]["to"],G);var N=E.Dom.getXY(this.getEl());for(M=0,O=L.length;M<O;++M){L[M]=B.call(this,L[M],G);}}else{if(D(J["points"]["by"])){I=[G[0]+J["points"]["by"][0],G[1]+J["points"]["by"][1]];for(M=0,O=L.length;M<O;++M){L[M]=[G[0]+L[M][0],G[1]+L[M][1]];}}}this.runtimeAttributes[P]=[G];if(L.length>0){this.runtimeAttributes[P]=this.runtimeAttributes[P].concat(L);}this.runtimeAttributes[P][this.runtimeAttributes[P].length]=I;}else{F.setRuntimeAttribute.call(this,P);}};var B=function(G,I){var H=E.Dom.getXY(this.getEl());G=[G[0]-H[0]+I[0],G[1]-H[1]+I[1]];return G;};var D=function(G){return(typeof G!=="undefined");};E.Motion=A;})();(function(){var D=function(F,E,G,H){if(F){D.superclass.constructor.call(this,F,E,G,H);}};D.NAME="Scroll";var B=YAHOO.util;YAHOO.extend(D,B.ColorAnim);var C=D.superclass;var A=D.prototype;A.doMethod=function(E,H,F){var G=null;if(E=="scroll"){G=[this.method(this.currentFrame,H[0],F[0]-H[0],this.totalFrames),this.method(this.currentFrame,H[1],F[1]-H[1],this.totalFrames)];}else{G=C.doMethod.call(this,E,H,F);}return G;};A.getAttribute=function(E){var G=null;var F=this.getEl();if(E=="scroll"){G=[F.scrollLeft,F.scrollTop];}else{G=C.getAttribute.call(this,E);}return G;};A.setAttribute=function(E,H,G){var F=this.getEl();if(E=="scroll"){F.scrollLeft=H[0];F.scrollTop=H[1];}else{C.setAttribute.call(this,E,H,G);}};B.Scroll=D;})();YAHOO.register("animation",YAHOO.util.Anim,{version:"2.8.0r4",build:"2449"});
(-)a/koha-tmpl/intranet-tmpl/lib/yui/animation/animation.js (-1392 lines)
Lines 1-1392 Link Here
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
(function() {
8
9
var Y = YAHOO.util;
10
11
/*
12
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
13
Code licensed under the BSD License:
14
http://developer.yahoo.net/yui/license.txt
15
*/
16
17
/**
18
 * The animation module provides allows effects to be added to HTMLElements.
19
 * @module animation
20
 * @requires yahoo, event, dom
21
 */
22
23
/**
24
 *
25
 * Base animation class that provides the interface for building animated effects.
26
 * <p>Usage: var myAnim = new YAHOO.util.Anim(el, { width: { from: 10, to: 100 } }, 1, YAHOO.util.Easing.easeOut);</p>
27
 * @class Anim
28
 * @namespace YAHOO.util
29
 * @requires YAHOO.util.AnimMgr
30
 * @requires YAHOO.util.Easing
31
 * @requires YAHOO.util.Dom
32
 * @requires YAHOO.util.Event
33
 * @requires YAHOO.util.CustomEvent
34
 * @constructor
35
 * @param {String | HTMLElement} el Reference to the element that will be animated
36
 * @param {Object} attributes The attribute(s) to be animated.  
37
 * Each attribute is an object with at minimum a "to" or "by" member defined.  
38
 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
39
 * All attribute names use camelCase.
40
 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
41
 * @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)
42
 */
43
44
var Anim = function(el, attributes, duration, method) {
45
    if (!el) {
46
    }
47
    this.init(el, attributes, duration, method); 
48
};
49
50
Anim.NAME = 'Anim';
51
52
Anim.prototype = {
53
    /**
54
     * Provides a readable name for the Anim instance.
55
     * @method toString
56
     * @return {String}
57
     */
58
    toString: function() {
59
        var el = this.getEl() || {};
60
        var id = el.id || el.tagName;
61
        return (this.constructor.NAME + ': ' + id);
62
    },
63
    
64
    patterns: { // cached for performance
65
        noNegatives:        /width|height|opacity|padding/i, // keep at zero or above
66
        offsetAttribute:  /^((width|height)|(top|left))$/, // use offsetValue as default
67
        defaultUnit:        /width|height|top$|bottom$|left$|right$/i, // use 'px' by default
68
        offsetUnit:         /\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i // IE may return these, so convert these to offset
69
    },
70
    
71
    /**
72
     * Returns the value computed by the animation's "method".
73
     * @method doMethod
74
     * @param {String} attr The name of the attribute.
75
     * @param {Number} start The value this attribute should start from for this animation.
76
     * @param {Number} end  The value this attribute should end at for this animation.
77
     * @return {Number} The Value to be applied to the attribute.
78
     */
79
    doMethod: function(attr, start, end) {
80
        return this.method(this.currentFrame, start, end - start, this.totalFrames);
81
    },
82
    
83
    /**
84
     * Applies a value to an attribute.
85
     * @method setAttribute
86
     * @param {String} attr The name of the attribute.
87
     * @param {Number} val The value to be applied to the attribute.
88
     * @param {String} unit The unit ('px', '%', etc.) of the value.
89
     */
90
    setAttribute: function(attr, val, unit) {
91
        var el = this.getEl();
92
        if ( this.patterns.noNegatives.test(attr) ) {
93
            val = (val > 0) ? val : 0;
94
        }
95
96
        if (attr in el && !('style' in el && attr in el.style)) {
97
            el[attr] = val;
98
        } else {
99
            Y.Dom.setStyle(el, attr, val + unit);
100
        }
101
    },                        
102
    
103
    /**
104
     * Returns current value of the attribute.
105
     * @method getAttribute
106
     * @param {String} attr The name of the attribute.
107
     * @return {Number} val The current value of the attribute.
108
     */
109
    getAttribute: function(attr) {
110
        var el = this.getEl();
111
        var val = Y.Dom.getStyle(el, attr);
112
113
        if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
114
            return parseFloat(val);
115
        }
116
        
117
        var a = this.patterns.offsetAttribute.exec(attr) || [];
118
        var pos = !!( a[3] ); // top or left
119
        var box = !!( a[2] ); // width or height
120
        
121
        if ('style' in el) {
122
            // use offsets for width/height and abs pos top/left
123
            if ( box || (Y.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
124
                val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
125
            } else { // default to zero for other 'auto'
126
                val = 0;
127
            }
128
        } else if (attr in el) {
129
            val = el[attr];
130
        }
131
132
        return val;
133
    },
134
    
135
    /**
136
     * Returns the unit to use when none is supplied.
137
     * @method getDefaultUnit
138
     * @param {attr} attr The name of the attribute.
139
     * @return {String} The default unit to be used.
140
     */
141
    getDefaultUnit: function(attr) {
142
         if ( this.patterns.defaultUnit.test(attr) ) {
143
            return 'px';
144
         }
145
         
146
         return '';
147
    },
148
        
149
    /**
150
     * Sets the actual values to be used during the animation.  Should only be needed for subclass use.
151
     * @method setRuntimeAttribute
152
     * @param {Object} attr The attribute object
153
     * @private 
154
     */
155
    setRuntimeAttribute: function(attr) {
156
        var start;
157
        var end;
158
        var attributes = this.attributes;
159
160
        this.runtimeAttributes[attr] = {};
161
        
162
        var isset = function(prop) {
163
            return (typeof prop !== 'undefined');
164
        };
165
        
166
        if ( !isset(attributes[attr]['to']) && !isset(attributes[attr]['by']) ) {
167
            return false; // note return; nothing to animate to
168
        }
169
        
170
        start = ( isset(attributes[attr]['from']) ) ? attributes[attr]['from'] : this.getAttribute(attr);
171
172
        // To beats by, per SMIL 2.1 spec
173
        if ( isset(attributes[attr]['to']) ) {
174
            end = attributes[attr]['to'];
175
        } else if ( isset(attributes[attr]['by']) ) {
176
            if (start.constructor == Array) {
177
                end = [];
178
                for (var i = 0, len = start.length; i < len; ++i) {
179
                    end[i] = start[i] + attributes[attr]['by'][i] * 1; // times 1 to cast "by" 
180
                }
181
            } else {
182
                end = start + attributes[attr]['by'] * 1;
183
            }
184
        }
185
        
186
        this.runtimeAttributes[attr].start = start;
187
        this.runtimeAttributes[attr].end = end;
188
189
        // set units if needed
190
        this.runtimeAttributes[attr].unit = ( isset(attributes[attr].unit) ) ?
191
                attributes[attr]['unit'] : this.getDefaultUnit(attr);
192
        return true;
193
    },
194
195
    /**
196
     * Constructor for Anim instance.
197
     * @method init
198
     * @param {String | HTMLElement} el Reference to the element that will be animated
199
     * @param {Object} attributes The attribute(s) to be animated.  
200
     * Each attribute is an object with at minimum a "to" or "by" member defined.  
201
     * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
202
     * All attribute names use camelCase.
203
     * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
204
     * @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)
205
     */ 
206
    init: function(el, attributes, duration, method) {
207
        /**
208
         * Whether or not the animation is running.
209
         * @property isAnimated
210
         * @private
211
         * @type Boolean
212
         */
213
        var isAnimated = false;
214
        
215
        /**
216
         * A Date object that is created when the animation begins.
217
         * @property startTime
218
         * @private
219
         * @type Date
220
         */
221
        var startTime = null;
222
        
223
        /**
224
         * The number of frames this animation was able to execute.
225
         * @property actualFrames
226
         * @private
227
         * @type Int
228
         */
229
        var actualFrames = 0; 
230
231
        /**
232
         * The element to be animated.
233
         * @property el
234
         * @private
235
         * @type HTMLElement
236
         */
237
        el = Y.Dom.get(el);
238
        
239
        /**
240
         * The collection of attributes to be animated.  
241
         * Each attribute must have at least a "to" or "by" defined in order to animate.  
242
         * If "to" is supplied, the animation will end with the attribute at that value.  
243
         * If "by" is supplied, the animation will end at that value plus its starting value. 
244
         * If both are supplied, "to" is used, and "by" is ignored. 
245
         * 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).
246
         * @property attributes
247
         * @type Object
248
         */
249
        this.attributes = attributes || {};
250
        
251
        /**
252
         * The length of the animation.  Defaults to "1" (second).
253
         * @property duration
254
         * @type Number
255
         */
256
        this.duration = !YAHOO.lang.isUndefined(duration) ? duration : 1;
257
        
258
        /**
259
         * The method that will provide values to the attribute(s) during the animation. 
260
         * Defaults to "YAHOO.util.Easing.easeNone".
261
         * @property method
262
         * @type Function
263
         */
264
        this.method = method || Y.Easing.easeNone;
265
266
        /**
267
         * Whether or not the duration should be treated as seconds.
268
         * Defaults to true.
269
         * @property useSeconds
270
         * @type Boolean
271
         */
272
        this.useSeconds = true; // default to seconds
273
        
274
        /**
275
         * The location of the current animation on the timeline.
276
         * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
277
         * @property currentFrame
278
         * @type Int
279
         */
280
        this.currentFrame = 0;
281
        
282
        /**
283
         * The total number of frames to be executed.
284
         * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
285
         * @property totalFrames
286
         * @type Int
287
         */
288
        this.totalFrames = Y.AnimMgr.fps;
289
        
290
        /**
291
         * Changes the animated element
292
         * @method setEl
293
         */
294
        this.setEl = function(element) {
295
            el = Y.Dom.get(element);
296
        };
297
        
298
        /**
299
         * Returns a reference to the animated element.
300
         * @method getEl
301
         * @return {HTMLElement}
302
         */
303
        this.getEl = function() { return el; };
304
        
305
        /**
306
         * Checks whether the element is currently animated.
307
         * @method isAnimated
308
         * @return {Boolean} current value of isAnimated.     
309
         */
310
        this.isAnimated = function() {
311
            return isAnimated;
312
        };
313
        
314
        /**
315
         * Returns the animation start time.
316
         * @method getStartTime
317
         * @return {Date} current value of startTime.      
318
         */
319
        this.getStartTime = function() {
320
            return startTime;
321
        };        
322
        
323
        this.runtimeAttributes = {};
324
        
325
        
326
        
327
        /**
328
         * Starts the animation by registering it with the animation manager. 
329
         * @method animate  
330
         */
331
        this.animate = function() {
332
            if ( this.isAnimated() ) {
333
                return false;
334
            }
335
            
336
            this.currentFrame = 0;
337
            
338
            this.totalFrames = ( this.useSeconds ) ? Math.ceil(Y.AnimMgr.fps * this.duration) : this.duration;
339
    
340
            if (this.duration === 0 && this.useSeconds) { // jump to last frame if zero second duration 
341
                this.totalFrames = 1; 
342
            }
343
            Y.AnimMgr.registerElement(this);
344
            return true;
345
        };
346
          
347
        /**
348
         * Stops the animation.  Normally called by AnimMgr when animation completes.
349
         * @method stop
350
         * @param {Boolean} finish (optional) If true, animation will jump to final frame.
351
         */ 
352
        this.stop = function(finish) {
353
            if (!this.isAnimated()) { // nothing to stop
354
                return false;
355
            }
356
357
            if (finish) {
358
                 this.currentFrame = this.totalFrames;
359
                 this._onTween.fire();
360
            }
361
            Y.AnimMgr.stop(this);
362
        };
363
        
364
        var onStart = function() {            
365
            this.onStart.fire();
366
            
367
            this.runtimeAttributes = {};
368
            for (var attr in this.attributes) {
369
                this.setRuntimeAttribute(attr);
370
            }
371
            
372
            isAnimated = true;
373
            actualFrames = 0;
374
            startTime = new Date(); 
375
        };
376
        
377
        /**
378
         * Feeds the starting and ending values for each animated attribute to doMethod once per frame, then applies the resulting value to the attribute(s).
379
         * @private
380
         */
381
         
382
        var onTween = function() {
383
            var data = {
384
                duration: new Date() - this.getStartTime(),
385
                currentFrame: this.currentFrame
386
            };
387
            
388
            data.toString = function() {
389
                return (
390
                    'duration: ' + data.duration +
391
                    ', currentFrame: ' + data.currentFrame
392
                );
393
            };
394
            
395
            this.onTween.fire(data);
396
            
397
            var runtimeAttributes = this.runtimeAttributes;
398
            
399
            for (var attr in runtimeAttributes) {
400
                this.setAttribute(attr, this.doMethod(attr, runtimeAttributes[attr].start, runtimeAttributes[attr].end), runtimeAttributes[attr].unit); 
401
            }
402
            
403
            actualFrames += 1;
404
        };
405
        
406
        var onComplete = function() {
407
            var actual_duration = (new Date() - startTime) / 1000 ;
408
            
409
            var data = {
410
                duration: actual_duration,
411
                frames: actualFrames,
412
                fps: actualFrames / actual_duration
413
            };
414
            
415
            data.toString = function() {
416
                return (
417
                    'duration: ' + data.duration +
418
                    ', frames: ' + data.frames +
419
                    ', fps: ' + data.fps
420
                );
421
            };
422
            
423
            isAnimated = false;
424
            actualFrames = 0;
425
            this.onComplete.fire(data);
426
        };
427
        
428
        /**
429
         * Custom event that fires after onStart, useful in subclassing
430
         * @private
431
         */    
432
        this._onStart = new Y.CustomEvent('_start', this, true);
433
434
        /**
435
         * Custom event that fires when animation begins
436
         * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)
437
         * @event onStart
438
         */    
439
        this.onStart = new Y.CustomEvent('start', this);
440
        
441
        /**
442
         * Custom event that fires between each frame
443
         * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)
444
         * @event onTween
445
         */
446
        this.onTween = new Y.CustomEvent('tween', this);
447
        
448
        /**
449
         * Custom event that fires after onTween
450
         * @private
451
         */
452
        this._onTween = new Y.CustomEvent('_tween', this, true);
453
        
454
        /**
455
         * Custom event that fires when animation ends
456
         * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)
457
         * @event onComplete
458
         */
459
        this.onComplete = new Y.CustomEvent('complete', this);
460
        /**
461
         * Custom event that fires after onComplete
462
         * @private
463
         */
464
        this._onComplete = new Y.CustomEvent('_complete', this, true);
465
466
        this._onStart.subscribe(onStart);
467
        this._onTween.subscribe(onTween);
468
        this._onComplete.subscribe(onComplete);
469
    }
470
};
471
472
    Y.Anim = Anim;
473
})();
474
/**
475
 * Handles animation queueing and threading.
476
 * Used by Anim and subclasses.
477
 * @class AnimMgr
478
 * @namespace YAHOO.util
479
 */
480
YAHOO.util.AnimMgr = new function() {
481
    /** 
482
     * Reference to the animation Interval.
483
     * @property thread
484
     * @private
485
     * @type Int
486
     */
487
    var thread = null;
488
    
489
    /** 
490
     * The current queue of registered animation objects.
491
     * @property queue
492
     * @private
493
     * @type Array
494
     */    
495
    var queue = [];
496
497
    /** 
498
     * The number of active animations.
499
     * @property tweenCount
500
     * @private
501
     * @type Int
502
     */        
503
    var tweenCount = 0;
504
505
    /** 
506
     * Base frame rate (frames per second). 
507
     * Arbitrarily high for better x-browser calibration (slower browsers drop more frames).
508
     * @property fps
509
     * @type Int
510
     * 
511
     */
512
    this.fps = 1000;
513
514
    /** 
515
     * Interval delay in milliseconds, defaults to fastest possible.
516
     * @property delay
517
     * @type Int
518
     * 
519
     */
520
    this.delay = 1;
521
522
    /**
523
     * Adds an animation instance to the animation queue.
524
     * All animation instances must be registered in order to animate.
525
     * @method registerElement
526
     * @param {object} tween The Anim instance to be be registered
527
     */
528
    this.registerElement = function(tween) {
529
        queue[queue.length] = tween;
530
        tweenCount += 1;
531
        tween._onStart.fire();
532
        this.start();
533
    };
534
    
535
    /**
536
     * removes an animation instance from the animation queue.
537
     * All animation instances must be registered in order to animate.
538
     * @method unRegister
539
     * @param {object} tween The Anim instance to be be registered
540
     * @param {Int} index The index of the Anim instance
541
     * @private
542
     */
543
    this.unRegister = function(tween, index) {
544
        index = index || getIndex(tween);
545
        if (!tween.isAnimated() || index === -1) {
546
            return false;
547
        }
548
        
549
        tween._onComplete.fire();
550
        queue.splice(index, 1);
551
552
        tweenCount -= 1;
553
        if (tweenCount <= 0) {
554
            this.stop();
555
        }
556
557
        return true;
558
    };
559
    
560
    /**
561
     * Starts the animation thread.
562
	* Only one thread can run at a time.
563
     * @method start
564
     */    
565
    this.start = function() {
566
        if (thread === null) {
567
            thread = setInterval(this.run, this.delay);
568
        }
569
    };
570
571
    /**
572
     * Stops the animation thread or a specific animation instance.
573
     * @method stop
574
     * @param {object} tween A specific Anim instance to stop (optional)
575
     * If no instance given, Manager stops thread and all animations.
576
     */    
577
    this.stop = function(tween) {
578
        if (!tween) {
579
            clearInterval(thread);
580
            
581
            for (var i = 0, len = queue.length; i < len; ++i) {
582
                this.unRegister(queue[0], 0);  
583
            }
584
585
            queue = [];
586
            thread = null;
587
            tweenCount = 0;
588
        }
589
        else {
590
            this.unRegister(tween);
591
        }
592
    };
593
    
594
    /**
595
     * Called per Interval to handle each animation frame.
596
     * @method run
597
     */    
598
    this.run = function() {
599
        for (var i = 0, len = queue.length; i < len; ++i) {
600
            var tween = queue[i];
601
            if ( !tween || !tween.isAnimated() ) { continue; }
602
603
            if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
604
            {
605
                tween.currentFrame += 1;
606
                
607
                if (tween.useSeconds) {
608
                    correctFrame(tween);
609
                }
610
                tween._onTween.fire();          
611
            }
612
            else { YAHOO.util.AnimMgr.stop(tween, i); }
613
        }
614
    };
615
    
616
    var getIndex = function(anim) {
617
        for (var i = 0, len = queue.length; i < len; ++i) {
618
            if (queue[i] === anim) {
619
                return i; // note return;
620
            }
621
        }
622
        return -1;
623
    };
624
    
625
    /**
626
     * On the fly frame correction to keep animation on time.
627
     * @method correctFrame
628
     * @private
629
     * @param {Object} tween The Anim instance being corrected.
630
     */
631
    var correctFrame = function(tween) {
632
        var frames = tween.totalFrames;
633
        var frame = tween.currentFrame;
634
        var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
635
        var elapsed = (new Date() - tween.getStartTime());
636
        var tweak = 0;
637
        
638
        if (elapsed < tween.duration * 1000) { // check if falling behind
639
            tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
640
        } else { // went over duration, so jump to end
641
            tweak = frames - (frame + 1); 
642
        }
643
        if (tweak > 0 && isFinite(tweak)) { // adjust if needed
644
            if (tween.currentFrame + tweak >= frames) {// dont go past last frame
645
                tweak = frames - (frame + 1);
646
            }
647
            
648
            tween.currentFrame += tweak;      
649
        }
650
    };
651
    this._queue = queue;
652
    this._getIndex = getIndex;
653
};
654
/**
655
 * Used to calculate Bezier splines for any number of control points.
656
 * @class Bezier
657
 * @namespace YAHOO.util
658
 *
659
 */
660
YAHOO.util.Bezier = new function() {
661
    /**
662
     * Get the current position of the animated element based on t.
663
     * Each point is an array of "x" and "y" values (0 = x, 1 = y)
664
     * At least 2 points are required (start and end).
665
     * First point is start. Last point is end.
666
     * Additional control points are optional.     
667
     * @method getPosition
668
     * @param {Array} points An array containing Bezier points
669
     * @param {Number} t A number between 0 and 1 which is the basis for determining current position
670
     * @return {Array} An array containing int x and y member data
671
     */
672
    this.getPosition = function(points, t) {  
673
        var n = points.length;
674
        var tmp = [];
675
676
        for (var i = 0; i < n; ++i){
677
            tmp[i] = [points[i][0], points[i][1]]; // save input
678
        }
679
        
680
        for (var j = 1; j < n; ++j) {
681
            for (i = 0; i < n - j; ++i) {
682
                tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
683
                tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1]; 
684
            }
685
        }
686
    
687
        return [ tmp[0][0], tmp[0][1] ]; 
688
    
689
    };
690
};
691
(function() {
692
/**
693
 * Anim subclass for color transitions.
694
 * <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, 
695
 * [255,255,255], or rgb(255,255,255)</p>
696
 * @class ColorAnim
697
 * @namespace YAHOO.util
698
 * @requires YAHOO.util.Anim
699
 * @requires YAHOO.util.AnimMgr
700
 * @requires YAHOO.util.Easing
701
 * @requires YAHOO.util.Bezier
702
 * @requires YAHOO.util.Dom
703
 * @requires YAHOO.util.Event
704
 * @constructor
705
 * @extends YAHOO.util.Anim
706
 * @param {HTMLElement | String} el Reference to the element that will be animated
707
 * @param {Object} attributes The attribute(s) to be animated.
708
 * Each attribute is an object with at minimum a "to" or "by" member defined.
709
 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
710
 * All attribute names use camelCase.
711
 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
712
 * @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)
713
 */
714
    var ColorAnim = function(el, attributes, duration,  method) {
715
        ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
716
    };
717
    
718
    ColorAnim.NAME = 'ColorAnim';
719
720
    ColorAnim.DEFAULT_BGCOLOR = '#fff';
721
    // shorthand
722
    var Y = YAHOO.util;
723
    YAHOO.extend(ColorAnim, Y.Anim);
724
725
    var superclass = ColorAnim.superclass;
726
    var proto = ColorAnim.prototype;
727
    
728
    proto.patterns.color = /color$/i;
729
    proto.patterns.rgb            = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
730
    proto.patterns.hex            = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
731
    proto.patterns.hex3          = /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;
732
    proto.patterns.transparent = /^transparent|rgba\(0, 0, 0, 0\)$/; // need rgba for safari
733
    
734
    /**
735
     * Attempts to parse the given string and return a 3-tuple.
736
     * @method parseColor
737
     * @param {String} s The string to parse.
738
     * @return {Array} The 3-tuple of rgb values.
739
     */
740
    proto.parseColor = function(s) {
741
        if (s.length == 3) { return s; }
742
    
743
        var c = this.patterns.hex.exec(s);
744
        if (c && c.length == 4) {
745
            return [ parseInt(c[1], 16), parseInt(c[2], 16), parseInt(c[3], 16) ];
746
        }
747
    
748
        c = this.patterns.rgb.exec(s);
749
        if (c && c.length == 4) {
750
            return [ parseInt(c[1], 10), parseInt(c[2], 10), parseInt(c[3], 10) ];
751
        }
752
    
753
        c = this.patterns.hex3.exec(s);
754
        if (c && c.length == 4) {
755
            return [ parseInt(c[1] + c[1], 16), parseInt(c[2] + c[2], 16), parseInt(c[3] + c[3], 16) ];
756
        }
757
        
758
        return null;
759
    };
760
761
    proto.getAttribute = function(attr) {
762
        var el = this.getEl();
763
        if (this.patterns.color.test(attr) ) {
764
            var val = YAHOO.util.Dom.getStyle(el, attr);
765
            
766
            var that = this;
767
            if (this.patterns.transparent.test(val)) { // bgcolor default
768
                var parent = YAHOO.util.Dom.getAncestorBy(el, function(node) {
769
                    return !that.patterns.transparent.test(val);
770
                });
771
772
                if (parent) {
773
                    val = Y.Dom.getStyle(parent, attr);
774
                } else {
775
                    val = ColorAnim.DEFAULT_BGCOLOR;
776
                }
777
            }
778
        } else {
779
            val = superclass.getAttribute.call(this, attr);
780
        }
781
782
        return val;
783
    };
784
    
785
    proto.doMethod = function(attr, start, end) {
786
        var val;
787
    
788
        if ( this.patterns.color.test(attr) ) {
789
            val = [];
790
            for (var i = 0, len = start.length; i < len; ++i) {
791
                val[i] = superclass.doMethod.call(this, attr, start[i], end[i]);
792
            }
793
            
794
            val = 'rgb('+Math.floor(val[0])+','+Math.floor(val[1])+','+Math.floor(val[2])+')';
795
        }
796
        else {
797
            val = superclass.doMethod.call(this, attr, start, end);
798
        }
799
800
        return val;
801
    };
802
803
    proto.setRuntimeAttribute = function(attr) {
804
        superclass.setRuntimeAttribute.call(this, attr);
805
        
806
        if ( this.patterns.color.test(attr) ) {
807
            var attributes = this.attributes;
808
            var start = this.parseColor(this.runtimeAttributes[attr].start);
809
            var end = this.parseColor(this.runtimeAttributes[attr].end);
810
            // fix colors if going "by"
811
            if ( typeof attributes[attr]['to'] === 'undefined' && typeof attributes[attr]['by'] !== 'undefined' ) {
812
                end = this.parseColor(attributes[attr].by);
813
            
814
                for (var i = 0, len = start.length; i < len; ++i) {
815
                    end[i] = start[i] + end[i];
816
                }
817
            }
818
            
819
            this.runtimeAttributes[attr].start = start;
820
            this.runtimeAttributes[attr].end = end;
821
        }
822
    };
823
824
    Y.ColorAnim = ColorAnim;
825
})();
826
/*!
827
TERMS OF USE - EASING EQUATIONS
828
Open source under the BSD License.
829
Copyright 2001 Robert Penner All rights reserved.
830
831
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
832
833
 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
834
 * 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.
835
 * 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.
836
837
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.
838
*/
839
840
/**
841
 * Singleton that determines how an animation proceeds from start to end.
842
 * @class Easing
843
 * @namespace YAHOO.util
844
*/
845
846
YAHOO.util.Easing = {
847
848
    /**
849
     * Uniform speed between points.
850
     * @method easeNone
851
     * @param {Number} t Time value used to compute current value
852
     * @param {Number} b Starting value
853
     * @param {Number} c Delta between start and end values
854
     * @param {Number} d Total length of animation
855
     * @return {Number} The computed value for the current animation frame
856
     */
857
    easeNone: function (t, b, c, d) {
858
    	return c*t/d + b;
859
    },
860
    
861
    /**
862
     * Begins slowly and accelerates towards end.
863
     * @method easeIn
864
     * @param {Number} t Time value used to compute current value
865
     * @param {Number} b Starting value
866
     * @param {Number} c Delta between start and end values
867
     * @param {Number} d Total length of animation
868
     * @return {Number} The computed value for the current animation frame
869
     */
870
    easeIn: function (t, b, c, d) {
871
    	return c*(t/=d)*t + b;
872
    },
873
874
    /**
875
     * Begins quickly and decelerates towards end.
876
     * @method easeOut
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
     * @return {Number} The computed value for the current animation frame
882
     */
883
    easeOut: function (t, b, c, d) {
884
    	return -c *(t/=d)*(t-2) + b;
885
    },
886
    
887
    /**
888
     * Begins slowly and decelerates towards end.
889
     * @method easeBoth
890
     * @param {Number} t Time value used to compute current value
891
     * @param {Number} b Starting value
892
     * @param {Number} c Delta between start and end values
893
     * @param {Number} d Total length of animation
894
     * @return {Number} The computed value for the current animation frame
895
     */
896
    easeBoth: function (t, b, c, d) {
897
    	if ((t/=d/2) < 1) {
898
            return c/2*t*t + b;
899
        }
900
        
901
    	return -c/2 * ((--t)*(t-2) - 1) + b;
902
    },
903
    
904
    /**
905
     * Begins slowly and accelerates towards end.
906
     * @method easeInStrong
907
     * @param {Number} t Time value used to compute current value
908
     * @param {Number} b Starting value
909
     * @param {Number} c Delta between start and end values
910
     * @param {Number} d Total length of animation
911
     * @return {Number} The computed value for the current animation frame
912
     */
913
    easeInStrong: function (t, b, c, d) {
914
    	return c*(t/=d)*t*t*t + b;
915
    },
916
    
917
    /**
918
     * Begins quickly and decelerates towards end.
919
     * @method easeOutStrong
920
     * @param {Number} t Time value used to compute current value
921
     * @param {Number} b Starting value
922
     * @param {Number} c Delta between start and end values
923
     * @param {Number} d Total length of animation
924
     * @return {Number} The computed value for the current animation frame
925
     */
926
    easeOutStrong: function (t, b, c, d) {
927
    	return -c * ((t=t/d-1)*t*t*t - 1) + b;
928
    },
929
    
930
    /**
931
     * Begins slowly and decelerates towards end.
932
     * @method easeBothStrong
933
     * @param {Number} t Time value used to compute current value
934
     * @param {Number} b Starting value
935
     * @param {Number} c Delta between start and end values
936
     * @param {Number} d Total length of animation
937
     * @return {Number} The computed value for the current animation frame
938
     */
939
    easeBothStrong: function (t, b, c, d) {
940
    	if ((t/=d/2) < 1) {
941
            return c/2*t*t*t*t + b;
942
        }
943
        
944
    	return -c/2 * ((t-=2)*t*t*t - 2) + b;
945
    },
946
947
    /**
948
     * Snap in elastic effect.
949
     * @method elasticIn
950
     * @param {Number} t Time value used to compute current value
951
     * @param {Number} b Starting value
952
     * @param {Number} c Delta between start and end values
953
     * @param {Number} d Total length of animation
954
     * @param {Number} a Amplitude (optional)
955
     * @param {Number} p Period (optional)
956
     * @return {Number} The computed value for the current animation frame
957
     */
958
959
    elasticIn: function (t, b, c, d, a, p) {
960
    	if (t == 0) {
961
            return b;
962
        }
963
        if ( (t /= d) == 1 ) {
964
            return b+c;
965
        }
966
        if (!p) {
967
            p=d*.3;
968
        }
969
        
970
    	if (!a || a < Math.abs(c)) {
971
            a = c; 
972
            var s = p/4;
973
        }
974
    	else {
975
            var s = p/(2*Math.PI) * Math.asin (c/a);
976
        }
977
        
978
    	return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
979
    },
980
981
    /**
982
     * Snap out elastic effect.
983
     * @method elasticOut
984
     * @param {Number} t Time value used to compute current value
985
     * @param {Number} b Starting value
986
     * @param {Number} c Delta between start and end values
987
     * @param {Number} d Total length of animation
988
     * @param {Number} a Amplitude (optional)
989
     * @param {Number} p Period (optional)
990
     * @return {Number} The computed value for the current animation frame
991
     */
992
    elasticOut: function (t, b, c, d, a, p) {
993
    	if (t == 0) {
994
            return b;
995
        }
996
        if ( (t /= d) == 1 ) {
997
            return b+c;
998
        }
999
        if (!p) {
1000
            p=d*.3;
1001
        }
1002
        
1003
    	if (!a || a < Math.abs(c)) {
1004
            a = c;
1005
            var s = p / 4;
1006
        }
1007
    	else {
1008
            var s = p/(2*Math.PI) * Math.asin (c/a);
1009
        }
1010
        
1011
    	return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
1012
    },
1013
    
1014
    /**
1015
     * Snap both elastic effect.
1016
     * @method elasticBoth
1017
     * @param {Number} t Time value used to compute current value
1018
     * @param {Number} b Starting value
1019
     * @param {Number} c Delta between start and end values
1020
     * @param {Number} d Total length of animation
1021
     * @param {Number} a Amplitude (optional)
1022
     * @param {Number} p Period (optional)
1023
     * @return {Number} The computed value for the current animation frame
1024
     */
1025
    elasticBoth: function (t, b, c, d, a, p) {
1026
    	if (t == 0) {
1027
            return b;
1028
        }
1029
        
1030
        if ( (t /= d/2) == 2 ) {
1031
            return b+c;
1032
        }
1033
        
1034
        if (!p) {
1035
            p = d*(.3*1.5);
1036
        }
1037
        
1038
    	if ( !a || a < Math.abs(c) ) {
1039
            a = c; 
1040
            var s = p/4;
1041
        }
1042
    	else {
1043
            var s = p/(2*Math.PI) * Math.asin (c/a);
1044
        }
1045
        
1046
    	if (t < 1) {
1047
            return -.5*(a*Math.pow(2,10*(t-=1)) * 
1048
                    Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
1049
        }
1050
    	return a*Math.pow(2,-10*(t-=1)) * 
1051
                Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
1052
    },
1053
1054
1055
    /**
1056
     * Backtracks slightly, then reverses direction and moves to end.
1057
     * @method backIn
1058
     * @param {Number} t Time value used to compute current value
1059
     * @param {Number} b Starting value
1060
     * @param {Number} c Delta between start and end values
1061
     * @param {Number} d Total length of animation
1062
     * @param {Number} s Overshoot (optional)
1063
     * @return {Number} The computed value for the current animation frame
1064
     */
1065
    backIn: function (t, b, c, d, s) {
1066
    	if (typeof s == 'undefined') {
1067
            s = 1.70158;
1068
        }
1069
    	return c*(t/=d)*t*((s+1)*t - s) + b;
1070
    },
1071
1072
    /**
1073
     * Overshoots end, then reverses and comes back to end.
1074
     * @method backOut
1075
     * @param {Number} t Time value used to compute current value
1076
     * @param {Number} b Starting value
1077
     * @param {Number} c Delta between start and end values
1078
     * @param {Number} d Total length of animation
1079
     * @param {Number} s Overshoot (optional)
1080
     * @return {Number} The computed value for the current animation frame
1081
     */
1082
    backOut: function (t, b, c, d, s) {
1083
    	if (typeof s == 'undefined') {
1084
            s = 1.70158;
1085
        }
1086
    	return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
1087
    },
1088
    
1089
    /**
1090
     * Backtracks slightly, then reverses direction, overshoots end, 
1091
     * then reverses and comes back to end.
1092
     * @method backBoth
1093
     * @param {Number} t Time value used to compute current value
1094
     * @param {Number} b Starting value
1095
     * @param {Number} c Delta between start and end values
1096
     * @param {Number} d Total length of animation
1097
     * @param {Number} s Overshoot (optional)
1098
     * @return {Number} The computed value for the current animation frame
1099
     */
1100
    backBoth: function (t, b, c, d, s) {
1101
    	if (typeof s == 'undefined') {
1102
            s = 1.70158; 
1103
        }
1104
        
1105
    	if ((t /= d/2 ) < 1) {
1106
            return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
1107
        }
1108
    	return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
1109
    },
1110
1111
    /**
1112
     * Bounce off of start.
1113
     * @method bounceIn
1114
     * @param {Number} t Time value used to compute current value
1115
     * @param {Number} b Starting value
1116
     * @param {Number} c Delta between start and end values
1117
     * @param {Number} d Total length of animation
1118
     * @return {Number} The computed value for the current animation frame
1119
     */
1120
    bounceIn: function (t, b, c, d) {
1121
    	return c - YAHOO.util.Easing.bounceOut(d-t, 0, c, d) + b;
1122
    },
1123
    
1124
    /**
1125
     * Bounces off end.
1126
     * @method bounceOut
1127
     * @param {Number} t Time value used to compute current value
1128
     * @param {Number} b Starting value
1129
     * @param {Number} c Delta between start and end values
1130
     * @param {Number} d Total length of animation
1131
     * @return {Number} The computed value for the current animation frame
1132
     */
1133
    bounceOut: function (t, b, c, d) {
1134
    	if ((t/=d) < (1/2.75)) {
1135
    		return c*(7.5625*t*t) + b;
1136
    	} else if (t < (2/2.75)) {
1137
    		return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
1138
    	} else if (t < (2.5/2.75)) {
1139
    		return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
1140
    	}
1141
        return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
1142
    },
1143
    
1144
    /**
1145
     * Bounces off start and end.
1146
     * @method bounceBoth
1147
     * @param {Number} t Time value used to compute current value
1148
     * @param {Number} b Starting value
1149
     * @param {Number} c Delta between start and end values
1150
     * @param {Number} d Total length of animation
1151
     * @return {Number} The computed value for the current animation frame
1152
     */
1153
    bounceBoth: function (t, b, c, d) {
1154
    	if (t < d/2) {
1155
            return YAHOO.util.Easing.bounceIn(t*2, 0, c, d) * .5 + b;
1156
        }
1157
    	return YAHOO.util.Easing.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
1158
    }
1159
};
1160
1161
(function() {
1162
/**
1163
 * Anim subclass for moving elements along a path defined by the "points" 
1164
 * member of "attributes".  All "points" are arrays with x, y coordinates.
1165
 * <p>Usage: <code>var myAnim = new YAHOO.util.Motion(el, { points: { to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1166
 * @class Motion
1167
 * @namespace YAHOO.util
1168
 * @requires YAHOO.util.Anim
1169
 * @requires YAHOO.util.AnimMgr
1170
 * @requires YAHOO.util.Easing
1171
 * @requires YAHOO.util.Bezier
1172
 * @requires YAHOO.util.Dom
1173
 * @requires YAHOO.util.Event
1174
 * @requires YAHOO.util.CustomEvent 
1175
 * @constructor
1176
 * @extends YAHOO.util.ColorAnim
1177
 * @param {String | HTMLElement} el Reference to the element that will be animated
1178
 * @param {Object} attributes The attribute(s) to be animated.  
1179
 * Each attribute is an object with at minimum a "to" or "by" member defined.  
1180
 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
1181
 * All attribute names use camelCase.
1182
 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1183
 * @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)
1184
 */
1185
    var Motion = function(el, attributes, duration,  method) {
1186
        if (el) { // dont break existing subclasses not using YAHOO.extend
1187
            Motion.superclass.constructor.call(this, el, attributes, duration, method);
1188
        }
1189
    };
1190
1191
1192
    Motion.NAME = 'Motion';
1193
1194
    // shorthand
1195
    var Y = YAHOO.util;
1196
    YAHOO.extend(Motion, Y.ColorAnim);
1197
    
1198
    var superclass = Motion.superclass;
1199
    var proto = Motion.prototype;
1200
1201
    proto.patterns.points = /^points$/i;
1202
    
1203
    proto.setAttribute = function(attr, val, unit) {
1204
        if (  this.patterns.points.test(attr) ) {
1205
            unit = unit || 'px';
1206
            superclass.setAttribute.call(this, 'left', val[0], unit);
1207
            superclass.setAttribute.call(this, 'top', val[1], unit);
1208
        } else {
1209
            superclass.setAttribute.call(this, attr, val, unit);
1210
        }
1211
    };
1212
1213
    proto.getAttribute = function(attr) {
1214
        if (  this.patterns.points.test(attr) ) {
1215
            var val = [
1216
                superclass.getAttribute.call(this, 'left'),
1217
                superclass.getAttribute.call(this, 'top')
1218
            ];
1219
        } else {
1220
            val = superclass.getAttribute.call(this, attr);
1221
        }
1222
1223
        return val;
1224
    };
1225
1226
    proto.doMethod = function(attr, start, end) {
1227
        var val = null;
1228
1229
        if ( this.patterns.points.test(attr) ) {
1230
            var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;				
1231
            val = Y.Bezier.getPosition(this.runtimeAttributes[attr], t);
1232
        } else {
1233
            val = superclass.doMethod.call(this, attr, start, end);
1234
        }
1235
        return val;
1236
    };
1237
1238
    proto.setRuntimeAttribute = function(attr) {
1239
        if ( this.patterns.points.test(attr) ) {
1240
            var el = this.getEl();
1241
            var attributes = this.attributes;
1242
            var start;
1243
            var control = attributes['points']['control'] || [];
1244
            var end;
1245
            var i, len;
1246
            
1247
            if (control.length > 0 && !(control[0] instanceof Array) ) { // could be single point or array of points
1248
                control = [control];
1249
            } else { // break reference to attributes.points.control
1250
                var tmp = []; 
1251
                for (i = 0, len = control.length; i< len; ++i) {
1252
                    tmp[i] = control[i];
1253
                }
1254
                control = tmp;
1255
            }
1256
1257
            if (Y.Dom.getStyle(el, 'position') == 'static') { // default to relative
1258
                Y.Dom.setStyle(el, 'position', 'relative');
1259
            }
1260
    
1261
            if ( isset(attributes['points']['from']) ) {
1262
                Y.Dom.setXY(el, attributes['points']['from']); // set position to from point
1263
            } 
1264
            else { Y.Dom.setXY( el, Y.Dom.getXY(el) ); } // set it to current position
1265
            
1266
            start = this.getAttribute('points'); // get actual top & left
1267
            
1268
            // TO beats BY, per SMIL 2.1 spec
1269
            if ( isset(attributes['points']['to']) ) {
1270
                end = translateValues.call(this, attributes['points']['to'], start);
1271
                
1272
                var pageXY = Y.Dom.getXY(this.getEl());
1273
                for (i = 0, len = control.length; i < len; ++i) {
1274
                    control[i] = translateValues.call(this, control[i], start);
1275
                }
1276
1277
                
1278
            } else if ( isset(attributes['points']['by']) ) {
1279
                end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1] ];
1280
                
1281
                for (i = 0, len = control.length; i < len; ++i) {
1282
                    control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
1283
                }
1284
            }
1285
1286
            this.runtimeAttributes[attr] = [start];
1287
            
1288
            if (control.length > 0) {
1289
                this.runtimeAttributes[attr] = this.runtimeAttributes[attr].concat(control); 
1290
            }
1291
1292
            this.runtimeAttributes[attr][this.runtimeAttributes[attr].length] = end;
1293
        }
1294
        else {
1295
            superclass.setRuntimeAttribute.call(this, attr);
1296
        }
1297
    };
1298
    
1299
    var translateValues = function(val, start) {
1300
        var pageXY = Y.Dom.getXY(this.getEl());
1301
        val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];
1302
1303
        return val; 
1304
    };
1305
    
1306
    var isset = function(prop) {
1307
        return (typeof prop !== 'undefined');
1308
    };
1309
1310
    Y.Motion = Motion;
1311
})();
1312
(function() {
1313
/**
1314
 * Anim subclass for scrolling elements to a position defined by the "scroll"
1315
 * member of "attributes".  All "scroll" members are arrays with x, y scroll positions.
1316
 * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
1317
 * @class Scroll
1318
 * @namespace YAHOO.util
1319
 * @requires YAHOO.util.Anim
1320
 * @requires YAHOO.util.AnimMgr
1321
 * @requires YAHOO.util.Easing
1322
 * @requires YAHOO.util.Bezier
1323
 * @requires YAHOO.util.Dom
1324
 * @requires YAHOO.util.Event
1325
 * @requires YAHOO.util.CustomEvent 
1326
 * @extends YAHOO.util.ColorAnim
1327
 * @constructor
1328
 * @param {String or HTMLElement} el Reference to the element that will be animated
1329
 * @param {Object} attributes The attribute(s) to be animated.  
1330
 * Each attribute is an object with at minimum a "to" or "by" member defined.  
1331
 * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
1332
 * All attribute names use camelCase.
1333
 * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
1334
 * @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)
1335
 */
1336
    var Scroll = function(el, attributes, duration,  method) {
1337
        if (el) { // dont break existing subclasses not using YAHOO.extend
1338
            Scroll.superclass.constructor.call(this, el, attributes, duration, method);
1339
        }
1340
    };
1341
1342
    Scroll.NAME = 'Scroll';
1343
1344
    // shorthand
1345
    var Y = YAHOO.util;
1346
    YAHOO.extend(Scroll, Y.ColorAnim);
1347
    
1348
    var superclass = Scroll.superclass;
1349
    var proto = Scroll.prototype;
1350
1351
    proto.doMethod = function(attr, start, end) {
1352
        var val = null;
1353
    
1354
        if (attr == 'scroll') {
1355
            val = [
1356
                this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),
1357
                this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)
1358
            ];
1359
            
1360
        } else {
1361
            val = superclass.doMethod.call(this, attr, start, end);
1362
        }
1363
        return val;
1364
    };
1365
1366
    proto.getAttribute = function(attr) {
1367
        var val = null;
1368
        var el = this.getEl();
1369
        
1370
        if (attr == 'scroll') {
1371
            val = [ el.scrollLeft, el.scrollTop ];
1372
        } else {
1373
            val = superclass.getAttribute.call(this, attr);
1374
        }
1375
        
1376
        return val;
1377
    };
1378
1379
    proto.setAttribute = function(attr, val, unit) {
1380
        var el = this.getEl();
1381
        
1382
        if (attr == 'scroll') {
1383
            el.scrollLeft = val[0];
1384
            el.scrollTop = val[1];
1385
        } else {
1386
            superclass.setAttribute.call(this, attr, val, unit);
1387
        }
1388
    };
1389
1390
    Y.Scroll = Scroll;
1391
})();
1392
YAHOO.register("animation", YAHOO.util.Anim, {version: "2.8.0r4", build: "2449"});
(-)a/koha-tmpl/intranet-tmpl/lib/yui/button/assets/button-core.css (-44 lines)
Lines 1-44 Link Here
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
.yui-button  {
8
9
    display: -moz-inline-box; /* Gecko */
10
    display: inline-block; /* IE, Opera and Safari */
11
    vertical-align: text-bottom;
12
    
13
}
14
15
.yui-button .first-child {
16
17
    display: block;
18
    *display: inline-block; /* IE */
19
20
}
21
22
.yui-button button,
23
.yui-button a {
24
25
    display: block;
26
    *display: inline-block; /* IE */
27
    border: none;
28
    margin: 0;
29
30
}
31
32
.yui-button button {
33
34
    background-color: transparent;
35
    *overflow: visible; /* Remove superfluous padding for IE */
36
    cursor: pointer;
37
38
}
39
40
.yui-button a {
41
42
    text-decoration: none;
43
44
}
(-)a/koha-tmpl/intranet-tmpl/lib/yui/button/assets/skins/sam/button-skin.css (-219 lines)
Lines 1-219 Link Here
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
.yui-skin-sam .yui-button  {
8
9
    border-width: 1px 0;
10
    border-style: solid;
11
    border-color: #808080;
12
    background: url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;
13
    margin: auto .25em;
14
    
15
}
16
17
.yui-skin-sam .yui-button .first-child {
18
19
    border-width: 0 1px;
20
    border-style: solid;
21
    border-color: #808080;
22
    margin: 0 -1px;
23
24
	/*
25
		Using negative margins for rounded corners won't work in IE 6 and IE 7 
26
		(Quirks Mode Only), so set the "margin" property to "0" for those 
27
		browsers.
28
	*/
29
 	_margin: 0;
30
31
}
32
33
.yui-skin-sam .yui-button button,
34
.yui-skin-sam .yui-button a,
35
.yui-skin-sam .yui-button a:visited {
36
37
    padding: 0 10px;
38
    font-size: 93%;  /* 12px */
39
    line-height: 2;  /* ~24px */
40
    *line-height: 1.7; /* For IE */
41
    min-height: 2em; /* For Gecko */
42
    *min-height: auto; /* For IE */
43
    color: #000; 
44
45
}
46
47
.yui-skin-sam .yui-button a {
48
49
    /*
50
        Necessary to get Buttons of type "link" to be the correct 
51
        height in IE.
52
    */
53
    *line-height: 1.875;
54
	*padding-bottom: 1px;
55
56
}
57
58
.yui-skin-sam .yui-split-button button,
59
.yui-skin-sam .yui-menu-button button {
60
61
    padding-right: 20px;
62
    background-position: right center;
63
    background-repeat: no-repeat;
64
    
65
}
66
67
.yui-skin-sam .yui-menu-button button {
68
69
    background-image: url(menu-button-arrow.png);
70
71
}
72
73
.yui-skin-sam .yui-split-button button {
74
75
    background-image: url(split-button-arrow.png);
76
77
}
78
79
80
/* Focus state */
81
82
83
.yui-skin-sam .yui-button-focus {
84
85
    border-color: #7D98B8;
86
    background-position: 0 -1300px;
87
88
}
89
90
.yui-skin-sam .yui-button-focus .first-child {
91
92
    border-color: #7D98B8;
93
94
}
95
96
.yui-skin-sam .yui-split-button-focus button {
97
98
    background-image: url(split-button-arrow-focus.png);
99
100
}
101
102
103
/* Hover state */
104
105
.yui-skin-sam .yui-button-hover {
106
107
    border-color: #7D98B8;
108
    background-position: 0 -1300px;
109
110
}
111
112
.yui-skin-sam .yui-button-hover .first-child {
113
114
    border-color: #7D98B8;
115
116
}
117
118
.yui-skin-sam .yui-split-button-hover button {
119
120
    background-image: url(split-button-arrow-hover.png);
121
122
}
123
124
125
/* Active state */
126
127
.yui-skin-sam .yui-button-active {
128
    
129
    border-color: #7D98B8;
130
    background-position: 0 -1700px;
131
    
132
}
133
134
.yui-skin-sam .yui-button-active .first-child {
135
136
    border-color: #7D98B8;
137
138
}
139
140
.yui-skin-sam .yui-split-button-activeoption {
141
142
    border-color: #808080;
143
    background-position: 0 0;
144
145
}
146
147
.yui-skin-sam .yui-split-button-activeoption .first-child {
148
149
    border-color: #808080;
150
151
}
152
153
.yui-skin-sam .yui-split-button-activeoption button {
154
155
    background-image: url(split-button-arrow-active.png);
156
157
}
158
159
160
/* Checked state */
161
162
.yui-skin-sam .yui-radio-button-checked,
163
.yui-skin-sam .yui-checkbox-button-checked {
164
    
165
    border-color: #304369;
166
    background-position: 0 -1400px;
167
    
168
}
169
170
.yui-skin-sam .yui-radio-button-checked .first-child,
171
.yui-skin-sam .yui-checkbox-button-checked .first-child {
172
173
    border-color: #304369;
174
175
}
176
177
.yui-skin-sam .yui-radio-button-checked button,
178
.yui-skin-sam .yui-checkbox-button-checked button { 
179
180
    color: #fff;
181
182
}
183
184
185
/* Disabled state */
186
187
.yui-skin-sam .yui-button-disabled {
188
    
189
    border-color: #ccc;
190
    background-position: 0 -1500px;
191
    
192
}
193
194
.yui-skin-sam .yui-button-disabled .first-child {
195
196
    border-color: #ccc;
197
198
}
199
200
.yui-skin-sam .yui-button-disabled button, 
201
.yui-skin-sam .yui-button-disabled a,
202
.yui-skin-sam .yui-button-disabled a:visited {
203
204
    color: #A6A6A6;
205
    cursor: default;
206
207
}
208
209
.yui-skin-sam .yui-menu-button-disabled button {
210
211
    background-image: url(menu-button-arrow-disabled.png);
212
    
213
}
214
215
.yui-skin-sam .yui-split-button-disabled button {
216
217
    background-image: url(split-button-arrow-disabled.png);
218
    
219
}
(-)a/koha-tmpl/intranet-tmpl/lib/yui/button/assets/skins/sam/button.css (-7 lines)
Lines 1-7 Link Here
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
.yui-button{display:-moz-inline-box;display:inline-block;vertical-align:text-bottom;}.yui-button .first-child{display:block;*display:inline-block;}.yui-button button,.yui-button a{display:block;*display:inline-block;border:none;margin:0;}.yui-button button{background-color:transparent;*overflow:visible;cursor:pointer;}.yui-button a{text-decoration:none;}.yui-skin-sam .yui-button{border-width:1px 0;border-style:solid;border-color:#808080;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;margin:auto .25em;}.yui-skin-sam .yui-button .first-child{border-width:0 1px;border-style:solid;border-color:#808080;margin:0 -1px;_margin:0;}.yui-skin-sam .yui-button button,.yui-skin-sam .yui-button a,.yui-skin-sam .yui-button a:visited{padding:0 10px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-button a{*line-height:1.875;*padding-bottom:1px;}.yui-skin-sam .yui-split-button button,.yui-skin-sam .yui-menu-button button{padding-right:20px;background-position:right center;background-repeat:no-repeat;}.yui-skin-sam .yui-menu-button button{background-image:url(menu-button-arrow.png);}.yui-skin-sam .yui-split-button button{background-image:url(split-button-arrow.png);}.yui-skin-sam .yui-button-focus{border-color:#7D98B8;background-position:0 -1300px;}.yui-skin-sam .yui-button-focus .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-split-button-focus button{background-image:url(split-button-arrow-focus.png);}.yui-skin-sam .yui-button-hover{border-color:#7D98B8;background-position:0 -1300px;}.yui-skin-sam .yui-button-hover .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-split-button-hover button{background-image:url(split-button-arrow-hover.png);}.yui-skin-sam .yui-button-active{border-color:#7D98B8;background-position:0 -1700px;}.yui-skin-sam .yui-button-active .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-split-button-activeoption{border-color:#808080;background-position:0 0;}.yui-skin-sam .yui-split-button-activeoption .first-child{border-color:#808080;}.yui-skin-sam .yui-split-button-activeoption button{background-image:url(split-button-arrow-active.png);}.yui-skin-sam .yui-radio-button-checked,.yui-skin-sam .yui-checkbox-button-checked{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-radio-button-checked .first-child,.yui-skin-sam .yui-checkbox-button-checked .first-child{border-color:#304369;}.yui-skin-sam .yui-radio-button-checked button,.yui-skin-sam .yui-checkbox-button-checked button{color:#fff;}.yui-skin-sam .yui-button-disabled{border-color:#ccc;background-position:0 -1500px;}.yui-skin-sam .yui-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-button-disabled button,.yui-skin-sam .yui-button-disabled a,.yui-skin-sam .yui-button-disabled a:visited{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-menu-button-disabled button{background-image:url(menu-button-arrow-disabled.png);}.yui-skin-sam .yui-split-button-disabled button{background-image:url(split-button-arrow-disabled.png);}
(-)a/koha-tmpl/intranet-tmpl/lib/yui/button/button-beta-min.js (-11 lines)
Lines 1-11 Link Here
1
/*
2
Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3
Code licensed under the BSD License:
4
http://developer.yahoo.net/yui/license.txt
5
version: 2.3.1
6
*/
7
(function(){var G=YAHOO.util.Dom,L=YAHOO.util.Event,I=YAHOO.lang,B=YAHOO.widget.Overlay,J=YAHOO.widget.Menu,D={},K=null,E=null,C=null;function F(N,M,Q,O){var R,P;if(I.isString(N)&&I.isString(M)){if(YAHOO.env.ua.ie){P="<input type=\""+N+"\" name=\""+M+"\"";if(O){P+=" checked";}P+=">";R=document.createElement(P);}else{R=document.createElement("input");R.name=M;R.type=N;if(O){R.checked=true;}}R.value=Q;return R;}}function H(N,T){var M=N.nodeName.toUpperCase(),R=this,S,O,P;function U(V){if(!(V in T)){S=N.getAttributeNode(V);if(S&&("value" in S)){T[V]=S.value;}}}function Q(){U("type");if(T.type=="button"){T.type="push";}if(!("disabled" in T)){T.disabled=N.disabled;}U("name");U("value");U("title");}switch(M){case"A":T.type="link";U("href");U("target");break;case"INPUT":Q();if(!("checked" in T)){T.checked=N.checked;}break;case"BUTTON":Q();O=N.parentNode.parentNode;if(G.hasClass(O,this.CSS_CLASS_NAME+"-checked")){T.checked=true;}if(G.hasClass(O,this.CSS_CLASS_NAME+"-disabled")){T.disabled=true;}N.removeAttribute("value");N.setAttribute("type","button");break;}N.removeAttribute("id");N.removeAttribute("name");if(!("tabindex" in T)){T.tabindex=N.tabIndex;}if(!("label" in T)){P=M=="INPUT"?N.value:N.innerHTML;if(P&&P.length>0){T.label=P;}}}function A(O){var N=O.attributes,M=N.srcelement,Q=M.nodeName.toUpperCase(),P=this;if(Q==this.NODE_NAME){O.element=M;O.id=M.id;G.getElementsBy(function(R){switch(R.nodeName.toUpperCase()){case"BUTTON":case"A":case"INPUT":H.call(P,R,N);break;}},"*",M);}else{switch(Q){case"BUTTON":case"A":case"INPUT":H.call(this,M,N);break;}}}YAHOO.widget.Button=function(Q,N){var P=YAHOO.widget.Button.superclass.constructor,O,M;if(arguments.length==1&&!I.isString(Q)&&!Q.nodeName){if(!Q.id){Q.id=G.generateId();}P.call(this,(this.createButtonElement(Q.type)),Q);}else{O={element:null,attributes:(N||{})};if(I.isString(Q)){M=G.get(Q);if(M){if(!O.attributes.id){O.attributes.id=Q;}O.attributes.srcelement=M;A.call(this,O);if(!O.element){O.element=this.createButtonElement(O.attributes.type);}P.call(this,O.element,O.attributes);}}else{if(Q.nodeName){if(!O.attributes.id){if(Q.id){O.attributes.id=Q.id;}else{O.attributes.id=G.generateId();}}O.attributes.srcelement=Q;A.call(this,O);if(!O.element){O.element=this.createButtonElement(O.attributes.type);}P.call(this,O.element,O.attributes);}}}};YAHOO.extend(YAHOO.widget.Button,YAHOO.util.Element,{_button:null,_menu:null,_hiddenFields:null,_onclickAttributeValue:null,_activationKeyPressed:false,_activationButtonPressed:false,_hasKeyEventHandlers:false,_hasMouseEventHandlers:false,NODE_NAME:"SPAN",CHECK_ACTIVATION_KEYS:[32],ACTIVATION_KEYS:[13,32],OPTION_AREA_WIDTH:20,CSS_CLASS_NAME:"yui-button",RADIO_DEFAULT_TITLE:"Unchecked.  Click to check.",RADIO_CHECKED_TITLE:"Checked.  Click to uncheck.",CHECKBOX_DEFAULT_TITLE:"Unchecked.  Click to check.",CHECKBOX_CHECKED_TITLE:"Checked.  Click to uncheck.",MENUBUTTON_DEFAULT_TITLE:"Menu collapsed.  Click to expand.",MENUBUTTON_MENU_VISIBLE_TITLE:"Menu expanded.  Click or press Esc to collapse.",SPLITBUTTON_DEFAULT_TITLE:("Menu collapsed.  Click inside option region or press Ctrl + Shift + M to show the menu."),SPLITBUTTON_OPTION_VISIBLE_TITLE:"Menu expanded.  Press Esc or Ctrl + Shift + M to hide the menu.",SUBMIT_TITLE:"Click to submit form.",_setType:function(M){if(M=="split"){this.on("option",this._onOption);}},_setLabel:function(M){this._button.innerHTML=M;var O,N;if(YAHOO.env.ua.gecko&&G.inDocument(this.get("element"))){N=this;O=this.CSS_CLASS_NAME;this.removeClass(O);window.setTimeout(function(){N.addClass(O);},0);}},_setTabIndex:function(M){this._button.tabIndex=M;},_setTitle:function(N){var M=N;if(this.get("type")!="link"){if(!M){switch(this.get("type")){case"radio":M=this.RADIO_DEFAULT_TITLE;break;case"checkbox":M=this.CHECKBOX_DEFAULT_TITLE;break;case"menu":M=this.MENUBUTTON_DEFAULT_TITLE;break;case"split":M=this.SPLITBUTTON_DEFAULT_TITLE;break;case"submit":M=this.SUBMIT_TITLE;break;}}this._button.title=M;}},_setDisabled:function(M){if(this.get("type")!="link"){if(M){if(this._menu){this._menu.hide();}if(this.hasFocus()){this.blur();}this._button.setAttribute("disabled","disabled");this.addStateCSSClasses("disabled");this.removeStateCSSClasses("hover");this.removeStateCSSClasses("active");this.removeStateCSSClasses("focus");}else{this._button.removeAttribute("disabled");this.removeStateCSSClasses("disabled");}}},_setHref:function(M){if(this.get("type")=="link"){this._button.href=M;}},_setTarget:function(M){if(this.get("type")=="link"){this._button.setAttribute("target",M);}},_setChecked:function(N){var O=this.get("type"),M;if(O=="checkbox"||O=="radio"){if(N){this.addStateCSSClasses("checked");M=(O=="radio")?this.RADIO_CHECKED_TITLE:this.CHECKBOX_CHECKED_TITLE;}else{this.removeStateCSSClasses("checked");M=(O=="radio")?this.RADIO_DEFAULT_TITLE:this.CHECKBOX_DEFAULT_TITLE;}this.set("title",M);}},_setMenu:function(W){var Q=this.get("lazyloadmenu"),T=this.get("element"),M=J.prototype.CSS_CLASS_NAME,Y=false,Z,P,S,O,N,V,R;if(!B){return false;}if(!J){return false;}function X(){Z.render(T.parentNode);this.removeListener("appendTo",X);}function U(){if(Z){G.addClass(Z.element,this.get("menuclassname"));G.addClass(Z.element,"yui-"+this.get("type")+"-button-menu");Z.showEvent.subscribe(this._onMenuShow,null,this);Z.hideEvent.subscribe(this._onMenuHide,null,this);Z.renderEvent.subscribe(this._onMenuRender,null,this);if(Z instanceof J){Z.keyDownEvent.subscribe(this._onMenuKeyDown,this,true);Z.subscribe("click",this._onMenuClick,this,true);Z.itemAddedEvent.subscribe(this._onMenuItemAdded,this,true);S=Z.srcElement;if(S&&S.nodeName.toUpperCase()=="SELECT"){S.style.display="none";S.parentNode.removeChild(S);}}else{if(Z instanceof B){if(!K){K=new YAHOO.widget.OverlayManager();}K.register(Z);}}this._menu=Z;if(!Y){if(Q&&!(Z instanceof J)){Z.beforeShowEvent.subscribe(this._onOverlayBeforeShow,null,this);}else{if(!Q){if(G.inDocument(T)){Z.render(T.parentNode);}else{this.on("appendTo",X);}}}}}}if(W&&(W instanceof J)){Z=W;O=Z.getItems();
8
N=O.length;Y=true;if(N>0){R=N-1;do{V=O[R];if(V){V.cfg.subscribeToConfigEvent("selected",this._onMenuItemSelected,V,this);}}while(R--);}U.call(this);}else{if(W&&(W instanceof B)){Z=W;Y=true;Z.cfg.setProperty("visible",false);Z.cfg.setProperty("context",[T,"tl","bl"]);U.call(this);}else{if(I.isArray(W)){this.on("appendTo",function(){Z=new J(G.generateId(),{lazyload:Q,itemdata:W});U.call(this);});}else{if(I.isString(W)){P=G.get(W);if(P){if(G.hasClass(P,M)||P.nodeName.toUpperCase()=="SELECT"){Z=new J(W,{lazyload:Q});U.call(this);}else{Z=new B(W,{visible:false,context:[T,"tl","bl"]});U.call(this);}}}else{if(W&&W.nodeName){if(G.hasClass(W,M)||W.nodeName.toUpperCase()=="SELECT"){Z=new J(W,{lazyload:Q});U.call(this);}else{if(!W.id){G.generateId(W);}Z=new B(W,{visible:false,context:[T,"tl","bl"]});U.call(this);}}}}}}},_setOnClick:function(M){if(this._onclickAttributeValue&&(this._onclickAttributeValue!=M)){this.removeListener("click",this._onclickAttributeValue.fn);this._onclickAttributeValue=null;}if(!this._onclickAttributeValue&&I.isObject(M)&&I.isFunction(M.fn)){this.on("click",M.fn,M.obj,M.scope);this._onclickAttributeValue=M;}},_setSelectedMenuItem:function(N){var M=this._menu,O;if(M&&M instanceof J){O=M.getItem(N);if(O&&!O.cfg.getProperty("selected")){O.cfg.setProperty("selected",true);}}},_isActivationKey:function(M){var Q=this.get("type"),N=(Q=="checkbox"||Q=="radio")?this.CHECK_ACTIVATION_KEYS:this.ACTIVATION_KEYS,P=N.length,O;if(P>0){O=P-1;do{if(M==N[O]){return true;}}while(O--);}},_isSplitButtonOptionKey:function(M){return(M.ctrlKey&&M.shiftKey&&L.getCharCode(M)==77);},_addListenersToForm:function(){var S=this.getForm(),R=YAHOO.widget.Button.onFormKeyPress,Q,M,P,O,N;if(S){L.on(S,"reset",this._onFormReset,null,this);L.on(S,"submit",this.createHiddenFields,null,this);M=this.get("srcelement");if(this.get("type")=="submit"||(M&&M.type=="submit")){P=L.getListeners(S,"keypress");Q=false;if(P){O=P.length;if(O>0){N=O-1;do{if(P[N].fn==R){Q=true;break;}}while(N--);}}if(!Q){L.on(S,"keypress",R);}}}},_originalMaxHeight:-1,_showMenu:function(O){YAHOO.widget.MenuManager.hideVisible();if(K){K.hideAll();}var M=this._menu,N=G.getViewportHeight(),Q,R,P;if(M&&(M instanceof J)){M.cfg.applyConfig({context:[this.get("id"),"tl","bl"],constraintoviewport:false,clicktohide:false,visible:true});M.cfg.fireQueue();M.align("tl","bl");if(O.type=="mousedown"){L.stopPropagation(O);}if(this.get("focusmenu")){this._menu.focus();}Q=M.element.offsetHeight;if((M.cfg.getProperty("y")+Q)>N){M.align("bl","tl");P=M.cfg.getProperty("y");R=G.getDocumentScrollTop();if(R>=P){if(this._originalMaxHeight==-1){this._originalMaxHeight=M.cfg.getProperty("maxheight");}M.cfg.setProperty("maxheight",(Q-((R-P)+20)));M.align("bl","tl");}}}else{if(M&&(M instanceof B)){M.show();M.align("tl","bl");Q=M.element.offsetHeight;if((M.cfg.getProperty("y")+Q)>N){M.align("bl","tl");}}}},_hideMenu:function(){var M=this._menu;if(M){M.hide();}},_onMouseOver:function(M){if(!this._hasMouseEventHandlers){this.on("mouseout",this._onMouseOut);this.on("mousedown",this._onMouseDown);this.on("mouseup",this._onMouseUp);this._hasMouseEventHandlers=true;}this.addStateCSSClasses("hover");if(this._activationButtonPressed){this.addStateCSSClasses("active");}if(this._bOptionPressed){this.addStateCSSClasses("activeoption");}},_onMouseOut:function(M){this.removeStateCSSClasses("hover");if(this.get("type")!="menu"){this.removeStateCSSClasses("active");}if(this._activationButtonPressed||this._bOptionPressed){L.on(document,"mouseup",this._onDocumentMouseUp,null,this);}},_onDocumentMouseUp:function(M){this._activationButtonPressed=false;this._bOptionPressed=false;var N=this.get("type");if(N=="menu"||N=="split"){this.removeStateCSSClasses((N=="menu"?"active":"activeoption"));this._hideMenu();}L.removeListener(document,"mouseup",this._onDocumentMouseUp);},_onMouseDown:function(P){var R,N,Q,O;function M(){this._hideMenu();this.removeListener("mouseup",M);}if((P.which||P.button)==1){if(!this.hasFocus()){this.focus();}R=this.get("type");if(R=="split"){N=this.get("element");Q=L.getPageX(P)-G.getX(N);if((N.offsetWidth-this.OPTION_AREA_WIDTH)<Q){this.fireEvent("option",P);}else{this.addStateCSSClasses("active");this._activationButtonPressed=true;}}else{if(R=="menu"){if(this.isActive()){this._hideMenu();this._activationButtonPressed=false;}else{this._showMenu(P);this._activationButtonPressed=true;}}else{this.addStateCSSClasses("active");this._activationButtonPressed=true;}}if(R=="split"||R=="menu"){O=this;this._hideMenuTimerId=window.setTimeout(function(){O.on("mouseup",M);},250);}}},_onMouseUp:function(M){var N=this.get("type");if(this._hideMenuTimerId){window.clearTimeout(this._hideMenuTimerId);}if(N=="checkbox"||N=="radio"){this.set("checked",!(this.get("checked")));}this._activationButtonPressed=false;if(this.get("type")!="menu"){this.removeStateCSSClasses("active");}},_onFocus:function(N){var M;this.addStateCSSClasses("focus");if(this._activationKeyPressed){this.addStateCSSClasses("active");}C=this;if(!this._hasKeyEventHandlers){M=this._button;L.on(M,"blur",this._onBlur,null,this);L.on(M,"keydown",this._onKeyDown,null,this);L.on(M,"keyup",this._onKeyUp,null,this);this._hasKeyEventHandlers=true;}this.fireEvent("focus",N);},_onBlur:function(M){this.removeStateCSSClasses("focus");if(this.get("type")!="menu"){this.removeStateCSSClasses("active");}if(this._activationKeyPressed){L.on(document,"keyup",this._onDocumentKeyUp,null,this);}C=null;this.fireEvent("blur",M);},_onDocumentKeyUp:function(M){if(this._isActivationKey(L.getCharCode(M))){this._activationKeyPressed=false;L.removeListener(document,"keyup",this._onDocumentKeyUp);}},_onKeyDown:function(N){var M=this._menu;if(this.get("type")=="split"&&this._isSplitButtonOptionKey(N)){this.fireEvent("option",N);}else{if(this._isActivationKey(L.getCharCode(N))){if(this.get("type")=="menu"){this._showMenu(N);}else{this._activationKeyPressed=true;this.addStateCSSClasses("active");}}}if(M&&M.cfg.getProperty("visible")&&L.getCharCode(N)==27){M.hide();
9
this.focus();}},_onKeyUp:function(M){var N;if(this._isActivationKey(L.getCharCode(M))){N=this.get("type");if(N=="checkbox"||N=="radio"){this.set("checked",!(this.get("checked")));}this._activationKeyPressed=false;if(this.get("type")!="menu"){this.removeStateCSSClasses("active");}}},_onClick:function(P){var S=this.get("type"),M,Q,N,O,R;switch(S){case"radio":case"checkbox":if(this.get("checked")){M=(S=="radio")?this.RADIO_CHECKED_TITLE:this.CHECKBOX_CHECKED_TITLE;}else{M=(S=="radio")?this.RADIO_DEFAULT_TITLE:this.CHECKBOX_DEFAULT_TITLE;}this.set("title",M);break;case"submit":this.submitForm();break;case"reset":Q=this.getForm();if(Q){Q.reset();}break;case"menu":M=this._menu.cfg.getProperty("visible")?this.MENUBUTTON_MENU_VISIBLE_TITLE:this.MENUBUTTON_DEFAULT_TITLE;this.set("title",M);break;case"split":O=this.get("element");R=L.getPageX(P)-G.getX(O);if((O.offsetWidth-this.OPTION_AREA_WIDTH)<R){return false;}else{this._hideMenu();N=this.get("srcelement");if(N&&N.type=="submit"){this.submitForm();}}M=this._menu.cfg.getProperty("visible")?this.SPLITBUTTON_OPTION_VISIBLE_TITLE:this.SPLITBUTTON_DEFAULT_TITLE;this.set("title",M);break;}},_onAppendTo:function(N){var M=this;window.setTimeout(function(){M._addListenersToForm();},0);},_onFormReset:function(N){var O=this.get("type"),M=this._menu;if(O=="checkbox"||O=="radio"){this.resetValue("checked");}if(M&&(M instanceof J)){this.resetValue("selectedMenuItem");}},_onDocumentMouseDown:function(P){var M=L.getTarget(P),O=this.get("element"),N=this._menu.element;if(M!=O&&!G.isAncestor(O,M)&&M!=N&&!G.isAncestor(N,M)){this._hideMenu();L.removeListener(document,"mousedown",this._onDocumentMouseDown);}},_onOption:function(M){if(this.hasClass("yui-split-button-activeoption")){this._hideMenu();this._bOptionPressed=false;}else{this._showMenu(M);this._bOptionPressed=true;}},_onOverlayBeforeShow:function(N){var M=this._menu;M.render(this.get("element").parentNode);M.beforeShowEvent.unsubscribe(this._onOverlayBeforeShow);},_onMenuShow:function(N){L.on(document,"mousedown",this._onDocumentMouseDown,null,this);var M,O;if(this.get("type")=="split"){M=this.SPLITBUTTON_OPTION_VISIBLE_TITLE;O="activeoption";}else{M=this.MENUBUTTON_MENU_VISIBLE_TITLE;O="active";}this.addStateCSSClasses(O);this.set("title",M);},_onMenuHide:function(O){var N=this._menu,M,P;if(N&&(N instanceof J)&&this._originalMaxHeight!=-1){this._menu.cfg.setProperty("maxheight",this._originalMaxHeight);}if(this.get("type")=="split"){M=this.SPLITBUTTON_DEFAULT_TITLE;P="activeoption";}else{M=this.MENUBUTTON_DEFAULT_TITLE;P="active";}this.removeStateCSSClasses(P);this.set("title",M);if(this.get("type")=="split"){this._bOptionPressed=false;}},_onMenuKeyDown:function(O,N){var M=N[0];if(L.getCharCode(M)==27){this.focus();if(this.get("type")=="split"){this._bOptionPressed=false;}}},_onMenuRender:function(N){var P=this.get("element"),M=P.parentNode,O=this._menu.element;if(M!=O.parentNode){M.appendChild(O);}this.set("selectedMenuItem",this.get("selectedMenuItem"));},_onMenuItemSelected:function(N,M,P){var O=M[0];if(O){this.set("selectedMenuItem",P);}},_onMenuItemAdded:function(O,N,M){var P=N[0];P.cfg.subscribeToConfigEvent("selected",this._onMenuItemSelected,P.index,this);},_onMenuClick:function(N,M){var P=M[1],O;if(P){O=this.get("srcelement");if(O&&O.type=="submit"){this.submitForm();}this._hideMenu();}},createButtonElement:function(M){var O=this.NODE_NAME,N=document.createElement(O);N.innerHTML="<"+O+" class=\"first-child\">"+(M=="link"?"<a></a>":"<button type=\"button\"></button>")+"</"+O+">";return N;},addStateCSSClasses:function(M){var N=this.get("type");if(I.isString(M)){if(M!="activeoption"){this.addClass(this.CSS_CLASS_NAME+("-"+M));}this.addClass("yui-"+N+("-button-"+M));}},removeStateCSSClasses:function(M){var N=this.get("type");if(I.isString(M)){this.removeClass(this.CSS_CLASS_NAME+("-"+M));this.removeClass("yui-"+N+("-button-"+M));}},createHiddenFields:function(){this.removeHiddenFields();var R=this.getForm(),U,N,P,S,T,O,Q,M;if(R&&!this.get("disabled")){N=this.get("type");P=(N=="checkbox"||N=="radio");if(P||(E==this)){U=F((P?N:"hidden"),this.get("name"),this.get("value"),this.get("checked"));if(U){if(P){U.style.display="none";}R.appendChild(U);}}S=this._menu;if(S&&(S instanceof J)){M=S.srcElement;T=S.getItem(this.get("selectedMenuItem"));if(T){if(M&&M.nodeName.toUpperCase()=="SELECT"){R.appendChild(M);M.selectedIndex=T.index;}else{Q=(T.value===null||T.value==="")?T.cfg.getProperty("text"):T.value;O=this.get("name");if(Q&&O){M=F("hidden",(O+"_options"),Q);R.appendChild(M);}}}}if(U&&M){this._hiddenFields=[U,M];}else{if(!U&&M){this._hiddenFields=M;}else{if(U&&!M){this._hiddenFields=U;}}}return this._hiddenFields;}},removeHiddenFields:function(){var P=this._hiddenFields,N,O;function M(Q){if(G.inDocument(Q)){Q.parentNode.removeChild(Q);}}if(P){if(I.isArray(P)){N=P.length;if(N>0){O=N-1;do{M(P[O]);}while(O--);}}else{M(P);}this._hiddenFields=null;}},submitForm:function(){var P=this.getForm(),O=this.get("srcelement"),N=false,M;if(P){if(this.get("type")=="submit"||(O&&O.type=="submit")){E=this;}if(YAHOO.env.ua.ie){N=P.fireEvent("onsubmit");}else{M=document.createEvent("HTMLEvents");M.initEvent("submit",true,true);N=P.dispatchEvent(M);}if((YAHOO.env.ua.ie||YAHOO.env.ua.webkit)&&N){P.submit();}}return N;},init:function(M,T){var O=T.type=="link"?"a":"button",Q=T.srcelement,S=M.getElementsByTagName(O)[0],R;if(!S){R=M.getElementsByTagName("input")[0];if(R){S=document.createElement("button");S.setAttribute("type","button");R.parentNode.replaceChild(S,R);}}this._button=S;YAHOO.widget.Button.superclass.init.call(this,M,T);D[this.get("id")]=this;this.addClass(this.CSS_CLASS_NAME);this.addClass("yui-"+this.get("type")+"-button");L.on(this._button,"focus",this._onFocus,null,this);this.on("mouseover",this._onMouseOver);this.on("click",this._onClick);this.on("appendTo",this._onAppendTo);var V=this.get("container"),N=this.get("element"),U=G.inDocument(N),P;if(V){if(Q&&Q!=N){P=Q.parentNode;if(P){P.removeChild(Q);}}if(I.isString(V)){L.onContentReady(V,function(){this.appendTo(V);
10
},null,this);}else{this.appendTo(V);}}else{if(!U&&Q&&Q!=N){P=Q.parentNode;if(P){this.fireEvent("beforeAppendTo",{type:"beforeAppendTo",target:P});P.replaceChild(N,Q);this.fireEvent("appendTo",{type:"appendTo",target:P});}}else{if(this.get("type")!="link"&&U&&Q&&Q==N){this._addListenersToForm();}}}},initAttributes:function(N){var M=N||{};YAHOO.widget.Button.superclass.initAttributes.call(this,M);this.setAttributeConfig("type",{value:(M.type||"push"),validator:I.isString,writeOnce:true,method:this._setType});this.setAttributeConfig("label",{value:M.label,validator:I.isString,method:this._setLabel});this.setAttributeConfig("value",{value:M.value});this.setAttributeConfig("name",{value:M.name,validator:I.isString});this.setAttributeConfig("tabindex",{value:M.tabindex,validator:I.isNumber,method:this._setTabIndex});this.configureAttribute("title",{value:M.title,validator:I.isString,method:this._setTitle});this.setAttributeConfig("disabled",{value:(M.disabled||false),validator:I.isBoolean,method:this._setDisabled});this.setAttributeConfig("href",{value:M.href,validator:I.isString,method:this._setHref});this.setAttributeConfig("target",{value:M.target,validator:I.isString,method:this._setTarget});this.setAttributeConfig("checked",{value:(M.checked||false),validator:I.isBoolean,method:this._setChecked});this.setAttributeConfig("container",{value:M.container,writeOnce:true});this.setAttributeConfig("srcelement",{value:M.srcelement,writeOnce:true});this.setAttributeConfig("menu",{value:null,method:this._setMenu,writeOnce:true});this.setAttributeConfig("lazyloadmenu",{value:(M.lazyloadmenu===false?false:true),validator:I.isBoolean,writeOnce:true});this.setAttributeConfig("menuclassname",{value:(M.menuclassname||"yui-button-menu"),validator:I.isString,method:this._setMenuClassName,writeOnce:true});this.setAttributeConfig("selectedMenuItem",{value:0,validator:I.isNumber,method:this._setSelectedMenuItem});this.setAttributeConfig("onclick",{value:M.onclick,method:this._setOnClick});this.setAttributeConfig("focusmenu",{value:(M.focusmenu===false?false:true),validator:I.isBoolean});},focus:function(){if(!this.get("disabled")){this._button.focus();}},blur:function(){if(!this.get("disabled")){this._button.blur();}},hasFocus:function(){return(C==this);},isActive:function(){return this.hasClass(this.CSS_CLASS_NAME+"-active");},getMenu:function(){return this._menu;},getForm:function(){return this._button.form;},getHiddenFields:function(){return this._hiddenFields;},destroy:function(){var O=this.get("element"),N=O.parentNode,M=this._menu,Q;if(M){if(K.find(M)){K.remove(M);}M.destroy();}L.purgeElement(O);L.purgeElement(this._button);L.removeListener(document,"mouseup",this._onDocumentMouseUp);L.removeListener(document,"keyup",this._onDocumentKeyUp);L.removeListener(document,"mousedown",this._onDocumentMouseDown);var P=this.getForm();if(P){L.removeListener(P,"reset",this._onFormReset);L.removeListener(P,"submit",this.createHiddenFields);}this.unsubscribeAll();if(N){N.removeChild(O);}delete D[this.get("id")];Q=G.getElementsByClassName(this.CSS_CLASS_NAME,this.NODE_NAME,P);if(I.isArray(Q)&&Q.length===0){L.removeListener(P,"keypress",YAHOO.widget.Button.onFormKeyPress);}},fireEvent:function(N,M){if(this.DOM_EVENTS[N]&&this.get("disabled")){return ;}YAHOO.widget.Button.superclass.fireEvent.call(this,N,M);},toString:function(){return("Button "+this.get("id"));}});YAHOO.widget.Button.onFormKeyPress=function(Q){var O=L.getTarget(Q),R=L.getCharCode(Q),P=O.nodeName&&O.nodeName.toUpperCase(),M=O.type,S=false,U,V,N,W;function T(Z){var Y,X;switch(Z.nodeName.toUpperCase()){case"INPUT":case"BUTTON":if(Z.type=="submit"&&!Z.disabled){if(!S&&!N){N=Z;}if(V&&!W){W=Z;}}break;default:Y=Z.id;if(Y){U=D[Y];if(U){S=true;if(!U.get("disabled")){X=U.get("srcelement");if(!V&&(U.get("type")=="submit"||(X&&X.type=="submit"))){V=U;}}}}break;}}if(R==13&&((P=="INPUT"&&(M=="text"||M=="password"||M=="checkbox"||M=="radio"||M=="file"))||P=="SELECT")){G.getElementsBy(T,"*",this);if(N){N.focus();}else{if(!N&&V){if(W){L.preventDefault(Q);}V.submitForm();}}}};YAHOO.widget.Button.addHiddenFieldsToForm=function(M){var R=G.getElementsByClassName(YAHOO.widget.Button.prototype.CSS_CLASS_NAME,"*",M),P=R.length,Q,N,O;if(P>0){for(O=0;O<P;O++){N=R[O].id;if(N){Q=D[N];if(Q){Q.createHiddenFields();}}}}};})();(function(){var C=YAHOO.util.Dom,B=YAHOO.util.Event,D=YAHOO.lang,A=YAHOO.widget.Button,E={};YAHOO.widget.ButtonGroup=function(J,H){var I=YAHOO.widget.ButtonGroup.superclass.constructor,K,G,F;if(arguments.length==1&&!D.isString(J)&&!J.nodeName){if(!J.id){F=C.generateId();J.id=F;}I.call(this,(this._createGroupElement()),J);}else{if(D.isString(J)){G=C.get(J);if(G){if(G.nodeName.toUpperCase()==this.NODE_NAME){I.call(this,G,H);}}}else{K=J.nodeName.toUpperCase();if(K&&K==this.NODE_NAME){if(!J.id){J.id=C.generateId();}I.call(this,J,H);}}}};YAHOO.extend(YAHOO.widget.ButtonGroup,YAHOO.util.Element,{_buttons:null,NODE_NAME:"DIV",CSS_CLASS_NAME:"yui-buttongroup",_createGroupElement:function(){var F=document.createElement(this.NODE_NAME);return F;},_setDisabled:function(G){var H=this.getCount(),F;if(H>0){F=H-1;do{this._buttons[F].set("disabled",G);}while(F--);}},_onKeyDown:function(K){var G=B.getTarget(K),I=B.getCharCode(K),H=G.parentNode.parentNode.id,J=E[H],F=-1;if(I==37||I==38){F=(J.index===0)?(this._buttons.length-1):(J.index-1);}else{if(I==39||I==40){F=(J.index===(this._buttons.length-1))?0:(J.index+1);}}if(F>-1){this.check(F);this.getButton(F).focus();}},_onAppendTo:function(H){var I=this._buttons,G=I.length,F;for(F=0;F<G;F++){I[F].appendTo(this.get("element"));}},_onButtonCheckedChange:function(G,F){var I=G.newValue,H=this.get("checkedButton");if(I&&H!=F){if(H){H.set("checked",false,true);}this.set("checkedButton",F);this.set("value",F.get("value"));}else{if(H&&!H.set("checked")){H.set("checked",true,true);}}},init:function(I,H){this._buttons=[];YAHOO.widget.ButtonGroup.superclass.init.call(this,I,H);this.addClass(this.CSS_CLASS_NAME);var J=this.getElementsByClassName("yui-radio-button");
11
if(J.length>0){this.addButtons(J);}function F(K){return(K.type=="radio");}J=C.getElementsBy(F,"input",this.get("element"));if(J.length>0){this.addButtons(J);}this.on("keydown",this._onKeyDown);this.on("appendTo",this._onAppendTo);var G=this.get("container");if(G){if(D.isString(G)){B.onContentReady(G,function(){this.appendTo(G);},null,this);}else{this.appendTo(G);}}},initAttributes:function(G){var F=G||{};YAHOO.widget.ButtonGroup.superclass.initAttributes.call(this,F);this.setAttributeConfig("name",{value:F.name,validator:D.isString});this.setAttributeConfig("disabled",{value:(F.disabled||false),validator:D.isBoolean,method:this._setDisabled});this.setAttributeConfig("value",{value:F.value});this.setAttributeConfig("container",{value:F.container,writeOnce:true});this.setAttributeConfig("checkedButton",{value:null});},addButton:function(J){var L,K,G,F,H,I;if(J instanceof A&&J.get("type")=="radio"){L=J;}else{if(!D.isString(J)&&!J.nodeName){J.type="radio";L=new A(J);}else{L=new A(J,{type:"radio"});}}if(L){F=this._buttons.length;H=L.get("name");I=this.get("name");L.index=F;this._buttons[F]=L;E[L.get("id")]=L;if(H!=I){L.set("name",I);}if(this.get("disabled")){L.set("disabled",true);}if(L.get("checked")){this.set("checkedButton",L);}K=L.get("element");G=this.get("element");if(K.parentNode!=G){G.appendChild(K);}L.on("checkedChange",this._onButtonCheckedChange,L,this);return L;}},addButtons:function(G){var H,I,J,F;if(D.isArray(G)){H=G.length;J=[];if(H>0){for(F=0;F<H;F++){I=this.addButton(G[F]);if(I){J[J.length]=I;}}if(J.length>0){return J;}}}},removeButton:function(H){var I=this.getButton(H),G,F;if(I){this._buttons.splice(H,1);delete E[I.get("id")];I.removeListener("checkedChange",this._onButtonCheckedChange);I.destroy();G=this._buttons.length;if(G>0){F=this._buttons.length-1;do{this._buttons[F].index=F;}while(F--);}}},getButton:function(F){if(D.isNumber(F)){return this._buttons[F];}},getButtons:function(){return this._buttons;},getCount:function(){return this._buttons.length;},focus:function(H){var I,G,F;if(D.isNumber(H)){I=this._buttons[H];if(I){I.focus();}}else{G=this.getCount();for(F=0;F<G;F++){I=this._buttons[F];if(!I.get("disabled")){I.focus();break;}}}},check:function(F){var G=this.getButton(F);if(G){G.set("checked",true);}},destroy:function(){var I=this._buttons.length,H=this.get("element"),F=H.parentNode,G;if(I>0){G=this._buttons.length-1;do{this._buttons[G].destroy();}while(G--);}B.purgeElement(H);F.removeChild(H);},toString:function(){return("ButtonGroup "+this.get("id"));}});})();YAHOO.register("button",YAHOO.widget.Button,{version:"2.3.1",build:"541"});
(-)a/koha-tmpl/intranet-tmpl/lib/yui/button/button-debug.js (-4694 lines)
Lines 1-4694 Link Here
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
* @module button
9
* @description <p>The Button Control enables the creation of rich, graphical 
10
* buttons that function like traditional HTML form buttons.  <em>Unlike</em> 
11
* traditional HTML form buttons, buttons created with the Button Control can have 
12
* a label that is different from its value.  With the inclusion of the optional 
13
* <a href="module_menu.html">Menu Control</a>, the Button Control can also be
14
* used to create menu buttons and split buttons, controls that are not 
15
* available natively in HTML.  The Button Control can also be thought of as a 
16
* way to create more visually engaging implementations of the browser's 
17
* default radio-button and check-box controls.</p>
18
* <p>The Button Control supports the following types:</p>
19
* <dl>
20
* <dt>push</dt>
21
* <dd>Basic push button that can execute a user-specified command when 
22
* pressed.</dd>
23
* <dt>link</dt>
24
* <dd>Navigates to a specified url when pressed.</dd>
25
* <dt>submit</dt>
26
* <dd>Submits the parent form when pressed.</dd>
27
* <dt>reset</dt>
28
* <dd>Resets the parent form when pressed.</dd>
29
* <dt>checkbox</dt>
30
* <dd>Maintains a "checked" state that can be toggled on and off.</dd>
31
* <dt>radio</dt>
32
* <dd>Maintains a "checked" state that can be toggled on and off.  Use with 
33
* the ButtonGroup class to create a set of controls that are mutually 
34
* exclusive; checking one button in the set will uncheck all others in 
35
* the group.</dd>
36
* <dt>menu</dt>
37
* <dd>When pressed will show/hide a menu.</dd>
38
* <dt>split</dt>
39
* <dd>Can execute a user-specified command or display a menu when pressed.</dd>
40
* </dl>
41
* @title Button
42
* @namespace YAHOO.widget
43
* @requires yahoo, dom, element, event
44
* @optional container, menu
45
*/
46
47
48
(function () {
49
50
51
    /**
52
    * The Button class creates a rich, graphical button.
53
    * @param {String} p_oElement String specifying the id attribute of the 
54
    * <code>&#60;input&#62;</code>, <code>&#60;button&#62;</code>,
55
    * <code>&#60;a&#62;</code>, or <code>&#60;span&#62;</code> element to 
56
    * be used to create the button.
57
    * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
58
    * one-html.html#ID-6043025">HTMLInputElement</a>|<a href="http://www.w3.org
59
    * /TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-34812697">
60
    * HTMLButtonElement</a>|<a href="
61
    * http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#
62
    * ID-33759296">HTMLElement</a>} p_oElement Object reference for the 
63
    * <code>&#60;input&#62;</code>, <code>&#60;button&#62;</code>, 
64
    * <code>&#60;a&#62;</code>, or <code>&#60;span&#62;</code> element to be 
65
    * used to create the button.
66
    * @param {Object} p_oElement Object literal specifying a set of   
67
    * configuration attributes used to create the button.
68
    * @param {Object} p_oAttributes Optional. Object literal specifying a set  
69
    * of configuration attributes used to create the button.
70
    * @namespace YAHOO.widget
71
    * @class Button
72
    * @constructor
73
    * @extends YAHOO.util.Element
74
    */
75
76
77
78
    // Shorthard for utilities
79
80
    var Dom = YAHOO.util.Dom,
81
        Event = YAHOO.util.Event,
82
        Lang = YAHOO.lang,
83
        UA = YAHOO.env.ua,
84
        Overlay = YAHOO.widget.Overlay,
85
        Menu = YAHOO.widget.Menu,
86
    
87
    
88
        // Private member variables
89
    
90
        m_oButtons = {},    // Collection of all Button instances
91
        m_oOverlayManager = null,   // YAHOO.widget.OverlayManager instance
92
        m_oSubmitTrigger = null,    // The button that submitted the form 
93
        m_oFocusedButton = null;    // The button that has focus
94
95
96
97
    // Private methods
98
99
    
100
    
101
    /**
102
    * @method createInputElement
103
    * @description Creates an <code>&#60;input&#62;</code> element of the 
104
    * specified type.
105
    * @private
106
    * @param {String} p_sType String specifying the type of 
107
    * <code>&#60;input&#62;</code> element to create.
108
    * @param {String} p_sName String specifying the name of 
109
    * <code>&#60;input&#62;</code> element to create.
110
    * @param {String} p_sValue String specifying the value of 
111
    * <code>&#60;input&#62;</code> element to create.
112
    * @param {String} p_bChecked Boolean specifying if the  
113
    * <code>&#60;input&#62;</code> element is to be checked.
114
    * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
115
    * one-html.html#ID-6043025">HTMLInputElement</a>}
116
    */
117
    function createInputElement(p_sType, p_sName, p_sValue, p_bChecked) {
118
    
119
        var oInput,
120
            sInput;
121
    
122
        if (Lang.isString(p_sType) && Lang.isString(p_sName)) {
123
        
124
            if (UA.ie) {
125
        
126
                /*
127
                    For IE it is necessary to create the element with the 
128
                    "type," "name," "value," and "checked" properties set all 
129
                    at once.
130
                */
131
            
132
                sInput = "<input type=\"" + p_sType + "\" name=\"" + 
133
                    p_sName + "\"";
134
        
135
                if (p_bChecked) {
136
        
137
                    sInput += " checked";
138
                
139
                }
140
                
141
                sInput += ">";
142
        
143
                oInput = document.createElement(sInput);
144
        
145
            }
146
            else {
147
            
148
                oInput = document.createElement("input");
149
                oInput.name = p_sName;
150
                oInput.type = p_sType;
151
        
152
                if (p_bChecked) {
153
        
154
                    oInput.checked = true;
155
                
156
                }
157
        
158
            }
159
        
160
            oInput.value = p_sValue;
161
        
162
        }
163
164
		return oInput;
165
    
166
    }
167
    
168
    
169
    /**
170
    * @method setAttributesFromSrcElement
171
    * @description Gets the values for all the attributes of the source element 
172
    * (either <code>&#60;input&#62;</code> or <code>&#60;a&#62;</code>) that 
173
    * map to Button configuration attributes and sets them into a collection 
174
    * that is passed to the Button constructor.
175
    * @private
176
    * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
177
    * one-html.html#ID-6043025">HTMLInputElement</a>|<a href="http://www.w3.org/
178
    * TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-
179
    * 48250443">HTMLAnchorElement</a>} p_oElement Object reference to the HTML 
180
    * element (either <code>&#60;input&#62;</code> or <code>&#60;span&#62;
181
    * </code>) used to create the button.
182
    * @param {Object} p_oAttributes Object reference for the collection of 
183
    * configuration attributes used to create the button.
184
    */
185
    function setAttributesFromSrcElement(p_oElement, p_oAttributes) {
186
    
187
        var sSrcElementNodeName = p_oElement.nodeName.toUpperCase(),
188
			sClass = (this.CLASS_NAME_PREFIX + this.CSS_CLASS_NAME),
189
            me = this,
190
            oAttribute,
191
            oRootNode,
192
            sText;
193
            
194
    
195
        /**
196
        * @method setAttributeFromDOMAttribute
197
        * @description Gets the value of the specified DOM attribute and sets it 
198
        * into the collection of configuration attributes used to configure 
199
        * the button.
200
        * @private
201
        * @param {String} p_sAttribute String representing the name of the 
202
        * attribute to retrieve from the DOM element.
203
        */
204
        function setAttributeFromDOMAttribute(p_sAttribute) {
205
    
206
            if (!(p_sAttribute in p_oAttributes)) {
207
    
208
                /*
209
                    Need to use "getAttributeNode" instead of "getAttribute" 
210
                    because using "getAttribute," IE will return the innerText 
211
                    of a <code>&#60;button&#62;</code> for the value attribute  
212
                    rather than the value of the "value" attribute.
213
                */
214
        
215
                oAttribute = p_oElement.getAttributeNode(p_sAttribute);
216
        
217
    
218
                if (oAttribute && ("value" in oAttribute)) {
219
    
220
                    YAHOO.log("Setting attribute \"" + p_sAttribute + 
221
                        "\" using source element's attribute value of \"" + 
222
                        oAttribute.value + "\"", "info", me.toString());
223
    
224
                    p_oAttributes[p_sAttribute] = oAttribute.value;
225
    
226
                }
227
    
228
            }
229
        
230
        }
231
    
232
    
233
        /**
234
        * @method setFormElementProperties
235
        * @description Gets the value of the attributes from the form element  
236
        * and sets them into the collection of configuration attributes used to 
237
        * configure the button.
238
        * @private
239
        */
240
        function setFormElementProperties() {
241
    
242
            setAttributeFromDOMAttribute("type");
243
    
244
            if (p_oAttributes.type == "button") {
245
            
246
                p_oAttributes.type = "push";
247
            
248
            }
249
    
250
            if (!("disabled" in p_oAttributes)) {
251
    
252
                p_oAttributes.disabled = p_oElement.disabled;
253
    
254
            }
255
    
256
            setAttributeFromDOMAttribute("name");
257
            setAttributeFromDOMAttribute("value");
258
            setAttributeFromDOMAttribute("title");
259
    
260
        }
261
262
    
263
        switch (sSrcElementNodeName) {
264
        
265
        case "A":
266
            
267
            p_oAttributes.type = "link";
268
            
269
            setAttributeFromDOMAttribute("href");
270
            setAttributeFromDOMAttribute("target");
271
        
272
            break;
273
    
274
        case "INPUT":
275
276
            setFormElementProperties();
277
278
            if (!("checked" in p_oAttributes)) {
279
    
280
                p_oAttributes.checked = p_oElement.checked;
281
    
282
            }
283
284
            break;
285
286
        case "BUTTON":
287
288
            setFormElementProperties();
289
290
            oRootNode = p_oElement.parentNode.parentNode;
291
292
            if (Dom.hasClass(oRootNode, sClass + "-checked")) {
293
            
294
                p_oAttributes.checked = true;
295
            
296
            }
297
298
            if (Dom.hasClass(oRootNode, sClass + "-disabled")) {
299
300
                p_oAttributes.disabled = true;
301
            
302
            }
303
304
            p_oElement.removeAttribute("value");
305
306
            p_oElement.setAttribute("type", "button");
307
308
            break;
309
        
310
        }
311
312
        p_oElement.removeAttribute("id");
313
        p_oElement.removeAttribute("name");
314
        
315
        if (!("tabindex" in p_oAttributes)) {
316
317
            p_oAttributes.tabindex = p_oElement.tabIndex;
318
319
        }
320
    
321
        if (!("label" in p_oAttributes)) {
322
    
323
            // Set the "label" property
324
        
325
            sText = sSrcElementNodeName == "INPUT" ? 
326
                            p_oElement.value : p_oElement.innerHTML;
327
        
328
    
329
            if (sText && sText.length > 0) {
330
                
331
                p_oAttributes.label = sText;
332
                
333
            } 
334
    
335
        }
336
    
337
    }
338
    
339
    
340
    /**
341
    * @method initConfig
342
    * @description Initializes the set of configuration attributes that are 
343
    * used to instantiate the button.
344
    * @private
345
    * @param {Object} Object representing the button's set of 
346
    * configuration attributes.
347
    */
348
    function initConfig(p_oConfig) {
349
    
350
        var oAttributes = p_oConfig.attributes,
351
            oSrcElement = oAttributes.srcelement,
352
            sSrcElementNodeName = oSrcElement.nodeName.toUpperCase(),
353
            me = this;
354
    
355
    
356
        if (sSrcElementNodeName == this.NODE_NAME) {
357
    
358
            p_oConfig.element = oSrcElement;
359
            p_oConfig.id = oSrcElement.id;
360
361
            Dom.getElementsBy(function (p_oElement) {
362
            
363
                switch (p_oElement.nodeName.toUpperCase()) {
364
                
365
                case "BUTTON":
366
                case "A":
367
                case "INPUT":
368
369
                    setAttributesFromSrcElement.call(me, p_oElement, 
370
                        oAttributes);
371
372
                    break;                        
373
                
374
                }
375
            
376
            }, "*", oSrcElement);
377
        
378
        }
379
        else {
380
    
381
            switch (sSrcElementNodeName) {
382
383
            case "BUTTON":
384
            case "A":
385
            case "INPUT":
386
387
                setAttributesFromSrcElement.call(this, oSrcElement, 
388
                    oAttributes);
389
390
                break;
391
392
            }
393
        
394
        }
395
    
396
    }
397
398
399
400
    //  Constructor
401
402
    YAHOO.widget.Button = function (p_oElement, p_oAttributes) {
403
    
404
		if (!Overlay && YAHOO.widget.Overlay) {
405
		
406
			Overlay = YAHOO.widget.Overlay;
407
		
408
		}
409
410
411
		if (!Menu && YAHOO.widget.Menu) {
412
		
413
			Menu = YAHOO.widget.Menu;
414
		
415
		}
416
417
418
        var fnSuperClass = YAHOO.widget.Button.superclass.constructor,
419
            oConfig,
420
            oElement;
421
    
422
423
        if (arguments.length == 1 && !Lang.isString(p_oElement) && !p_oElement.nodeName) {
424
    
425
            if (!p_oElement.id) {
426
    
427
                p_oElement.id = Dom.generateId();
428
    
429
                YAHOO.log("No value specified for the button's \"id\" " + 
430
                    "attribute. Setting button id to \"" + p_oElement.id + 
431
                    "\".", "info", this.toString());
432
    
433
            }
434
    
435
            YAHOO.log("No source HTML element.  Building the button " +
436
                    "using the set of configuration attributes.", "info", this.toString());
437
    
438
            fnSuperClass.call(this, (this.createButtonElement(p_oElement.type)), p_oElement);
439
    
440
        }
441
        else {
442
    
443
            oConfig = { element: null, attributes: (p_oAttributes || {}) };
444
    
445
    
446
            if (Lang.isString(p_oElement)) {
447
    
448
                oElement = Dom.get(p_oElement);
449
    
450
                if (oElement) {
451
452
                    if (!oConfig.attributes.id) {
453
                    
454
                        oConfig.attributes.id = p_oElement;
455
                    
456
                    }
457
    
458
                    YAHOO.log("Building the button using an existing " + 
459
                            "HTML element as a source element.", "info", this.toString());
460
                
461
                
462
                    oConfig.attributes.srcelement = oElement;
463
                
464
                    initConfig.call(this, oConfig);
465
                
466
                
467
                    if (!oConfig.element) {
468
                
469
                        YAHOO.log("Source element could not be used " +
470
                                "as is.  Creating a new HTML element for " + 
471
                                "the button.", "info", this.toString());
472
                
473
                        oConfig.element = this.createButtonElement(oConfig.attributes.type);
474
                
475
                    }
476
                
477
                    fnSuperClass.call(this, oConfig.element, oConfig.attributes);
478
    
479
                }
480
    
481
            }
482
            else if (p_oElement.nodeName) {
483
    
484
                if (!oConfig.attributes.id) {
485
    
486
                    if (p_oElement.id) {
487
        
488
                        oConfig.attributes.id = p_oElement.id;
489
                    
490
                    }
491
                    else {
492
        
493
                        oConfig.attributes.id = Dom.generateId();
494
        
495
                        YAHOO.log("No value specified for the button's " +
496
                            "\"id\" attribute. Setting button id to \"" + 
497
                            oConfig.attributes.id + "\".", "info", this.toString());
498
        
499
                    }
500
    
501
                }
502
    
503
                YAHOO.log("Building the button using an existing HTML " + 
504
                    "element as a source element.", "info", this.toString());
505
    
506
    
507
                oConfig.attributes.srcelement = p_oElement;
508
        
509
                initConfig.call(this, oConfig);
510
        
511
        
512
                if (!oConfig.element) {
513
    
514
                    YAHOO.log("Source element could not be used as is." +
515
                            "  Creating a new HTML element for the button.", 
516
                            "info", this.toString());
517
            
518
                    oConfig.element = this.createButtonElement(oConfig.attributes.type);
519
            
520
                }
521
            
522
                fnSuperClass.call(this, oConfig.element, oConfig.attributes);
523
            
524
            }
525
    
526
        }
527
    
528
    };
529
530
531
532
    YAHOO.extend(YAHOO.widget.Button, YAHOO.util.Element, {
533
    
534
    
535
        // Protected properties
536
        
537
        
538
        /** 
539
        * @property _button
540
        * @description Object reference to the button's internal 
541
        * <code>&#60;a&#62;</code> or <code>&#60;button&#62;</code> element.
542
        * @default null
543
        * @protected
544
        * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
545
        * level-one-html.html#ID-48250443">HTMLAnchorElement</a>|<a href="
546
        * http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html
547
        * #ID-34812697">HTMLButtonElement</a>
548
        */
549
        _button: null,
550
        
551
        
552
        /** 
553
        * @property _menu
554
        * @description Object reference to the button's menu.
555
        * @default null
556
        * @protected
557
        * @type {<a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>|
558
        * <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a>}
559
        */
560
        _menu: null,
561
        
562
        
563
        /** 
564
        * @property _hiddenFields
565
        * @description Object reference to the <code>&#60;input&#62;</code>  
566
        * element, or array of HTML form elements used to represent the button
567
        *  when its parent form is submitted.
568
        * @default null
569
        * @protected
570
        * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
571
        * level-one-html.html#ID-6043025">HTMLInputElement</a>|Array
572
        */
573
        _hiddenFields: null,
574
        
575
        
576
        /** 
577
        * @property _onclickAttributeValue
578
        * @description Object reference to the button's current value for the 
579
        * "onclick" configuration attribute.
580
        * @default null
581
        * @protected
582
        * @type Object
583
        */
584
        _onclickAttributeValue: null,
585
        
586
        
587
        /** 
588
        * @property _activationKeyPressed
589
        * @description Boolean indicating if the key(s) that toggle the button's 
590
        * "active" state have been pressed.
591
        * @default false
592
        * @protected
593
        * @type Boolean
594
        */
595
        _activationKeyPressed: false,
596
        
597
        
598
        /** 
599
        * @property _activationButtonPressed
600
        * @description Boolean indicating if the mouse button that toggles 
601
        * the button's "active" state has been pressed.
602
        * @default false
603
        * @protected
604
        * @type Boolean
605
        */
606
        _activationButtonPressed: false,
607
        
608
        
609
        /** 
610
        * @property _hasKeyEventHandlers
611
        * @description Boolean indicating if the button's "blur", "keydown" and 
612
        * "keyup" event handlers are assigned
613
        * @default false
614
        * @protected
615
        * @type Boolean
616
        */
617
        _hasKeyEventHandlers: false,
618
        
619
        
620
        /** 
621
        * @property _hasMouseEventHandlers
622
        * @description Boolean indicating if the button's "mouseout," 
623
        * "mousedown," and "mouseup" event handlers are assigned
624
        * @default false
625
        * @protected
626
        * @type Boolean
627
        */
628
        _hasMouseEventHandlers: false,
629
630
631
        /** 
632
        * @property _nOptionRegionX
633
        * @description Number representing the X coordinate of the leftmost edge of the Button's 
634
        * option region.  Applies only to Buttons of type "split".
635
        * @default 0
636
        * @protected
637
        * @type Number
638
        */        
639
        _nOptionRegionX: 0,
640
        
641
642
643
        // Constants
644
645
        /**
646
        * @property CLASS_NAME_PREFIX
647
        * @description Prefix used for all class names applied to a Button.
648
        * @default "yui-"
649
        * @final
650
        * @type String
651
        */
652
        CLASS_NAME_PREFIX: "yui-",
653
        
654
        
655
        /**
656
        * @property NODE_NAME
657
        * @description The name of the node to be used for the button's 
658
        * root element.
659
        * @default "SPAN"
660
        * @final
661
        * @type String
662
        */
663
        NODE_NAME: "SPAN",
664
        
665
        
666
        /**
667
        * @property CHECK_ACTIVATION_KEYS
668
        * @description Array of numbers representing keys that (when pressed) 
669
        * toggle the button's "checked" attribute.
670
        * @default [32]
671
        * @final
672
        * @type Array
673
        */
674
        CHECK_ACTIVATION_KEYS: [32],
675
        
676
        
677
        /**
678
        * @property ACTIVATION_KEYS
679
        * @description Array of numbers representing keys that (when presed) 
680
        * toggle the button's "active" state.
681
        * @default [13, 32]
682
        * @final
683
        * @type Array
684
        */
685
        ACTIVATION_KEYS: [13, 32],
686
        
687
        
688
        /**
689
        * @property OPTION_AREA_WIDTH
690
        * @description Width (in pixels) of the area of a split button that  
691
        * when pressed will display a menu.
692
        * @default 20
693
        * @final
694
        * @type Number
695
        */
696
        OPTION_AREA_WIDTH: 20,
697
        
698
        
699
        /**
700
        * @property CSS_CLASS_NAME
701
        * @description String representing the CSS class(es) to be applied to  
702
        * the button's root element.
703
        * @default "button"
704
        * @final
705
        * @type String
706
        */
707
        CSS_CLASS_NAME: "button",
708
        
709
        
710
        
711
        // Protected attribute setter methods
712
        
713
        
714
        /**
715
        * @method _setType
716
        * @description Sets the value of the button's "type" attribute.
717
        * @protected
718
        * @param {String} p_sType String indicating the value for the button's 
719
        * "type" attribute.
720
        */
721
        _setType: function (p_sType) {
722
        
723
            if (p_sType == "split") {
724
        
725
                this.on("option", this._onOption);
726
        
727
            }
728
        
729
        },
730
        
731
        
732
        /**
733
        * @method _setLabel
734
        * @description Sets the value of the button's "label" attribute.
735
        * @protected
736
        * @param {String} p_sLabel String indicating the value for the button's 
737
        * "label" attribute.
738
        */
739
        _setLabel: function (p_sLabel) {
740
741
            this._button.innerHTML = p_sLabel;
742
743
            
744
            /*
745
                Remove and add the default class name from the root element
746
                for Gecko to ensure that the button shrinkwraps to the label.
747
                Without this the button will not be rendered at the correct 
748
                width when the label changes.  The most likely cause for this 
749
                bug is button's use of the Gecko-specific CSS display type of 
750
                "-moz-inline-box" to simulate "inline-block" supported by IE, 
751
                Safari and Opera.
752
            */
753
            
754
            var sClass,
755
                nGeckoVersion = UA.gecko;
756
				
757
            
758
            if (nGeckoVersion && nGeckoVersion < 1.9 && Dom.inDocument(this.get("element"))) {
759
            
760
                sClass = (this.CLASS_NAME_PREFIX + this.CSS_CLASS_NAME);
761
762
                this.removeClass(sClass);
763
                
764
                Lang.later(0, this, this.addClass, sClass);
765
766
            }
767
        
768
        },
769
        
770
        
771
        /**
772
        * @method _setTabIndex
773
        * @description Sets the value of the button's "tabindex" attribute.
774
        * @protected
775
        * @param {Number} p_nTabIndex Number indicating the value for the 
776
        * button's "tabindex" attribute.
777
        */
778
        _setTabIndex: function (p_nTabIndex) {
779
        
780
            this._button.tabIndex = p_nTabIndex;
781
        
782
        },
783
        
784
        
785
        /**
786
        * @method _setTitle
787
        * @description Sets the value of the button's "title" attribute.
788
        * @protected
789
        * @param {String} p_nTabIndex Number indicating the value for 
790
        * the button's "title" attribute.
791
        */
792
        _setTitle: function (p_sTitle) {
793
        
794
            if (this.get("type") != "link") {
795
        
796
                this._button.title = p_sTitle;
797
        
798
            }
799
        
800
        },
801
        
802
        
803
        /**
804
        * @method _setDisabled
805
        * @description Sets the value of the button's "disabled" attribute.
806
        * @protected
807
        * @param {Boolean} p_bDisabled Boolean indicating the value for 
808
        * the button's "disabled" attribute.
809
        */
810
        _setDisabled: function (p_bDisabled) {
811
        
812
            if (this.get("type") != "link") {
813
        
814
                if (p_bDisabled) {
815
        
816
                    if (this._menu) {
817
        
818
                        this._menu.hide();
819
        
820
                    }
821
        
822
                    if (this.hasFocus()) {
823
                    
824
                        this.blur();
825
                    
826
                    }
827
        
828
                    this._button.setAttribute("disabled", "disabled");
829
        
830
                    this.addStateCSSClasses("disabled");
831
832
                    this.removeStateCSSClasses("hover");
833
                    this.removeStateCSSClasses("active");
834
                    this.removeStateCSSClasses("focus");
835
        
836
                }
837
                else {
838
        
839
                    this._button.removeAttribute("disabled");
840
        
841
                    this.removeStateCSSClasses("disabled");
842
                
843
                }
844
        
845
            }
846
        
847
        },
848
849
        
850
        /**
851
        * @method _setHref
852
        * @description Sets the value of the button's "href" attribute.
853
        * @protected
854
        * @param {String} p_sHref String indicating the value for the button's 
855
        * "href" attribute.
856
        */
857
        _setHref: function (p_sHref) {
858
        
859
            if (this.get("type") == "link") {
860
        
861
                this._button.href = p_sHref;
862
            
863
            }
864
        
865
        },
866
        
867
        
868
        /**
869
        * @method _setTarget
870
        * @description Sets the value of the button's "target" attribute.
871
        * @protected
872
        * @param {String} p_sTarget String indicating the value for the button's 
873
        * "target" attribute.
874
        */
875
        _setTarget: function (p_sTarget) {
876
        
877
            if (this.get("type") == "link") {
878
        
879
                this._button.setAttribute("target", p_sTarget);
880
            
881
            }
882
        
883
        },
884
        
885
        
886
        /**
887
        * @method _setChecked
888
        * @description Sets the value of the button's "target" attribute.
889
        * @protected
890
        * @param {Boolean} p_bChecked Boolean indicating the value for  
891
        * the button's "checked" attribute.
892
        */
893
        _setChecked: function (p_bChecked) {
894
        
895
            var sType = this.get("type");
896
        
897
            if (sType == "checkbox" || sType == "radio") {
898
        
899
                if (p_bChecked) {
900
                    this.addStateCSSClasses("checked");
901
                }
902
                else {
903
                    this.removeStateCSSClasses("checked");
904
                }
905
        
906
            }
907
        
908
        },
909
910
        
911
        /**
912
        * @method _setMenu
913
        * @description Sets the value of the button's "menu" attribute.
914
        * @protected
915
        * @param {Object} p_oMenu Object indicating the value for the button's 
916
        * "menu" attribute.
917
        */
918
        _setMenu: function (p_oMenu) {
919
920
            var bLazyLoad = this.get("lazyloadmenu"),
921
                oButtonElement = this.get("element"),
922
                sMenuCSSClassName,
923
        
924
                /*
925
                    Boolean indicating if the value of p_oMenu is an instance 
926
                    of YAHOO.widget.Menu or YAHOO.widget.Overlay.
927
                */
928
        
929
                bInstance = false,
930
                oMenu,
931
                oMenuElement,
932
                oSrcElement;
933
        
934
935
			function onAppendTo() {
936
937
				oMenu.render(oButtonElement.parentNode);
938
				
939
				this.removeListener("appendTo", onAppendTo);
940
			
941
			}
942
			
943
			
944
			function setMenuContainer() {
945
946
				oMenu.cfg.queueProperty("container", oButtonElement.parentNode);
947
				
948
				this.removeListener("appendTo", setMenuContainer);
949
			
950
			}
951
952
953
			function initMenu() {
954
		
955
				var oContainer;
956
		
957
				if (oMenu) {
958
959
					Dom.addClass(oMenu.element, this.get("menuclassname"));
960
					Dom.addClass(oMenu.element, this.CLASS_NAME_PREFIX + this.get("type") + "-button-menu");
961
962
					oMenu.showEvent.subscribe(this._onMenuShow, null, this);
963
					oMenu.hideEvent.subscribe(this._onMenuHide, null, this);
964
					oMenu.renderEvent.subscribe(this._onMenuRender, null, this);
965
966
967
					if (Menu && oMenu instanceof Menu) {
968
969
						if (bLazyLoad) {
970
971
							oContainer = this.get("container");
972
973
							if (oContainer) {
974
975
								oMenu.cfg.queueProperty("container", oContainer);
976
977
							}
978
							else {
979
980
								this.on("appendTo", setMenuContainer);
981
982
							}
983
984
						}
985
986
						oMenu.cfg.queueProperty("clicktohide", false);
987
988
						oMenu.keyDownEvent.subscribe(this._onMenuKeyDown, this, true);
989
						oMenu.subscribe("click", this._onMenuClick, this, true);
990
991
						this.on("selectedMenuItemChange", this._onSelectedMenuItemChange);
992
		
993
						oSrcElement = oMenu.srcElement;
994
		
995
						if (oSrcElement && oSrcElement.nodeName.toUpperCase() == "SELECT") {
996
997
							oSrcElement.style.display = "none";
998
							oSrcElement.parentNode.removeChild(oSrcElement);
999
		
1000
						}
1001
		
1002
					}
1003
					else if (Overlay && oMenu instanceof Overlay) {
1004
		
1005
						if (!m_oOverlayManager) {
1006
		
1007
							m_oOverlayManager = new YAHOO.widget.OverlayManager();
1008
						
1009
						}
1010
						
1011
						m_oOverlayManager.register(oMenu);
1012
						
1013
					}
1014
		
1015
		
1016
					this._menu = oMenu;
1017
1018
		
1019
					if (!bInstance && !bLazyLoad) {
1020
		
1021
						if (Dom.inDocument(oButtonElement)) {
1022
	
1023
							oMenu.render(oButtonElement.parentNode);
1024
						
1025
						}
1026
						else {
1027
		
1028
							this.on("appendTo", onAppendTo);
1029
						
1030
						}
1031
					
1032
					}
1033
		
1034
				}
1035
		
1036
			}
1037
1038
        
1039
            if (Overlay) {
1040
        
1041
				if (Menu) {
1042
				
1043
					sMenuCSSClassName = Menu.prototype.CSS_CLASS_NAME;
1044
				
1045
				}
1046
			
1047
				if (p_oMenu && Menu && (p_oMenu instanceof Menu)) {
1048
			
1049
					oMenu = p_oMenu;
1050
					bInstance = true;
1051
			
1052
					initMenu.call(this);
1053
			
1054
				}
1055
				else if (Overlay && p_oMenu && (p_oMenu instanceof Overlay)) {
1056
			
1057
					oMenu = p_oMenu;
1058
					bInstance = true;
1059
			
1060
					oMenu.cfg.queueProperty("visible", false);
1061
			
1062
					initMenu.call(this);
1063
			
1064
				}
1065
				else if (Menu && Lang.isArray(p_oMenu)) {
1066
1067
					oMenu = new Menu(Dom.generateId(), { lazyload: bLazyLoad, itemdata: p_oMenu });
1068
						
1069
					this._menu = oMenu;
1070
			
1071
					this.on("appendTo", initMenu);
1072
			
1073
				}
1074
				else if (Lang.isString(p_oMenu)) {
1075
			
1076
					oMenuElement = Dom.get(p_oMenu);
1077
			
1078
					if (oMenuElement) {
1079
			
1080
						if (Menu && Dom.hasClass(oMenuElement, sMenuCSSClassName) || 
1081
							oMenuElement.nodeName.toUpperCase() == "SELECT") {
1082
				
1083
							oMenu = new Menu(p_oMenu, { lazyload: bLazyLoad });
1084
				
1085
							initMenu.call(this);
1086
				
1087
						}
1088
						else if (Overlay) {
1089
			
1090
							oMenu = new Overlay(p_oMenu, { visible: false });
1091
				
1092
							initMenu.call(this);
1093
				
1094
						}
1095
			
1096
					}
1097
			
1098
				}
1099
				else if (p_oMenu && p_oMenu.nodeName) {
1100
			
1101
					if (Menu && Dom.hasClass(p_oMenu, sMenuCSSClassName) || 
1102
							p_oMenu.nodeName.toUpperCase() == "SELECT") {
1103
			
1104
						oMenu = new Menu(p_oMenu, { lazyload: bLazyLoad });
1105
					
1106
						initMenu.call(this);
1107
			
1108
					}
1109
					else if (Overlay) {
1110
			
1111
						if (!p_oMenu.id) {
1112
						
1113
							Dom.generateId(p_oMenu);
1114
						
1115
						}
1116
			
1117
						oMenu = new Overlay(p_oMenu, { visible: false });
1118
			
1119
						initMenu.call(this);
1120
					
1121
					}
1122
				
1123
				}
1124
            
1125
            }
1126
        
1127
        },
1128
        
1129
        
1130
        /**
1131
        * @method _setOnClick
1132
        * @description Sets the value of the button's "onclick" attribute.
1133
        * @protected
1134
        * @param {Object} p_oObject Object indicating the value for the button's 
1135
        * "onclick" attribute.
1136
        */
1137
        _setOnClick: function (p_oObject) {
1138
        
1139
            /*
1140
                Remove any existing listeners if a "click" event handler 
1141
                has already been specified.
1142
            */
1143
        
1144
            if (this._onclickAttributeValue && 
1145
                (this._onclickAttributeValue != p_oObject)) {
1146
        
1147
                this.removeListener("click", this._onclickAttributeValue.fn);
1148
        
1149
                this._onclickAttributeValue = null;
1150
        
1151
            }
1152
        
1153
        
1154
            if (!this._onclickAttributeValue && 
1155
                Lang.isObject(p_oObject) && 
1156
                Lang.isFunction(p_oObject.fn)) {
1157
        
1158
                this.on("click", p_oObject.fn, p_oObject.obj, p_oObject.scope);
1159
        
1160
                this._onclickAttributeValue = p_oObject;
1161
        
1162
            }
1163
        
1164
        },
1165
1166
        
1167
        
1168
        // Protected methods
1169
1170
        
1171
        
1172
        /**
1173
        * @method _isActivationKey
1174
        * @description Determines if the specified keycode is one that toggles  
1175
        * the button's "active" state.
1176
        * @protected
1177
        * @param {Number} p_nKeyCode Number representing the keycode to 
1178
        * be evaluated.
1179
        * @return {Boolean}
1180
        */
1181
        _isActivationKey: function (p_nKeyCode) {
1182
        
1183
            var sType = this.get("type"),
1184
                aKeyCodes = (sType == "checkbox" || sType == "radio") ? 
1185
                    this.CHECK_ACTIVATION_KEYS : this.ACTIVATION_KEYS,
1186
        
1187
                nKeyCodes = aKeyCodes.length,
1188
                bReturnVal = false,
1189
                i;
1190
        
1191
1192
            if (nKeyCodes > 0) {
1193
        
1194
                i = nKeyCodes - 1;
1195
        
1196
                do {
1197
        
1198
                    if (p_nKeyCode == aKeyCodes[i]) {
1199
        
1200
                        bReturnVal = true;
1201
                        break;
1202
        
1203
                    }
1204
        
1205
                }
1206
                while (i--);
1207
            
1208
            }
1209
            
1210
            return bReturnVal;
1211
        
1212
        },
1213
        
1214
        
1215
        /**
1216
        * @method _isSplitButtonOptionKey
1217
        * @description Determines if the specified keycode is one that toggles  
1218
        * the display of the split button's menu.
1219
        * @protected
1220
        * @param {Event} p_oEvent Object representing the DOM event object  
1221
        * passed back by the event utility (YAHOO.util.Event).
1222
        * @return {Boolean}
1223
        */
1224
        _isSplitButtonOptionKey: function (p_oEvent) {
1225
1226
			var bShowMenu = (Event.getCharCode(p_oEvent) == 40);
1227
1228
1229
			var onKeyPress = function (p_oEvent) {
1230
1231
				Event.preventDefault(p_oEvent);
1232
1233
				this.removeListener("keypress", onKeyPress);
1234
			
1235
			};
1236
1237
1238
			// Prevent the browser from scrolling the window
1239
			if (bShowMenu) {
1240
1241
				if (UA.opera) {
1242
	
1243
					this.on("keypress", onKeyPress);
1244
	
1245
				}
1246
1247
				Event.preventDefault(p_oEvent);
1248
			}
1249
1250
            return bShowMenu;
1251
        
1252
        },
1253
        
1254
        
1255
        /**
1256
        * @method _addListenersToForm
1257
        * @description Adds event handlers to the button's form.
1258
        * @protected
1259
        */
1260
        _addListenersToForm: function () {
1261
        
1262
            var oForm = this.getForm(),
1263
                onFormKeyPress = YAHOO.widget.Button.onFormKeyPress,
1264
                bHasKeyPressListener,
1265
                oSrcElement,
1266
                aListeners,
1267
                nListeners,
1268
                i;
1269
        
1270
        
1271
            if (oForm) {
1272
        
1273
                Event.on(oForm, "reset", this._onFormReset, null, this);
1274
                Event.on(oForm, "submit", this._onFormSubmit, null, this);
1275
        
1276
                oSrcElement = this.get("srcelement");
1277
        
1278
        
1279
                if (this.get("type") == "submit" || 
1280
                    (oSrcElement && oSrcElement.type == "submit")) 
1281
                {
1282
                
1283
                    aListeners = Event.getListeners(oForm, "keypress");
1284
                    bHasKeyPressListener = false;
1285
            
1286
                    if (aListeners) {
1287
            
1288
                        nListeners = aListeners.length;
1289
        
1290
                        if (nListeners > 0) {
1291
            
1292
                            i = nListeners - 1;
1293
                            
1294
                            do {
1295
               
1296
                                if (aListeners[i].fn == onFormKeyPress) {
1297
                
1298
                                    bHasKeyPressListener = true;
1299
                                    break;
1300
                                
1301
                                }
1302
                
1303
                            }
1304
                            while (i--);
1305
                        
1306
                        }
1307
                    
1308
                    }
1309
            
1310
            
1311
                    if (!bHasKeyPressListener) {
1312
               
1313
                        Event.on(oForm, "keypress", onFormKeyPress);
1314
            
1315
                    }
1316
        
1317
                }
1318
            
1319
            }
1320
        
1321
        },
1322
        
1323
        
1324
        
1325
        /**
1326
        * @method _showMenu
1327
        * @description Shows the button's menu.
1328
        * @protected
1329
        * @param {Event} p_oEvent Object representing the DOM event object 
1330
        * passed back by the event utility (YAHOO.util.Event) that triggered 
1331
        * the display of the menu.
1332
        */
1333
        _showMenu: function (p_oEvent) {
1334
1335
            if (YAHOO.widget.MenuManager) {
1336
                YAHOO.widget.MenuManager.hideVisible();
1337
            }
1338
1339
        
1340
            if (m_oOverlayManager) {
1341
                m_oOverlayManager.hideAll();
1342
            }
1343
1344
1345
            var oMenu = this._menu,
1346
            	aMenuAlignment = this.get("menualignment"),
1347
            	bFocusMenu = this.get("focusmenu"),
1348
				fnFocusMethod;
1349
1350
1351
			if (this._renderedMenu) {
1352
1353
				oMenu.cfg.setProperty("context", 
1354
								[this.get("element"), aMenuAlignment[0], aMenuAlignment[1]]);
1355
	
1356
				oMenu.cfg.setProperty("preventcontextoverlap", true);
1357
				oMenu.cfg.setProperty("constraintoviewport", true);
1358
1359
			}
1360
			else {
1361
1362
				oMenu.cfg.queueProperty("context", 
1363
								[this.get("element"), aMenuAlignment[0], aMenuAlignment[1]]);
1364
	
1365
				oMenu.cfg.queueProperty("preventcontextoverlap", true);
1366
				oMenu.cfg.queueProperty("constraintoviewport", true);
1367
			
1368
			}
1369
1370
1371
			/*
1372
				 Refocus the Button before showing its Menu in case the call to 
1373
				 YAHOO.widget.MenuManager.hideVisible() resulted in another element in the 
1374
				 DOM being focused after another Menu was hidden.
1375
			*/
1376
			
1377
			this.focus();
1378
1379
1380
            if (Menu && oMenu && (oMenu instanceof Menu)) {
1381
1382
				// Since Menus automatically focus themselves when made visible, temporarily 
1383
				// replace the Menu focus method so that the value of the Button's "focusmenu"
1384
				// attribute determines if the Menu should be focus when made visible.
1385
1386
				fnFocusMethod = oMenu.focus;
1387
1388
				oMenu.focus = function () {};
1389
1390
				if (this._renderedMenu) {
1391
1392
					oMenu.cfg.setProperty("minscrollheight", this.get("menuminscrollheight"));
1393
					oMenu.cfg.setProperty("maxheight", this.get("menumaxheight"));
1394
				
1395
				}
1396
				else {
1397
1398
					oMenu.cfg.queueProperty("minscrollheight", this.get("menuminscrollheight"));
1399
					oMenu.cfg.queueProperty("maxheight", this.get("menumaxheight"));
1400
				
1401
				}
1402
1403
1404
                oMenu.show();
1405
1406
        		oMenu.focus = fnFocusMethod;
1407
1408
				oMenu.align();
1409
        
1410
1411
                /*
1412
                    Stop the propagation of the event so that the MenuManager 
1413
                    doesn't blur the menu after it gets focus.
1414
                */
1415
        
1416
                if (p_oEvent.type == "mousedown") {
1417
                    Event.stopPropagation(p_oEvent);
1418
                }
1419
1420
        
1421
                if (bFocusMenu) { 
1422
                    oMenu.focus();
1423
                }
1424
1425
            }
1426
            else if (Overlay && oMenu && (oMenu instanceof Overlay)) {
1427
1428
				if (!this._renderedMenu) {
1429
		            oMenu.render(this.get("element").parentNode);
1430
				}
1431
1432
                oMenu.show();
1433
				oMenu.align();
1434
1435
            }
1436
        
1437
        },
1438
        
1439
        
1440
        /**
1441
        * @method _hideMenu
1442
        * @description Hides the button's menu.
1443
        * @protected
1444
        */
1445
        _hideMenu: function () {
1446
        
1447
            var oMenu = this._menu;
1448
        
1449
            if (oMenu) {
1450
        
1451
                oMenu.hide();
1452
        
1453
            }
1454
        
1455
        },
1456
        
1457
        
1458
        
1459
        
1460
        // Protected event handlers
1461
        
1462
        
1463
        /**
1464
        * @method _onMouseOver
1465
        * @description "mouseover" event handler for the button.
1466
        * @protected
1467
        * @param {Event} p_oEvent Object representing the DOM event object  
1468
        * passed back by the event utility (YAHOO.util.Event).
1469
        */
1470
        _onMouseOver: function (p_oEvent) {
1471
        
1472
        	var sType = this.get("type"),
1473
        		oElement,
1474
				nOptionRegionX;
1475
1476
1477
			if (sType === "split") {
1478
1479
				oElement = this.get("element");
1480
				nOptionRegionX = 
1481
					(Dom.getX(oElement) + (oElement.offsetWidth - this.OPTION_AREA_WIDTH));
1482
					
1483
				this._nOptionRegionX = nOptionRegionX;
1484
			
1485
			}
1486
        
1487
1488
            if (!this._hasMouseEventHandlers) {
1489
        
1490
				if (sType === "split") {
1491
        
1492
	        		this.on("mousemove", this._onMouseMove);
1493
1494
        		}
1495
1496
                this.on("mouseout", this._onMouseOut);
1497
        
1498
                this._hasMouseEventHandlers = true;
1499
        
1500
            }
1501
        
1502
1503
            this.addStateCSSClasses("hover");
1504
1505
1506
			if (sType === "split" && (Event.getPageX(p_oEvent) > nOptionRegionX)) {
1507
	
1508
				this.addStateCSSClasses("hoveroption");
1509
	
1510
			}
1511
1512
        
1513
            if (this._activationButtonPressed) {
1514
        
1515
                this.addStateCSSClasses("active");
1516
        
1517
            }
1518
        
1519
        
1520
            if (this._bOptionPressed) {
1521
        
1522
                this.addStateCSSClasses("activeoption");
1523
            
1524
            }
1525
1526
1527
            if (this._activationButtonPressed || this._bOptionPressed) {
1528
        
1529
                Event.removeListener(document, "mouseup", this._onDocumentMouseUp);
1530
        
1531
            }
1532
1533
        },
1534
1535
1536
        /**
1537
        * @method _onMouseMove
1538
        * @description "mousemove" event handler for the button.
1539
        * @protected
1540
        * @param {Event} p_oEvent Object representing the DOM event object  
1541
        * passed back by the event utility (YAHOO.util.Event).
1542
        */        
1543
        _onMouseMove: function (p_oEvent) {
1544
        
1545
        	var nOptionRegionX = this._nOptionRegionX;
1546
        
1547
        	if (nOptionRegionX) {
1548
1549
				if (Event.getPageX(p_oEvent) > nOptionRegionX) {
1550
					
1551
					this.addStateCSSClasses("hoveroption");
1552
	
1553
				}
1554
				else {
1555
1556
					this.removeStateCSSClasses("hoveroption");
1557
				
1558
				}
1559
				
1560
        	}
1561
        
1562
        },
1563
        
1564
        /**
1565
        * @method _onMouseOut
1566
        * @description "mouseout" event handler for the button.
1567
        * @protected
1568
        * @param {Event} p_oEvent Object representing the DOM event object  
1569
        * passed back by the event utility (YAHOO.util.Event).
1570
        */
1571
        _onMouseOut: function (p_oEvent) {
1572
1573
			var sType = this.get("type");
1574
        
1575
            this.removeStateCSSClasses("hover");
1576
        
1577
1578
            if (sType != "menu") {
1579
        
1580
                this.removeStateCSSClasses("active");
1581
        
1582
            }
1583
        
1584
1585
            if (this._activationButtonPressed || this._bOptionPressed) {
1586
        
1587
                Event.on(document, "mouseup", this._onDocumentMouseUp, null, this);
1588
        
1589
            }
1590
1591
1592
			if (sType === "split" && (Event.getPageX(p_oEvent) > this._nOptionRegionX)) {
1593
			
1594
				this.removeStateCSSClasses("hoveroption");
1595
	
1596
			}
1597
            
1598
        },
1599
        
1600
        
1601
        /**
1602
        * @method _onDocumentMouseUp
1603
        * @description "mouseup" event handler for the button.
1604
        * @protected
1605
        * @param {Event} p_oEvent Object representing the DOM event object  
1606
        * passed back by the event utility (YAHOO.util.Event).
1607
        */
1608
        _onDocumentMouseUp: function (p_oEvent) {
1609
        
1610
            this._activationButtonPressed = false;
1611
            this._bOptionPressed = false;
1612
        
1613
            var sType = this.get("type"),
1614
                oTarget,
1615
                oMenuElement;
1616
        
1617
            if (sType == "menu" || sType == "split") {
1618
1619
                oTarget = Event.getTarget(p_oEvent);
1620
                oMenuElement = this._menu.element;
1621
        
1622
                if (oTarget != oMenuElement && 
1623
                    !Dom.isAncestor(oMenuElement, oTarget)) {
1624
1625
                    this.removeStateCSSClasses((sType == "menu" ? 
1626
                        "active" : "activeoption"));
1627
            
1628
                    this._hideMenu();
1629
1630
                }
1631
        
1632
            }
1633
        
1634
            Event.removeListener(document, "mouseup", this._onDocumentMouseUp);
1635
        
1636
        },
1637
        
1638
        
1639
        /**
1640
        * @method _onMouseDown
1641
        * @description "mousedown" event handler for the button.
1642
        * @protected
1643
        * @param {Event} p_oEvent Object representing the DOM event object  
1644
        * passed back by the event utility (YAHOO.util.Event).
1645
        */
1646
        _onMouseDown: function (p_oEvent) {
1647
        
1648
            var sType,
1649
            	bReturnVal = true;
1650
        
1651
        
1652
            function onMouseUp() {
1653
            
1654
                this._hideMenu();
1655
                this.removeListener("mouseup", onMouseUp);
1656
            
1657
            }
1658
        
1659
        
1660
            if ((p_oEvent.which || p_oEvent.button) == 1) {
1661
        
1662
        
1663
                if (!this.hasFocus()) {
1664
                
1665
                    this.focus();
1666
                
1667
                }
1668
        
1669
        
1670
                sType = this.get("type");
1671
        
1672
        
1673
                if (sType == "split") {
1674
                
1675
                    if (Event.getPageX(p_oEvent) > this._nOptionRegionX) {
1676
                        
1677
                        this.fireEvent("option", p_oEvent);
1678
						bReturnVal = false;
1679
        
1680
                    }
1681
                    else {
1682
        
1683
                        this.addStateCSSClasses("active");
1684
        
1685
                        this._activationButtonPressed = true;
1686
        
1687
                    }
1688
        
1689
                }
1690
                else if (sType == "menu") {
1691
        
1692
                    if (this.isActive()) {
1693
        
1694
                        this._hideMenu();
1695
        
1696
                        this._activationButtonPressed = false;
1697
        
1698
                    }
1699
                    else {
1700
        
1701
                        this._showMenu(p_oEvent);
1702
        
1703
                        this._activationButtonPressed = true;
1704
                    
1705
                    }
1706
        
1707
                }
1708
                else {
1709
        
1710
                    this.addStateCSSClasses("active");
1711
        
1712
                    this._activationButtonPressed = true;
1713
                
1714
                }
1715
        
1716
        
1717
        
1718
                if (sType == "split" || sType == "menu") {
1719
1720
                    this._hideMenuTimer = Lang.later(250, this, this.on, ["mouseup", onMouseUp]);
1721
        
1722
                }
1723
        
1724
            }
1725
            
1726
            return bReturnVal;
1727
            
1728
        },
1729
        
1730
        
1731
        /**
1732
        * @method _onMouseUp
1733
        * @description "mouseup" event handler for the button.
1734
        * @protected
1735
        * @param {Event} p_oEvent Object representing the DOM event object  
1736
        * passed back by the event utility (YAHOO.util.Event).
1737
        */
1738
        _onMouseUp: function (p_oEvent) {
1739
        
1740
            var sType = this.get("type"),
1741
            	oHideMenuTimer = this._hideMenuTimer,
1742
            	bReturnVal = true;
1743
        
1744
        
1745
            if (oHideMenuTimer) {
1746
  
1747
  				oHideMenuTimer.cancel();
1748
        
1749
            }
1750
        
1751
        
1752
            if (sType == "checkbox" || sType == "radio") {
1753
        
1754
                this.set("checked", !(this.get("checked")));
1755
            
1756
            }
1757
        
1758
        
1759
            this._activationButtonPressed = false;
1760
            
1761
        
1762
            if (sType != "menu") {
1763
        
1764
                this.removeStateCSSClasses("active");
1765
            
1766
            }
1767
1768
                
1769
			if (sType == "split" && Event.getPageX(p_oEvent) > this._nOptionRegionX) {
1770
				
1771
				bReturnVal = false;
1772
1773
			}
1774
1775
			return bReturnVal;
1776
            
1777
        },
1778
        
1779
        
1780
        /**
1781
        * @method _onFocus
1782
        * @description "focus" event handler for the button.
1783
        * @protected
1784
        * @param {Event} p_oEvent Object representing the DOM event object  
1785
        * passed back by the event utility (YAHOO.util.Event).
1786
        */
1787
        _onFocus: function (p_oEvent) {
1788
        
1789
            var oElement;
1790
        
1791
            this.addStateCSSClasses("focus");
1792
        
1793
            if (this._activationKeyPressed) {
1794
        
1795
                this.addStateCSSClasses("active");
1796
           
1797
            }
1798
        
1799
            m_oFocusedButton = this;
1800
        
1801
        
1802
            if (!this._hasKeyEventHandlers) {
1803
        
1804
                oElement = this._button;
1805
        
1806
                Event.on(oElement, "blur", this._onBlur, null, this);
1807
                Event.on(oElement, "keydown", this._onKeyDown, null, this);
1808
                Event.on(oElement, "keyup", this._onKeyUp, null, this);
1809
        
1810
                this._hasKeyEventHandlers = true;
1811
        
1812
            }
1813
        
1814
        
1815
            this.fireEvent("focus", p_oEvent);
1816
        
1817
        },
1818
        
1819
        
1820
        /**
1821
        * @method _onBlur
1822
        * @description "blur" event handler for the button.
1823
        * @protected
1824
        * @param {Event} p_oEvent Object representing the DOM event object  
1825
        * passed back by the event utility (YAHOO.util.Event).
1826
        */
1827
        _onBlur: function (p_oEvent) {
1828
        
1829
            this.removeStateCSSClasses("focus");
1830
        
1831
            if (this.get("type") != "menu") {
1832
        
1833
                this.removeStateCSSClasses("active");
1834
1835
            }    
1836
        
1837
            if (this._activationKeyPressed) {
1838
        
1839
                Event.on(document, "keyup", this._onDocumentKeyUp, null, this);
1840
        
1841
            }
1842
        
1843
        
1844
            m_oFocusedButton = null;
1845
        
1846
            this.fireEvent("blur", p_oEvent);
1847
           
1848
        },
1849
        
1850
        
1851
        /**
1852
        * @method _onDocumentKeyUp
1853
        * @description "keyup" event handler for the document.
1854
        * @protected
1855
        * @param {Event} p_oEvent Object representing the DOM event object  
1856
        * passed back by the event utility (YAHOO.util.Event).
1857
        */
1858
        _onDocumentKeyUp: function (p_oEvent) {
1859
        
1860
            if (this._isActivationKey(Event.getCharCode(p_oEvent))) {
1861
        
1862
                this._activationKeyPressed = false;
1863
                
1864
                Event.removeListener(document, "keyup", this._onDocumentKeyUp);
1865
            
1866
            }
1867
        
1868
        },
1869
        
1870
        
1871
        /**
1872
        * @method _onKeyDown
1873
        * @description "keydown" event handler for the button.
1874
        * @protected
1875
        * @param {Event} p_oEvent Object representing the DOM event object  
1876
        * passed back by the event utility (YAHOO.util.Event).
1877
        */
1878
        _onKeyDown: function (p_oEvent) {
1879
        
1880
            var oMenu = this._menu;
1881
        
1882
        
1883
            if (this.get("type") == "split" && 
1884
                this._isSplitButtonOptionKey(p_oEvent)) {
1885
        
1886
                this.fireEvent("option", p_oEvent);
1887
        
1888
            }
1889
            else if (this._isActivationKey(Event.getCharCode(p_oEvent))) {
1890
        
1891
                if (this.get("type") == "menu") {
1892
        
1893
                    this._showMenu(p_oEvent);
1894
        
1895
                }
1896
                else {
1897
        
1898
                    this._activationKeyPressed = true;
1899
                    
1900
                    this.addStateCSSClasses("active");
1901
                
1902
                }
1903
            
1904
            }
1905
        
1906
        
1907
            if (oMenu && oMenu.cfg.getProperty("visible") && 
1908
                Event.getCharCode(p_oEvent) == 27) {
1909
            
1910
                oMenu.hide();
1911
                this.focus();
1912
            
1913
            }
1914
        
1915
        },
1916
        
1917
        
1918
        /**
1919
        * @method _onKeyUp
1920
        * @description "keyup" event handler for the button.
1921
        * @protected
1922
        * @param {Event} p_oEvent Object representing the DOM event object  
1923
        * passed back by the event utility (YAHOO.util.Event).
1924
        */
1925
        _onKeyUp: function (p_oEvent) {
1926
        
1927
            var sType;
1928
        
1929
            if (this._isActivationKey(Event.getCharCode(p_oEvent))) {
1930
        
1931
                sType = this.get("type");
1932
        
1933
                if (sType == "checkbox" || sType == "radio") {
1934
        
1935
                    this.set("checked", !(this.get("checked")));
1936
                
1937
                }
1938
        
1939
                this._activationKeyPressed = false;
1940
        
1941
                if (this.get("type") != "menu") {
1942
        
1943
                    this.removeStateCSSClasses("active");
1944
        
1945
                }
1946
        
1947
            }
1948
        
1949
        },
1950
        
1951
        
1952
        /**
1953
        * @method _onClick
1954
        * @description "click" event handler for the button.
1955
        * @protected
1956
        * @param {Event} p_oEvent Object representing the DOM event object  
1957
        * passed back by the event utility (YAHOO.util.Event).
1958
        */
1959
        _onClick: function (p_oEvent) {
1960
        
1961
            var sType = this.get("type"),
1962
                oForm,
1963
                oSrcElement,
1964
                bReturnVal;
1965
        
1966
1967
			switch (sType) {
1968
1969
			case "submit":
1970
1971
				if (p_oEvent.returnValue !== false) {
1972
1973
					this.submitForm();
1974
1975
				}
1976
1977
				break;
1978
1979
			case "reset":
1980
1981
				oForm = this.getForm();
1982
1983
				if (oForm) {
1984
1985
					oForm.reset();
1986
1987
				}
1988
1989
				break;
1990
1991
1992
			case "split":
1993
1994
				if (this._nOptionRegionX > 0 && 
1995
						(Event.getPageX(p_oEvent) > this._nOptionRegionX)) {
1996
1997
					bReturnVal = false;
1998
1999
				}
2000
				else {
2001
2002
					this._hideMenu();
2003
2004
					oSrcElement = this.get("srcelement");
2005
2006
					if (oSrcElement && oSrcElement.type == "submit" && 
2007
							p_oEvent.returnValue !== false) {
2008
2009
						this.submitForm();
2010
2011
					}
2012
2013
				}
2014
2015
				break;
2016
2017
			}
2018
2019
			return bReturnVal;
2020
        
2021
        },
2022
        
2023
        
2024
        /**
2025
        * @method _onDblClick
2026
        * @description "dblclick" event handler for the button.
2027
        * @protected
2028
        * @param {Event} p_oEvent Object representing the DOM event object  
2029
        * passed back by the event utility (YAHOO.util.Event).
2030
        */
2031
        _onDblClick: function (p_oEvent) {
2032
        
2033
            var bReturnVal = true;
2034
    
2035
			if (this.get("type") == "split" && Event.getPageX(p_oEvent) > this._nOptionRegionX) {
2036
2037
				bReturnVal = false;
2038
			
2039
			}
2040
        
2041
        	return bReturnVal;
2042
        
2043
        },        
2044
        
2045
        
2046
        /**
2047
        * @method _onAppendTo
2048
        * @description "appendTo" event handler for the button.
2049
        * @protected
2050
        * @param {Event} p_oEvent Object representing the DOM event object  
2051
        * passed back by the event utility (YAHOO.util.Event).
2052
        */
2053
        _onAppendTo: function (p_oEvent) {
2054
        
2055
            /*
2056
                It is necessary to call "_addListenersToForm" using 
2057
                "setTimeout" to make sure that the button's "form" property 
2058
                returns a node reference.  Sometimes, if you try to get the 
2059
                reference immediately after appending the field, it is null.
2060
            */
2061
        
2062
            Lang.later(0, this, this._addListenersToForm);
2063
        
2064
        },
2065
        
2066
        
2067
        /**
2068
        * @method _onFormReset
2069
        * @description "reset" event handler for the button's form.
2070
        * @protected
2071
        * @param {Event} p_oEvent Object representing the DOM event 
2072
        * object passed back by the event utility (YAHOO.util.Event).
2073
        */
2074
        _onFormReset: function (p_oEvent) {
2075
        
2076
            var sType = this.get("type"),
2077
                oMenu = this._menu;
2078
        
2079
            if (sType == "checkbox" || sType == "radio") {
2080
        
2081
                this.resetValue("checked");
2082
        
2083
            }
2084
        
2085
        
2086
            if (Menu && oMenu && (oMenu instanceof Menu)) {
2087
        
2088
                this.resetValue("selectedMenuItem");
2089
        
2090
            }
2091
        
2092
        },
2093
2094
2095
        /**
2096
        * @method _onFormSubmit
2097
        * @description "submit" event handler for the button's form.
2098
        * @protected
2099
        * @param {Event} p_oEvent Object representing the DOM event 
2100
        * object passed back by the event utility (YAHOO.util.Event).
2101
        */        
2102
        _onFormSubmit: function (p_oEvent) {
2103
        
2104
        	this.createHiddenFields();
2105
        
2106
        },
2107
        
2108
        
2109
        /**
2110
        * @method _onDocumentMouseDown
2111
        * @description "mousedown" event handler for the document.
2112
        * @protected
2113
        * @param {Event} p_oEvent Object representing the DOM event object  
2114
        * passed back by the event utility (YAHOO.util.Event).
2115
        */
2116
        _onDocumentMouseDown: function (p_oEvent) {
2117
2118
            var oTarget = Event.getTarget(p_oEvent),
2119
                oButtonElement = this.get("element"),
2120
                oMenuElement = this._menu.element;
2121
           
2122
        
2123
            if (oTarget != oButtonElement && 
2124
                !Dom.isAncestor(oButtonElement, oTarget) && 
2125
                oTarget != oMenuElement && 
2126
                !Dom.isAncestor(oMenuElement, oTarget)) {
2127
        
2128
                this._hideMenu();
2129
2130
				//	In IE when the user mouses down on a focusable element
2131
				//	that element will be focused and become the "activeElement".
2132
				//	(http://msdn.microsoft.com/en-us/library/ms533065(VS.85).aspx)
2133
				//	However, there is a bug in IE where if there is a  
2134
				//	positioned element with a focused descendant that is 
2135
				//	hidden in response to the mousedown event, the target of 
2136
				//	the mousedown event will appear to have focus, but will 
2137
				//	not be set as the activeElement.  This will result 
2138
				//	in the element not firing key events, even though it
2139
				//	appears to have focus.	The following call to "setActive"
2140
				//	fixes this bug.
2141
2142
				if (UA.ie && oTarget.focus) {
2143
					oTarget.setActive();
2144
				}
2145
        
2146
                Event.removeListener(document, "mousedown", 
2147
                    this._onDocumentMouseDown);    
2148
            
2149
            }
2150
        
2151
        },
2152
        
2153
        
2154
        /**
2155
        * @method _onOption
2156
        * @description "option" event handler for the button.
2157
        * @protected
2158
        * @param {Event} p_oEvent Object representing the DOM event object  
2159
        * passed back by the event utility (YAHOO.util.Event).
2160
        */
2161
        _onOption: function (p_oEvent) {
2162
        
2163
            if (this.hasClass(this.CLASS_NAME_PREFIX + "split-button-activeoption")) {
2164
        
2165
                this._hideMenu();
2166
        
2167
                this._bOptionPressed = false;
2168
        
2169
            }
2170
            else {
2171
        
2172
                this._showMenu(p_oEvent);    
2173
        
2174
                this._bOptionPressed = true;
2175
        
2176
            }
2177
        
2178
        },
2179
        
2180
        
2181
        /**
2182
        * @method _onMenuShow
2183
        * @description "show" event handler for the button's menu.
2184
        * @private
2185
        * @param {String} p_sType String representing the name of the event  
2186
        * that was fired.
2187
        */
2188
        _onMenuShow: function (p_sType) {
2189
        
2190
            Event.on(document, "mousedown", this._onDocumentMouseDown, 
2191
                null, this);
2192
        
2193
            var sState = (this.get("type") == "split") ? "activeoption" : "active";
2194
        
2195
            this.addStateCSSClasses(sState);
2196
        
2197
        },
2198
        
2199
        
2200
        /**
2201
        * @method _onMenuHide
2202
        * @description "hide" event handler for the button's menu.
2203
        * @private
2204
        * @param {String} p_sType String representing the name of the event  
2205
        * that was fired.
2206
        */
2207
        _onMenuHide: function (p_sType) {
2208
            
2209
            var sState = (this.get("type") == "split") ? "activeoption" : "active";
2210
        
2211
            this.removeStateCSSClasses(sState);
2212
        
2213
        
2214
            if (this.get("type") == "split") {
2215
        
2216
                this._bOptionPressed = false;
2217
            
2218
            }
2219
        
2220
        },
2221
        
2222
        
2223
        /**
2224
        * @method _onMenuKeyDown
2225
        * @description "keydown" event handler for the button's menu.
2226
        * @private
2227
        * @param {String} p_sType String representing the name of the event  
2228
        * that was fired.
2229
        * @param {Array} p_aArgs Array of arguments sent when the event 
2230
        * was fired.
2231
        */
2232
        _onMenuKeyDown: function (p_sType, p_aArgs) {
2233
        
2234
            var oEvent = p_aArgs[0];
2235
        
2236
            if (Event.getCharCode(oEvent) == 27) {
2237
        
2238
                this.focus();
2239
        
2240
                if (this.get("type") == "split") {
2241
                
2242
                    this._bOptionPressed = false;
2243
                
2244
                }
2245
        
2246
            }
2247
        
2248
        },
2249
        
2250
        
2251
        /**
2252
        * @method _onMenuRender
2253
        * @description "render" event handler for the button's menu.
2254
        * @private
2255
        * @param {String} p_sType String representing the name of the  
2256
        * event thatwas fired.
2257
        */
2258
        _onMenuRender: function (p_sType) {
2259
        
2260
            var oButtonElement = this.get("element"),
2261
                oButtonParent = oButtonElement.parentNode,
2262
				oMenu = this._menu,
2263
                oMenuElement = oMenu.element,
2264
				oSrcElement = oMenu.srcElement,
2265
				oItem;
2266
        
2267
        
2268
            if (oButtonParent != oMenuElement.parentNode) {
2269
        
2270
                oButtonParent.appendChild(oMenuElement);
2271
            
2272
            }
2273
2274
			this._renderedMenu = true;
2275
2276
			//	If the user has designated an <option> of the Menu's source 
2277
			//	<select> element to be selected, sync the selectedIndex with 
2278
			//	the "selectedMenuItem" Attribute.
2279
2280
			if (oSrcElement && 
2281
					oSrcElement.nodeName.toLowerCase() === "select" && 
2282
					oSrcElement.value) {
2283
				
2284
				
2285
				oItem = oMenu.getItem(oSrcElement.selectedIndex);
2286
				
2287
				//	Set the value of the "selectedMenuItem" attribute
2288
				//	silently since this is the initial set--synchronizing 
2289
				//	the value of the source <SELECT> element in the DOM with 
2290
				//	its corresponding Menu instance.
2291
2292
				this.set("selectedMenuItem", oItem, true);
2293
				
2294
				//	Call the "_onSelectedMenuItemChange" method since the 
2295
				//	attribute was set silently.
2296
2297
				this._onSelectedMenuItemChange({ newValue: oItem });
2298
				
2299
			}
2300
2301
        },
2302
2303
        
2304
        
2305
        /**
2306
        * @method _onMenuClick
2307
        * @description "click" event handler for the button's menu.
2308
        * @private
2309
        * @param {String} p_sType String representing the name of the event  
2310
        * that was fired.
2311
        * @param {Array} p_aArgs Array of arguments sent when the event 
2312
        * was fired.
2313
        */
2314
        _onMenuClick: function (p_sType, p_aArgs) {
2315
2316
            var oItem = p_aArgs[1],
2317
                oSrcElement;
2318
        
2319
            if (oItem) {
2320
        
2321
				this.set("selectedMenuItem", oItem);
2322
2323
                oSrcElement = this.get("srcelement");
2324
            
2325
                if (oSrcElement && oSrcElement.type == "submit") {
2326
        
2327
                    this.submitForm();
2328
            
2329
                }
2330
            
2331
                this._hideMenu();
2332
            
2333
            }
2334
        
2335
        },
2336
2337
2338
        /**
2339
        * @method _onSelectedMenuItemChange
2340
        * @description "selectedMenuItemChange" event handler for the Button's
2341
		* "selectedMenuItem" attribute.
2342
        * @param {Event} event Object representing the DOM event object  
2343
        * passed back by the event utility (YAHOO.util.Event).
2344
        */
2345
		_onSelectedMenuItemChange: function (event) {
2346
		
2347
			var oSelected = event.prevValue,
2348
				oItem = event.newValue,
2349
				sPrefix = this.CLASS_NAME_PREFIX;
2350
2351
			if (oSelected) {
2352
				Dom.removeClass(oSelected.element, (sPrefix + "button-selectedmenuitem"));
2353
			}
2354
			
2355
			if (oItem) {
2356
				Dom.addClass(oItem.element, (sPrefix + "button-selectedmenuitem"));
2357
			}
2358
			
2359
		},        
2360
        
2361
2362
        /**
2363
        * @method _onLabelClick
2364
        * @description "click" event handler for the Button's
2365
		* <code>&#60;label&#62;</code> element.
2366
        * @param {Event} event Object representing the DOM event object  
2367
        * passed back by the event utility (YAHOO.util.Event).
2368
        */
2369
		_onLabelClick: function (event) {
2370
2371
			this.focus();
2372
2373
			var sType = this.get("type");
2374
2375
			if (sType == "radio" || sType == "checkbox") {
2376
				this.set("checked", (!this.get("checked")));						
2377
			}
2378
			
2379
		},
2380
2381
        
2382
        // Public methods
2383
        
2384
        
2385
        /**
2386
        * @method createButtonElement
2387
        * @description Creates the button's HTML elements.
2388
        * @param {String} p_sType String indicating the type of element 
2389
        * to create.
2390
        * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
2391
        * level-one-html.html#ID-58190037">HTMLElement</a>}
2392
        */
2393
        createButtonElement: function (p_sType) {
2394
        
2395
            var sNodeName = this.NODE_NAME,
2396
                oElement = document.createElement(sNodeName);
2397
        
2398
            oElement.innerHTML =  "<" + sNodeName + " class=\"first-child\">" + 
2399
                (p_sType == "link" ? "<a></a>" : 
2400
                "<button type=\"button\"></button>") + "</" + sNodeName + ">";
2401
        
2402
            return oElement;
2403
        
2404
        },
2405
2406
        
2407
        /**
2408
        * @method addStateCSSClasses
2409
        * @description Appends state-specific CSS classes to the button's root 
2410
        * DOM element.
2411
        */
2412
        addStateCSSClasses: function (p_sState) {
2413
        
2414
            var sType = this.get("type"),
2415
				sPrefix = this.CLASS_NAME_PREFIX;
2416
        
2417
            if (Lang.isString(p_sState)) {
2418
        
2419
                if (p_sState != "activeoption" && p_sState != "hoveroption") {
2420
        
2421
                    this.addClass(sPrefix + this.CSS_CLASS_NAME + ("-" + p_sState));
2422
        
2423
                }
2424
        
2425
                this.addClass(sPrefix + sType + ("-button-" + p_sState));
2426
            
2427
            }
2428
        
2429
        },
2430
        
2431
        
2432
        /**
2433
        * @method removeStateCSSClasses
2434
        * @description Removes state-specific CSS classes to the button's root 
2435
        * DOM element.
2436
        */
2437
        removeStateCSSClasses: function (p_sState) {
2438
        
2439
            var sType = this.get("type"),
2440
				sPrefix = this.CLASS_NAME_PREFIX;
2441
        
2442
            if (Lang.isString(p_sState)) {
2443
        
2444
                this.removeClass(sPrefix + this.CSS_CLASS_NAME + ("-" + p_sState));
2445
                this.removeClass(sPrefix + sType + ("-button-" + p_sState));
2446
            
2447
            }
2448
        
2449
        },
2450
        
2451
        
2452
        /**
2453
        * @method createHiddenFields
2454
        * @description Creates the button's hidden form field and appends it 
2455
        * to its parent form.
2456
        * @return {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
2457
        * level-one-html.html#ID-6043025">HTMLInputElement</a>|Array}
2458
        */
2459
        createHiddenFields: function () {
2460
        
2461
            this.removeHiddenFields();
2462
        
2463
            var oForm = this.getForm(),
2464
                oButtonField,
2465
                sType,
2466
                bCheckable,
2467
                oMenu,
2468
                oMenuItem,
2469
                sButtonName,
2470
                oValue,
2471
                oMenuField,
2472
                oReturnVal,
2473
				sMenuFieldName,
2474
				oMenuSrcElement,
2475
				bMenuSrcElementIsSelect = false;
2476
        
2477
        
2478
            if (oForm && !this.get("disabled")) {
2479
        
2480
                sType = this.get("type");
2481
                bCheckable = (sType == "checkbox" || sType == "radio");
2482
        
2483
        
2484
                if ((bCheckable && this.get("checked")) || (m_oSubmitTrigger == this)) {
2485
                
2486
                    YAHOO.log("Creating hidden field.", "info", this.toString());
2487
        
2488
                    oButtonField = createInputElement((bCheckable ? sType : "hidden"),
2489
                                    this.get("name"), this.get("value"), this.get("checked"));
2490
            
2491
            
2492
                    if (oButtonField) {
2493
            
2494
                        if (bCheckable) {
2495
            
2496
                            oButtonField.style.display = "none";
2497
            
2498
                        }
2499
            
2500
                        oForm.appendChild(oButtonField);
2501
            
2502
                    }
2503
        
2504
                }
2505
                    
2506
        
2507
                oMenu = this._menu;
2508
            
2509
            
2510
                if (Menu && oMenu && (oMenu instanceof Menu)) {
2511
        
2512
                    YAHOO.log("Creating hidden field for menu.", "info", this.toString());
2513
        
2514
                    oMenuItem = this.get("selectedMenuItem");
2515
					oMenuSrcElement = oMenu.srcElement;
2516
					bMenuSrcElementIsSelect = (oMenuSrcElement && 
2517
												oMenuSrcElement.nodeName.toUpperCase() == "SELECT");
2518
2519
                    if (oMenuItem) {
2520
2521
						oValue = (oMenuItem.value === null || oMenuItem.value === "") ? 
2522
									oMenuItem.cfg.getProperty("text") : oMenuItem.value;
2523
2524
						sButtonName = this.get("name");
2525
2526
2527
						if (bMenuSrcElementIsSelect) {
2528
						
2529
							sMenuFieldName = oMenuSrcElement.name;
2530
						
2531
						}
2532
						else if (sButtonName) {
2533
2534
							sMenuFieldName = (sButtonName + "_options");
2535
						
2536
						}
2537
						
2538
2539
						if (oValue && sMenuFieldName) {
2540
		
2541
							oMenuField = createInputElement("hidden", sMenuFieldName, oValue);
2542
							oForm.appendChild(oMenuField);
2543
		
2544
						}
2545
                    
2546
                    }
2547
                    else if (bMenuSrcElementIsSelect) {
2548
					
2549
						oMenuField = oForm.appendChild(oMenuSrcElement);
2550
                    
2551
                    }
2552
        
2553
                }
2554
            
2555
            
2556
                if (oButtonField && oMenuField) {
2557
        
2558
                    this._hiddenFields = [oButtonField, oMenuField];
2559
        
2560
                }
2561
                else if (!oButtonField && oMenuField) {
2562
        
2563
                    this._hiddenFields = oMenuField;
2564
                
2565
                }
2566
                else if (oButtonField && !oMenuField) {
2567
        
2568
                    this._hiddenFields = oButtonField;
2569
                
2570
                }
2571
        
2572
        		oReturnVal = this._hiddenFields;
2573
        
2574
            }
2575
2576
			return oReturnVal;
2577
        
2578
        },
2579
        
2580
        
2581
        /**
2582
        * @method removeHiddenFields
2583
        * @description Removes the button's hidden form field(s) from its 
2584
        * parent form.
2585
        */
2586
        removeHiddenFields: function () {
2587
        
2588
            var oField = this._hiddenFields,
2589
                nFields,
2590
                i;
2591
        
2592
            function removeChild(p_oElement) {
2593
        
2594
                if (Dom.inDocument(p_oElement)) {
2595
        
2596
                    p_oElement.parentNode.removeChild(p_oElement);
2597
2598
                }
2599
                
2600
            }
2601
            
2602
        
2603
            if (oField) {
2604
        
2605
                if (Lang.isArray(oField)) {
2606
        
2607
                    nFields = oField.length;
2608
                    
2609
                    if (nFields > 0) {
2610
                    
2611
                        i = nFields - 1;
2612
                        
2613
                        do {
2614
        
2615
                            removeChild(oField[i]);
2616
        
2617
                        }
2618
                        while (i--);
2619
                    
2620
                    }
2621
                
2622
                }
2623
                else {
2624
        
2625
                    removeChild(oField);
2626
        
2627
                }
2628
        
2629
                this._hiddenFields = null;
2630
            
2631
            }
2632
        
2633
        },
2634
        
2635
        
2636
        /**
2637
        * @method submitForm
2638
        * @description Submits the form to which the button belongs.  Returns  
2639
        * true if the form was submitted successfully, false if the submission 
2640
        * was cancelled.
2641
        * @protected
2642
        * @return {Boolean}
2643
        */
2644
        submitForm: function () {
2645
        
2646
            var oForm = this.getForm(),
2647
        
2648
                oSrcElement = this.get("srcelement"),
2649
        
2650
                /*
2651
                    Boolean indicating if the event fired successfully 
2652
                    (was not cancelled by any handlers)
2653
                */
2654
        
2655
                bSubmitForm = false,
2656
                
2657
                oEvent;
2658
        
2659
        
2660
            if (oForm) {
2661
        
2662
                if (this.get("type") == "submit" || (oSrcElement && oSrcElement.type == "submit")) {
2663
        
2664
                    m_oSubmitTrigger = this;
2665
                    
2666
                }
2667
        
2668
        
2669
                if (UA.ie) {
2670
        
2671
                    bSubmitForm = oForm.fireEvent("onsubmit");
2672
        
2673
                }
2674
                else {  // Gecko, Opera, and Safari
2675
        
2676
                    oEvent = document.createEvent("HTMLEvents");
2677
                    oEvent.initEvent("submit", true, true);
2678
        
2679
                    bSubmitForm = oForm.dispatchEvent(oEvent);
2680
        
2681
                }
2682
        
2683
        
2684
                /*
2685
                    In IE and Safari, dispatching a "submit" event to a form 
2686
                    WILL cause the form's "submit" event to fire, but WILL NOT 
2687
                    submit the form.  Therefore, we need to call the "submit" 
2688
                    method as well.
2689
                */
2690
              
2691
                if ((UA.ie || UA.webkit) && bSubmitForm) {
2692
        
2693
                    oForm.submit();
2694
                
2695
                }
2696
            
2697
            }
2698
        
2699
            return bSubmitForm;
2700
            
2701
        },
2702
        
2703
        
2704
        /**
2705
        * @method init
2706
        * @description The Button class's initialization method.
2707
        * @param {String} p_oElement String specifying the id attribute of the 
2708
        * <code>&#60;input&#62;</code>, <code>&#60;button&#62;</code>,
2709
        * <code>&#60;a&#62;</code>, or <code>&#60;span&#62;</code> element to 
2710
        * be used to create the button.
2711
        * @param {<a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
2712
        * level-one-html.html#ID-6043025">HTMLInputElement</a>|<a href="http://
2713
        * www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html
2714
        * #ID-34812697">HTMLButtonElement</a>|<a href="http://www.w3.org/TR
2715
        * /2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-33759296">
2716
        * HTMLElement</a>} p_oElement Object reference for the 
2717
        * <code>&#60;input&#62;</code>, <code>&#60;button&#62;</code>, 
2718
        * <code>&#60;a&#62;</code>, or <code>&#60;span&#62;</code> element to be 
2719
        * used to create the button.
2720
        * @param {Object} p_oElement Object literal specifying a set of 
2721
        * configuration attributes used to create the button.
2722
        * @param {Object} p_oAttributes Optional. Object literal specifying a 
2723
        * set of configuration attributes used to create the button.
2724
        */
2725
        init: function (p_oElement, p_oAttributes) {
2726
        
2727
            var sNodeName = p_oAttributes.type == "link" ? "a" : "button",
2728
                oSrcElement = p_oAttributes.srcelement,
2729
                oButton = p_oElement.getElementsByTagName(sNodeName)[0],
2730
                oInput;
2731
2732
2733
            if (!oButton) {
2734
2735
                oInput = p_oElement.getElementsByTagName("input")[0];
2736
2737
2738
                if (oInput) {
2739
2740
                    oButton = document.createElement("button");
2741
                    oButton.setAttribute("type", "button");
2742
2743
                    oInput.parentNode.replaceChild(oButton, oInput);
2744
                
2745
                }
2746
2747
            }
2748
2749
            this._button = oButton;
2750
2751
2752
            YAHOO.widget.Button.superclass.init.call(this, p_oElement, p_oAttributes);
2753
2754
2755
			var sId = this.get("id"),
2756
				sButtonId = sId + "-button";
2757
2758
2759
        	oButton.id = sButtonId;
2760
2761
2762
			var aLabels,
2763
				oLabel;
2764
2765
2766
        	var hasLabel = function (element) {
2767
        	
2768
				return (element.htmlFor === sId);
2769
2770
        	};
2771
2772
2773
			var setLabel = function () {
2774
2775
				oLabel.setAttribute((UA.ie ? "htmlFor" : "for"), sButtonId);
2776
			
2777
			};
2778
2779
2780
			if (oSrcElement && this.get("type") != "link") {
2781
2782
				aLabels = Dom.getElementsBy(hasLabel, "label");
2783
2784
				if (Lang.isArray(aLabels) && aLabels.length > 0) {
2785
				
2786
					oLabel = aLabels[0];
2787
				
2788
				}
2789
2790
			}
2791
        
2792
2793
            m_oButtons[sId] = this;
2794
2795
        	var sPrefix = this.CLASS_NAME_PREFIX;
2796
2797
            this.addClass(sPrefix + this.CSS_CLASS_NAME);
2798
            this.addClass(sPrefix + this.get("type") + "-button");
2799
        
2800
            Event.on(this._button, "focus", this._onFocus, null, this);
2801
            this.on("mouseover", this._onMouseOver);
2802
			this.on("mousedown", this._onMouseDown);
2803
			this.on("mouseup", this._onMouseUp);
2804
            this.on("click", this._onClick);
2805
2806
			//	Need to reset the value of the "onclick" Attribute so that any
2807
			//	handlers registered via the "onclick" Attribute are fired after 
2808
			//	Button's default "_onClick" listener.
2809
2810
			var fnOnClick = this.get("onclick");
2811
2812
			this.set("onclick", null);
2813
			this.set("onclick", fnOnClick);
2814
2815
            this.on("dblclick", this._onDblClick);
2816
2817
2818
			var oParentNode;
2819
2820
            if (oLabel) {
2821
            
2822
				if (this.get("replaceLabel")) {
2823
2824
					this.set("label", oLabel.innerHTML);
2825
					
2826
					oParentNode = oLabel.parentNode;
2827
					
2828
					oParentNode.removeChild(oLabel);
2829
					
2830
				}
2831
				else {
2832
2833
					this.on("appendTo", setLabel); 
2834
2835
					Event.on(oLabel, "click", this._onLabelClick, null, this);
2836
2837
					this._label = oLabel;
2838
					
2839
				}
2840
            
2841
            }
2842
            
2843
            this.on("appendTo", this._onAppendTo);
2844
       
2845
        
2846
2847
            var oContainer = this.get("container"),
2848
                oElement = this.get("element"),
2849
                bElInDoc = Dom.inDocument(oElement);
2850
2851
2852
            if (oContainer) {
2853
        
2854
                if (oSrcElement && oSrcElement != oElement) {
2855
                
2856
                    oParentNode = oSrcElement.parentNode;
2857
2858
                    if (oParentNode) {
2859
                    
2860
                        oParentNode.removeChild(oSrcElement);
2861
                    
2862
                    }
2863
2864
                }
2865
        
2866
                if (Lang.isString(oContainer)) {
2867
        
2868
                    Event.onContentReady(oContainer, this.appendTo, oContainer, this);
2869
        
2870
                }
2871
                else {
2872
        
2873
        			this.on("init", function () {
2874
        			
2875
        				Lang.later(0, this, this.appendTo, oContainer);
2876
        			
2877
        			});
2878
        
2879
                }
2880
        
2881
            }
2882
            else if (!bElInDoc && oSrcElement && oSrcElement != oElement) {
2883
2884
                oParentNode = oSrcElement.parentNode;
2885
        
2886
                if (oParentNode) {
2887
        
2888
                    this.fireEvent("beforeAppendTo", {
2889
                        type: "beforeAppendTo",
2890
                        target: oParentNode
2891
                    });
2892
            
2893
                    oParentNode.replaceChild(oElement, oSrcElement);
2894
            
2895
                    this.fireEvent("appendTo", {
2896
                        type: "appendTo",
2897
                        target: oParentNode
2898
                    });
2899
                
2900
                }
2901
        
2902
            }
2903
            else if (this.get("type") != "link" && bElInDoc && oSrcElement && 
2904
                oSrcElement == oElement) {
2905
        
2906
                this._addListenersToForm();
2907
        
2908
            }
2909
        
2910
            YAHOO.log("Initialization completed.", "info", this.toString());
2911
        
2912
2913
			this.fireEvent("init", {
2914
				type: "init",
2915
				target: this
2916
			});        
2917
        
2918
        },
2919
        
2920
        
2921
        /**
2922
        * @method initAttributes
2923
        * @description Initializes all of the configuration attributes used to  
2924
        * create the button.
2925
        * @param {Object} p_oAttributes Object literal specifying a set of 
2926
        * configuration attributes used to create the button.
2927
        */
2928
        initAttributes: function (p_oAttributes) {
2929
        
2930
            var oAttributes = p_oAttributes || {};
2931
        
2932
            YAHOO.widget.Button.superclass.initAttributes.call(this, 
2933
                oAttributes);
2934
        
2935
        
2936
            /**
2937
            * @attribute type
2938
            * @description String specifying the button's type.  Possible 
2939
            * values are: "push," "link," "submit," "reset," "checkbox," 
2940
            * "radio," "menu," and "split."
2941
            * @default "push"
2942
            * @type String
2943
			* @writeonce
2944
            */
2945
            this.setAttributeConfig("type", {
2946
        
2947
                value: (oAttributes.type || "push"),
2948
                validator: Lang.isString,
2949
                writeOnce: true,
2950
                method: this._setType
2951
2952
            });
2953
        
2954
        
2955
            /**
2956
            * @attribute label
2957
            * @description String specifying the button's text label 
2958
            * or innerHTML.
2959
            * @default null
2960
            * @type String
2961
            */
2962
            this.setAttributeConfig("label", {
2963
        
2964
                value: oAttributes.label,
2965
                validator: Lang.isString,
2966
                method: this._setLabel
2967
        
2968
            });
2969
        
2970
        
2971
            /**
2972
            * @attribute value
2973
            * @description Object specifying the value for the button.
2974
            * @default null
2975
            * @type Object
2976
            */
2977
            this.setAttributeConfig("value", {
2978
        
2979
                value: oAttributes.value
2980
        
2981
            });
2982
        
2983
        
2984
            /**
2985
            * @attribute name
2986
            * @description String specifying the name for the button.
2987
            * @default null
2988
            * @type String
2989
            */
2990
            this.setAttributeConfig("name", {
2991
        
2992
                value: oAttributes.name,
2993
                validator: Lang.isString
2994
        
2995
            });
2996
        
2997
        
2998
            /**
2999
            * @attribute tabindex
3000
            * @description Number specifying the tabindex for the button.
3001
            * @default null
3002
            * @type Number
3003
            */
3004
            this.setAttributeConfig("tabindex", {
3005
        
3006
                value: oAttributes.tabindex,
3007
                validator: Lang.isNumber,
3008
                method: this._setTabIndex
3009
        
3010
            });
3011
        
3012
        
3013
            /**
3014
            * @attribute title
3015
            * @description String specifying the title for the button.
3016
            * @default null
3017
            * @type String
3018
            */
3019
            this.configureAttribute("title", {
3020
        
3021
                value: oAttributes.title,
3022
                validator: Lang.isString,
3023
                method: this._setTitle
3024
        
3025
            });
3026
        
3027
        
3028
            /**
3029
            * @attribute disabled
3030
            * @description Boolean indicating if the button should be disabled.  
3031
            * (Disabled buttons are dimmed and will not respond to user input 
3032
            * or fire events.  Does not apply to button's of type "link.")
3033
            * @default false
3034
            * @type Boolean
3035
            */
3036
            this.setAttributeConfig("disabled", {
3037
        
3038
                value: (oAttributes.disabled || false),
3039
                validator: Lang.isBoolean,
3040
                method: this._setDisabled
3041
        
3042
            });
3043
        
3044
        
3045
            /**
3046
            * @attribute href
3047
            * @description String specifying the href for the button.  Applies
3048
            * only to buttons of type "link."
3049
            * @type String
3050
            */
3051
            this.setAttributeConfig("href", {
3052
        
3053
                value: oAttributes.href,
3054
                validator: Lang.isString,
3055
                method: this._setHref
3056
        
3057
            });
3058
        
3059
        
3060
            /**
3061
            * @attribute target
3062
            * @description String specifying the target for the button.  
3063
            * Applies only to buttons of type "link."
3064
            * @type String
3065
            */
3066
            this.setAttributeConfig("target", {
3067
        
3068
                value: oAttributes.target,
3069
                validator: Lang.isString,
3070
                method: this._setTarget
3071
        
3072
            });
3073
        
3074
        
3075
            /**
3076
            * @attribute checked
3077
            * @description Boolean indicating if the button is checked. 
3078
            * Applies only to buttons of type "radio" and "checkbox."
3079
            * @default false
3080
            * @type Boolean
3081
            */
3082
            this.setAttributeConfig("checked", {
3083
        
3084
                value: (oAttributes.checked || false),
3085
                validator: Lang.isBoolean,
3086
                method: this._setChecked
3087
        
3088
            });
3089
        
3090
        
3091
            /**
3092
            * @attribute container
3093
            * @description HTML element reference or string specifying the id 
3094
            * attribute of the HTML element that the button's markup should be 
3095
            * rendered into.
3096
            * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3097
            * level-one-html.html#ID-58190037">HTMLElement</a>|String
3098
            * @default null
3099
			* @writeonce
3100
            */
3101
            this.setAttributeConfig("container", {
3102
        
3103
                value: oAttributes.container,
3104
                writeOnce: true
3105
        
3106
            });
3107
        
3108
        
3109
            /**
3110
            * @attribute srcelement
3111
            * @description Object reference to the HTML element (either 
3112
            * <code>&#60;input&#62;</code> or <code>&#60;span&#62;</code>) 
3113
            * used to create the button.
3114
            * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
3115
            * level-one-html.html#ID-58190037">HTMLElement</a>|String
3116
            * @default null
3117
			* @writeonce
3118
            */
3119
            this.setAttributeConfig("srcelement", {
3120
        
3121
                value: oAttributes.srcelement,
3122
                writeOnce: true
3123
        
3124
            });
3125
        
3126
        
3127
            /**
3128
            * @attribute menu
3129
            * @description Object specifying the menu for the button.  
3130
            * The value can be one of the following:
3131
            * <ul>
3132
            * <li>Object specifying a rendered <a href="YAHOO.widget.Menu.html">
3133
            * YAHOO.widget.Menu</a> instance.</li>
3134
            * <li>Object specifying a rendered <a href="YAHOO.widget.Overlay.html">
3135
            * YAHOO.widget.Overlay</a> instance.</li>
3136
            * <li>String specifying the id attribute of the <code>&#60;div&#62;
3137
            * </code> element used to create the menu.  By default the menu 
3138
            * will be created as an instance of 
3139
            * <a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>.  
3140
            * If the <a href="YAHOO.widget.Menu.html#CSS_CLASS_NAME">
3141
            * default CSS class name for YAHOO.widget.Menu</a> is applied to 
3142
            * the <code>&#60;div&#62;</code> element, it will be created as an
3143
            * instance of <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu
3144
            * </a>.</li><li>String specifying the id attribute of the 
3145
            * <code>&#60;select&#62;</code> element used to create the menu.
3146
            * </li><li>Object specifying the <code>&#60;div&#62;</code> element
3147
            * used to create the menu.</li>
3148
            * <li>Object specifying the <code>&#60;select&#62;</code> element
3149
            * used to create the menu.</li>
3150
            * <li>Array of object literals, each representing a set of 
3151
            * <a href="YAHOO.widget.MenuItem.html">YAHOO.widget.MenuItem</a> 
3152
            * configuration attributes.</li>
3153
            * <li>Array of strings representing the text labels for each menu 
3154
            * item in the menu.</li>
3155
            * </ul>
3156
            * @type <a href="YAHOO.widget.Menu.html">YAHOO.widget.Menu</a>|<a 
3157
            * href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>|<a 
3158
            * href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-
3159
            * one-html.html#ID-58190037">HTMLElement</a>|String|Array
3160
            * @default null
3161
			* @writeonce
3162
            */
3163
            this.setAttributeConfig("menu", {
3164
        
3165
                value: null,
3166
                method: this._setMenu,
3167
                writeOnce: true
3168
            
3169
            });
3170
        
3171
        
3172
            /**
3173
            * @attribute lazyloadmenu
3174
            * @description Boolean indicating the value to set for the 
3175
            * <a href="YAHOO.widget.Menu.html#lazyLoad">"lazyload"</a>
3176
            * configuration property of the button's menu.  Setting 
3177
            * "lazyloadmenu" to <code>true </code> will defer rendering of 
3178
            * the button's menu until the first time it is made visible.  
3179
            * If "lazyloadmenu" is set to <code>false</code>, the button's 
3180
            * menu will be rendered immediately if the button is in the 
3181
            * document, or in response to the button's "appendTo" event if 
3182
            * the button is not yet in the document.  In either case, the 
3183
            * menu is rendered into the button's parent HTML element.  
3184
            * <em>This attribute does not apply if a 
3185
            * <a href="YAHOO.widget.