~jstys-z/helioviewer.org/client5

« back to all changes in this revision

Viewing changes to lib/yui/build/container/container.js

  • Committer: V. Keith Hughitt
  • Date: 2008-06-11 19:37:01 UTC
  • Revision ID: hughitt1@kore-20080611193701-ddjd2nkey4ohmyam
nightly build 06-11-2008: spring cleaning.. preparing for multi-tiered construction of layer entries and their options

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
Copyright (c) 2008, Yahoo! Inc. All rights reserved.
3
 
Code licensed under the BSD License:
4
 
http://developer.yahoo.net/yui/license.txt
5
 
version: 2.5.0
6
 
*/
7
 
(function () {
8
 
 
9
 
    /**
10
 
    * Config is a utility used within an Object to allow the implementer to
11
 
    * maintain a list of local configuration properties and listen for changes 
12
 
    * to those properties dynamically using CustomEvent. The initial values are 
13
 
    * also maintained so that the configuration can be reset at any given point 
14
 
    * to its initial state.
15
 
    * @namespace YAHOO.util
16
 
    * @class Config
17
 
    * @constructor
18
 
    * @param {Object} owner The owner Object to which this Config Object belongs
19
 
    */
20
 
    YAHOO.util.Config = function (owner) {
21
 
 
22
 
        if (owner) {
23
 
            this.init(owner);
24
 
        }
25
 
 
26
 
 
27
 
    };
28
 
 
29
 
 
30
 
    var Lang = YAHOO.lang,
31
 
        CustomEvent = YAHOO.util.CustomEvent,
32
 
        Config = YAHOO.util.Config;
33
 
 
34
 
 
35
 
    /**
36
 
     * Constant representing the CustomEvent type for the config changed event.
37
 
     * @property YAHOO.util.Config.CONFIG_CHANGED_EVENT
38
 
     * @private
39
 
     * @static
40
 
     * @final
41
 
     */
42
 
    Config.CONFIG_CHANGED_EVENT = "configChanged";
43
 
    
44
 
    /**
45
 
     * Constant representing the boolean type string
46
 
     * @property YAHOO.util.Config.BOOLEAN_TYPE
47
 
     * @private
48
 
     * @static
49
 
     * @final
50
 
     */
51
 
    Config.BOOLEAN_TYPE = "boolean";
52
 
    
53
 
    Config.prototype = {
54
 
     
55
 
        /**
56
 
        * Object reference to the owner of this Config Object
57
 
        * @property owner
58
 
        * @type Object
59
 
        */
60
 
        owner: null,
61
 
        
62
 
        /**
63
 
        * Boolean flag that specifies whether a queue is currently 
64
 
        * being executed
65
 
        * @property queueInProgress
66
 
        * @type Boolean
67
 
        */
68
 
        queueInProgress: false,
69
 
        
70
 
        /**
71
 
        * Maintains the local collection of configuration property objects and 
72
 
        * their specified values
73
 
        * @property config
74
 
        * @private
75
 
        * @type Object
76
 
        */ 
77
 
        config: null,
78
 
        
79
 
        /**
80
 
        * Maintains the local collection of configuration property objects as 
81
 
        * they were initially applied.
82
 
        * This object is used when resetting a property.
83
 
        * @property initialConfig
84
 
        * @private
85
 
        * @type Object
86
 
        */ 
87
 
        initialConfig: null,
88
 
        
89
 
        /**
90
 
        * Maintains the local, normalized CustomEvent queue
91
 
        * @property eventQueue
92
 
        * @private
93
 
        * @type Object
94
 
        */ 
95
 
        eventQueue: null,
96
 
        
97
 
        /**
98
 
        * Custom Event, notifying subscribers when Config properties are set 
99
 
        * (setProperty is called without the silent flag
100
 
        * @event configChangedEvent
101
 
        */
102
 
        configChangedEvent: null,
103
 
    
104
 
        /**
105
 
        * Initializes the configuration Object and all of its local members.
106
 
        * @method init
107
 
        * @param {Object} owner The owner Object to which this Config 
108
 
        * Object belongs
109
 
        */
110
 
        init: function (owner) {
111
 
    
112
 
            this.owner = owner;
113
 
    
114
 
            this.configChangedEvent = 
115
 
                this.createEvent(Config.CONFIG_CHANGED_EVENT);
116
 
    
117
 
            this.configChangedEvent.signature = CustomEvent.LIST;
118
 
            this.queueInProgress = false;
119
 
            this.config = {};
120
 
            this.initialConfig = {};
121
 
            this.eventQueue = [];
122
 
        
123
 
        },
124
 
        
125
 
        /**
126
 
        * Validates that the value passed in is a Boolean.
127
 
        * @method checkBoolean
128
 
        * @param {Object} val The value to validate
129
 
        * @return {Boolean} true, if the value is valid
130
 
        */ 
131
 
        checkBoolean: function (val) {
132
 
            return (typeof val == Config.BOOLEAN_TYPE);
133
 
        },
134
 
        
135
 
        /**
136
 
        * Validates that the value passed in is a number.
137
 
        * @method checkNumber
138
 
        * @param {Object} val The value to validate
139
 
        * @return {Boolean} true, if the value is valid
140
 
        */
141
 
        checkNumber: function (val) {
142
 
            return (!isNaN(val));
143
 
        },
144
 
        
145
 
        /**
146
 
        * Fires a configuration property event using the specified value. 
147
 
        * @method fireEvent
148
 
        * @private
149
 
        * @param {String} key The configuration property's name
150
 
        * @param {value} Object The value of the correct type for the property
151
 
        */ 
152
 
        fireEvent: function ( key, value ) {
153
 
            var property = this.config[key];
154
 
        
155
 
            if (property && property.event) {
156
 
                property.event.fire(value);
157
 
            } 
158
 
        },
159
 
        
160
 
        /**
161
 
        * Adds a property to the Config Object's private config hash.
162
 
        * @method addProperty
163
 
        * @param {String} key The configuration property's name
164
 
        * @param {Object} propertyObject The Object containing all of this 
165
 
        * property's arguments
166
 
        */
167
 
        addProperty: function ( key, propertyObject ) {
168
 
            key = key.toLowerCase();
169
 
        
170
 
            this.config[key] = propertyObject;
171
 
        
172
 
            propertyObject.event = this.createEvent(key, { scope: this.owner });
173
 
            propertyObject.event.signature = CustomEvent.LIST;
174
 
            
175
 
            
176
 
            propertyObject.key = key;
177
 
        
178
 
            if (propertyObject.handler) {
179
 
                propertyObject.event.subscribe(propertyObject.handler, 
180
 
                    this.owner);
181
 
            }
182
 
        
183
 
            this.setProperty(key, propertyObject.value, true);
184
 
            
185
 
            if (! propertyObject.suppressEvent) {
186
 
                this.queueProperty(key, propertyObject.value);
187
 
            }
188
 
            
189
 
        },
190
 
        
191
 
        /**
192
 
        * Returns a key-value configuration map of the values currently set in  
193
 
        * the Config Object.
194
 
        * @method getConfig
195
 
        * @return {Object} The current config, represented in a key-value map
196
 
        */
197
 
        getConfig: function () {
198
 
        
199
 
            var cfg = {},
200
 
                prop,
201
 
                property;
202
 
                
203
 
            for (prop in this.config) {
204
 
                property = this.config[prop];
205
 
                if (property && property.event) {
206
 
                    cfg[prop] = property.value;
207
 
                }
208
 
            }
209
 
            
210
 
            return cfg;
211
 
        },
212
 
        
213
 
        /**
214
 
        * Returns the value of specified property.
215
 
        * @method getProperty
216
 
        * @param {String} key The name of the property
217
 
        * @return {Object}  The value of the specified property
218
 
        */
219
 
        getProperty: function (key) {
220
 
            var property = this.config[key.toLowerCase()];
221
 
            if (property && property.event) {
222
 
                return property.value;
223
 
            } else {
224
 
                return undefined;
225
 
            }
226
 
        },
227
 
        
228
 
        /**
229
 
        * Resets the specified property's value to its initial value.
230
 
        * @method resetProperty
231
 
        * @param {String} key The name of the property
232
 
        * @return {Boolean} True is the property was reset, false if not
233
 
        */
234
 
        resetProperty: function (key) {
235
 
    
236
 
            key = key.toLowerCase();
237
 
        
238
 
            var property = this.config[key];
239
 
    
240
 
            if (property && property.event) {
241
 
    
242
 
                if (this.initialConfig[key] && 
243
 
                    !Lang.isUndefined(this.initialConfig[key])) {
244
 
    
245
 
                    this.setProperty(key, this.initialConfig[key]);
246
 
 
247
 
                    return true;
248
 
    
249
 
                }
250
 
    
251
 
            } else {
252
 
    
253
 
                return false;
254
 
            }
255
 
    
256
 
        },
257
 
        
258
 
        /**
259
 
        * Sets the value of a property. If the silent property is passed as 
260
 
        * true, the property's event will not be fired.
261
 
        * @method setProperty
262
 
        * @param {String} key The name of the property
263
 
        * @param {String} value The value to set the property to
264
 
        * @param {Boolean} silent Whether the value should be set silently, 
265
 
        * without firing the property event.
266
 
        * @return {Boolean} True, if the set was successful, false if it failed.
267
 
        */
268
 
        setProperty: function (key, value, silent) {
269
 
        
270
 
            var property;
271
 
        
272
 
            key = key.toLowerCase();
273
 
        
274
 
            if (this.queueInProgress && ! silent) {
275
 
                // Currently running through a queue... 
276
 
                this.queueProperty(key,value);
277
 
                return true;
278
 
    
279
 
            } else {
280
 
                property = this.config[key];
281
 
                if (property && property.event) {
282
 
                    if (property.validator && !property.validator(value)) {
283
 
                        return false;
284
 
                    } else {
285
 
                        property.value = value;
286
 
                        if (! silent) {
287
 
                            this.fireEvent(key, value);
288
 
                            this.configChangedEvent.fire([key, value]);
289
 
                        }
290
 
                        return true;
291
 
                    }
292
 
                } else {
293
 
                    return false;
294
 
                }
295
 
            }
296
 
        },
297
 
        
298
 
        /**
299
 
        * Sets the value of a property and queues its event to execute. If the 
300
 
        * event is already scheduled to execute, it is
301
 
        * moved from its current position to the end of the queue.
302
 
        * @method queueProperty
303
 
        * @param {String} key The name of the property
304
 
        * @param {String} value The value to set the property to
305
 
        * @return {Boolean}  true, if the set was successful, false if 
306
 
        * it failed.
307
 
        */ 
308
 
        queueProperty: function (key, value) {
309
 
        
310
 
            key = key.toLowerCase();
311
 
        
312
 
            var property = this.config[key],
313
 
                foundDuplicate = false,
314
 
                iLen,
315
 
                queueItem,
316
 
                queueItemKey,
317
 
                queueItemValue,
318
 
                sLen,
319
 
                supercedesCheck,
320
 
                qLen,
321
 
                queueItemCheck,
322
 
                queueItemCheckKey,
323
 
                queueItemCheckValue,
324
 
                i,
325
 
                s,
326
 
                q;
327
 
                                
328
 
            if (property && property.event) {
329
 
    
330
 
                if (!Lang.isUndefined(value) && property.validator && 
331
 
                    !property.validator(value)) { // validator
332
 
                    return false;
333
 
                } else {
334
 
        
335
 
                    if (!Lang.isUndefined(value)) {
336
 
                        property.value = value;
337
 
                    } else {
338
 
                        value = property.value;
339
 
                    }
340
 
        
341
 
                    foundDuplicate = false;
342
 
                    iLen = this.eventQueue.length;
343
 
        
344
 
                    for (i = 0; i < iLen; i++) {
345
 
                        queueItem = this.eventQueue[i];
346
 
        
347
 
                        if (queueItem) {
348
 
                            queueItemKey = queueItem[0];
349
 
                            queueItemValue = queueItem[1];
350
 
 
351
 
                            if (queueItemKey == key) {
352
 
    
353
 
                                /*
354
 
                                    found a dupe... push to end of queue, null 
355
 
                                    current item, and break
356
 
                                */
357
 
    
358
 
                                this.eventQueue[i] = null;
359
 
    
360
 
                                this.eventQueue.push(
361
 
                                    [key, (!Lang.isUndefined(value) ? 
362
 
                                    value : queueItemValue)]);
363
 
    
364
 
                                foundDuplicate = true;
365
 
                                break;
366
 
                            }
367
 
                        }
368
 
                    }
369
 
                    
370
 
                    // this is a refire, or a new property in the queue
371
 
    
372
 
                    if (! foundDuplicate && !Lang.isUndefined(value)) { 
373
 
                        this.eventQueue.push([key, value]);
374
 
                    }
375
 
                }
376
 
        
377
 
                if (property.supercedes) {
378
 
 
379
 
                    sLen = property.supercedes.length;
380
 
 
381
 
                    for (s = 0; s < sLen; s++) {
382
 
 
383
 
                        supercedesCheck = property.supercedes[s];
384
 
                        qLen = this.eventQueue.length;
385
 
 
386
 
                        for (q = 0; q < qLen; q++) {
387
 
                            queueItemCheck = this.eventQueue[q];
388
 
 
389
 
                            if (queueItemCheck) {
390
 
                                queueItemCheckKey = queueItemCheck[0];
391
 
                                queueItemCheckValue = queueItemCheck[1];
392
 
 
393
 
                                if (queueItemCheckKey == 
394
 
                                    supercedesCheck.toLowerCase() ) {
395
 
 
396
 
                                    this.eventQueue.push([queueItemCheckKey, 
397
 
                                        queueItemCheckValue]);
398
 
 
399
 
                                    this.eventQueue[q] = null;
400
 
                                    break;
401
 
 
402
 
                                }
403
 
                            }
404
 
                        }
405
 
                    }
406
 
                }
407
 
 
408
 
 
409
 
                return true;
410
 
            } else {
411
 
                return false;
412
 
            }
413
 
        },
414
 
        
415
 
        /**
416
 
        * Fires the event for a property using the property's current value.
417
 
        * @method refireEvent
418
 
        * @param {String} key The name of the property
419
 
        */
420
 
        refireEvent: function (key) {
421
 
    
422
 
            key = key.toLowerCase();
423
 
        
424
 
            var property = this.config[key];
425
 
    
426
 
            if (property && property.event && 
427
 
    
428
 
                !Lang.isUndefined(property.value)) {
429
 
    
430
 
                if (this.queueInProgress) {
431
 
    
432
 
                    this.queueProperty(key);
433
 
    
434
 
                } else {
435
 
    
436
 
                    this.fireEvent(key, property.value);
437
 
    
438
 
                }
439
 
    
440
 
            }
441
 
        },
442
 
        
443
 
        /**
444
 
        * Applies a key-value Object literal to the configuration, replacing  
445
 
        * any existing values, and queueing the property events.
446
 
        * Although the values will be set, fireQueue() must be called for their 
447
 
        * associated events to execute.
448
 
        * @method applyConfig
449
 
        * @param {Object} userConfig The configuration Object literal
450
 
        * @param {Boolean} init  When set to true, the initialConfig will 
451
 
        * be set to the userConfig passed in, so that calling a reset will 
452
 
        * reset the properties to the passed values.
453
 
        */
454
 
        applyConfig: function (userConfig, init) {
455
 
        
456
 
            var sKey,
457
 
                oConfig;
458
 
 
459
 
            if (init) {
460
 
                oConfig = {};
461
 
                for (sKey in userConfig) {
462
 
                    if (Lang.hasOwnProperty(userConfig, sKey)) {
463
 
                        oConfig[sKey.toLowerCase()] = userConfig[sKey];
464
 
                    }
465
 
                }
466
 
                this.initialConfig = oConfig;
467
 
            }
468
 
 
469
 
            for (sKey in userConfig) {
470
 
                if (Lang.hasOwnProperty(userConfig, sKey)) {
471
 
                    this.queueProperty(sKey, userConfig[sKey]);
472
 
                }
473
 
            }
474
 
        },
475
 
        
476
 
        /**
477
 
        * Refires the events for all configuration properties using their 
478
 
        * current values.
479
 
        * @method refresh
480
 
        */
481
 
        refresh: function () {
482
 
        
483
 
            var prop;
484
 
        
485
 
            for (prop in this.config) {
486
 
                this.refireEvent(prop);
487
 
            }
488
 
        },
489
 
        
490
 
        /**
491
 
        * Fires the normalized list of queued property change events
492
 
        * @method fireQueue
493
 
        */
494
 
        fireQueue: function () {
495
 
        
496
 
            var i, 
497
 
                queueItem,
498
 
                key,
499
 
                value,
500
 
                property;
501
 
        
502
 
            this.queueInProgress = true;
503
 
            for (i = 0;i < this.eventQueue.length; i++) {
504
 
                queueItem = this.eventQueue[i];
505
 
                if (queueItem) {
506
 
        
507
 
                    key = queueItem[0];
508
 
                    value = queueItem[1];
509
 
                    property = this.config[key];
510
 
        
511
 
                    property.value = value;
512
 
        
513
 
                    this.fireEvent(key,value);
514
 
                }
515
 
            }
516
 
            
517
 
            this.queueInProgress = false;
518
 
            this.eventQueue = [];
519
 
        },
520
 
        
521
 
        /**
522
 
        * Subscribes an external handler to the change event for any 
523
 
        * given property. 
524
 
        * @method subscribeToConfigEvent
525
 
        * @param {String} key The property name
526
 
        * @param {Function} handler The handler function to use subscribe to 
527
 
        * the property's event
528
 
        * @param {Object} obj The Object to use for scoping the event handler 
529
 
        * (see CustomEvent documentation)
530
 
        * @param {Boolean} override Optional. If true, will override "this"  
531
 
        * within the handler to map to the scope Object passed into the method.
532
 
        * @return {Boolean} True, if the subscription was successful, 
533
 
        * otherwise false.
534
 
        */ 
535
 
        subscribeToConfigEvent: function (key, handler, obj, override) {
536
 
    
537
 
            var property = this.config[key.toLowerCase()];
538
 
    
539
 
            if (property && property.event) {
540
 
                if (!Config.alreadySubscribed(property.event, handler, obj)) {
541
 
                    property.event.subscribe(handler, obj, override);
542
 
                }
543
 
                return true;
544
 
            } else {
545
 
                return false;
546
 
            }
547
 
    
548
 
        },
549
 
        
550
 
        /**
551
 
        * Unsubscribes an external handler from the change event for any 
552
 
        * given property. 
553
 
        * @method unsubscribeFromConfigEvent
554
 
        * @param {String} key The property name
555
 
        * @param {Function} handler The handler function to use subscribe to 
556
 
        * the property's event
557
 
        * @param {Object} obj The Object to use for scoping the event 
558
 
        * handler (see CustomEvent documentation)
559
 
        * @return {Boolean} True, if the unsubscription was successful, 
560
 
        * otherwise false.
561
 
        */
562
 
        unsubscribeFromConfigEvent: function (key, handler, obj) {
563
 
            var property = this.config[key.toLowerCase()];
564
 
            if (property && property.event) {
565
 
                return property.event.unsubscribe(handler, obj);
566
 
            } else {
567
 
                return false;
568
 
            }
569
 
        },
570
 
        
571
 
        /**
572
 
        * Returns a string representation of the Config object
573
 
        * @method toString
574
 
        * @return {String} The Config object in string format.
575
 
        */
576
 
        toString: function () {
577
 
            var output = "Config";
578
 
            if (this.owner) {
579
 
                output += " [" + this.owner.toString() + "]";
580
 
            }
581
 
            return output;
582
 
        },
583
 
        
584
 
        /**
585
 
        * Returns a string representation of the Config object's current 
586
 
        * CustomEvent queue
587
 
        * @method outputEventQueue
588
 
        * @return {String} The string list of CustomEvents currently queued 
589
 
        * for execution
590
 
        */
591
 
        outputEventQueue: function () {
592
 
 
593
 
            var output = "",
594
 
                queueItem,
595
 
                q,
596
 
                nQueue = this.eventQueue.length;
597
 
              
598
 
            for (q = 0; q < nQueue; q++) {
599
 
                queueItem = this.eventQueue[q];
600
 
                if (queueItem) {
601
 
                    output += queueItem[0] + "=" + queueItem[1] + ", ";
602
 
                }
603
 
            }
604
 
            return output;
605
 
        },
606
 
 
607
 
        /**
608
 
        * Sets all properties to null, unsubscribes all listeners from each 
609
 
        * property's change event and all listeners from the configChangedEvent.
610
 
        * @method destroy
611
 
        */
612
 
        destroy: function () {
613
 
 
614
 
            var oConfig = this.config,
615
 
                sProperty,
616
 
                oProperty;
617
 
 
618
 
 
619
 
            for (sProperty in oConfig) {
620
 
            
621
 
                if (Lang.hasOwnProperty(oConfig, sProperty)) {
622
 
 
623
 
                    oProperty = oConfig[sProperty];
624
 
 
625
 
                    oProperty.event.unsubscribeAll();
626
 
                    oProperty.event = null;
627
 
 
628
 
                }
629
 
            
630
 
            }
631
 
            
632
 
            this.configChangedEvent.unsubscribeAll();
633
 
            
634
 
            this.configChangedEvent = null;
635
 
            this.owner = null;
636
 
            this.config = null;
637
 
            this.initialConfig = null;
638
 
            this.eventQueue = null;
639
 
        
640
 
        }
641
 
 
642
 
    };
643
 
    
644
 
    
645
 
    
646
 
    /**
647
 
    * Checks to determine if a particular function/Object pair are already 
648
 
    * subscribed to the specified CustomEvent
649
 
    * @method YAHOO.util.Config.alreadySubscribed
650
 
    * @static
651
 
    * @param {YAHOO.util.CustomEvent} evt The CustomEvent for which to check 
652
 
    * the subscriptions
653
 
    * @param {Function} fn The function to look for in the subscribers list
654
 
    * @param {Object} obj The execution scope Object for the subscription
655
 
    * @return {Boolean} true, if the function/Object pair is already subscribed 
656
 
    * to the CustomEvent passed in
657
 
    */
658
 
    Config.alreadySubscribed = function (evt, fn, obj) {
659
 
    
660
 
        var nSubscribers = evt.subscribers.length,
661
 
            subsc,
662
 
            i;
663
 
 
664
 
        if (nSubscribers > 0) {
665
 
            i = nSubscribers - 1;
666
 
            do {
667
 
                subsc = evt.subscribers[i];
668
 
                if (subsc && subsc.obj == obj && subsc.fn == fn) {
669
 
                    return true;
670
 
                }
671
 
            }
672
 
            while (i--);
673
 
        }
674
 
 
675
 
        return false;
676
 
 
677
 
    };
678
 
 
679
 
    YAHOO.lang.augmentProto(Config, YAHOO.util.EventProvider);
680
 
 
681
 
}());
682
 
 
683
 
(function () {
684
 
 
685
 
    /**
686
 
    * The Container family of components is designed to enable developers to 
687
 
    * create different kinds of content-containing modules on the web. Module 
688
 
    * and Overlay are the most basic containers, and they can be used directly 
689
 
    * or extended to build custom containers. Also part of the Container family 
690
 
    * are four UI controls that extend Module and Overlay: Tooltip, Panel, 
691
 
    * Dialog, and SimpleDialog.
692
 
    * @module container
693
 
    * @title Container
694
 
    * @requires yahoo, dom, event 
695
 
    * @optional dragdrop, animation, button
696
 
    */
697
 
    
698
 
    /**
699
 
    * Module is a JavaScript representation of the Standard Module Format. 
700
 
    * Standard Module Format is a simple standard for markup containers where 
701
 
    * child nodes representing the header, body, and footer of the content are 
702
 
    * denoted using the CSS classes "hd", "bd", and "ft" respectively. 
703
 
    * Module is the base class for all other classes in the YUI 
704
 
    * Container package.
705
 
    * @namespace YAHOO.widget
706
 
    * @class Module
707
 
    * @constructor
708
 
    * @param {String} el The element ID representing the Module <em>OR</em>
709
 
    * @param {HTMLElement} el The element representing the Module
710
 
    * @param {Object} userConfig The configuration Object literal containing 
711
 
    * the configuration that should be set for this module. See configuration 
712
 
    * documentation for more details.
713
 
    */
714
 
    YAHOO.widget.Module = function (el, userConfig) {
715
 
        if (el) {
716
 
            this.init(el, userConfig);
717
 
        } else {
718
 
        }
719
 
    };
720
 
 
721
 
    var Dom = YAHOO.util.Dom,
722
 
        Config = YAHOO.util.Config,
723
 
        Event = YAHOO.util.Event,
724
 
        CustomEvent = YAHOO.util.CustomEvent,
725
 
        Module = YAHOO.widget.Module,
726
 
 
727
 
        m_oModuleTemplate,
728
 
        m_oHeaderTemplate,
729
 
        m_oBodyTemplate,
730
 
        m_oFooterTemplate,
731
 
 
732
 
        /**
733
 
        * Constant representing the name of the Module's events
734
 
        * @property EVENT_TYPES
735
 
        * @private
736
 
        * @final
737
 
        * @type Object
738
 
        */
739
 
        EVENT_TYPES = {
740
 
        
741
 
            "BEFORE_INIT": "beforeInit",
742
 
            "INIT": "init",
743
 
            "APPEND": "append",
744
 
            "BEFORE_RENDER": "beforeRender",
745
 
            "RENDER": "render",
746
 
            "CHANGE_HEADER": "changeHeader",
747
 
            "CHANGE_BODY": "changeBody",
748
 
            "CHANGE_FOOTER": "changeFooter",
749
 
            "CHANGE_CONTENT": "changeContent",
750
 
            "DESTORY": "destroy",
751
 
            "BEFORE_SHOW": "beforeShow",
752
 
            "SHOW": "show",
753
 
            "BEFORE_HIDE": "beforeHide",
754
 
            "HIDE": "hide"
755
 
        
756
 
        },
757
 
            
758
 
        /**
759
 
        * Constant representing the Module's configuration properties
760
 
        * @property DEFAULT_CONFIG
761
 
        * @private
762
 
        * @final
763
 
        * @type Object
764
 
        */
765
 
        DEFAULT_CONFIG = {
766
 
        
767
 
            "VISIBLE": { 
768
 
                key: "visible", 
769
 
                value: true, 
770
 
                validator: YAHOO.lang.isBoolean 
771
 
            },
772
 
        
773
 
            "EFFECT": { 
774
 
                key: "effect", 
775
 
                suppressEvent: true, 
776
 
                supercedes: ["visible"] 
777
 
            },
778
 
 
779
 
            "MONITOR_RESIZE": { 
780
 
                key: "monitorresize", 
781
 
                value: true  
782
 
            },
783
 
 
784
 
            "APPEND_TO_DOCUMENT_BODY": { 
785
 
                key: "appendtodocumentbody", 
786
 
                value: false
787
 
            }
788
 
        };
789
 
    
790
 
    /**
791
 
    * Constant representing the prefix path to use for non-secure images
792
 
    * @property YAHOO.widget.Module.IMG_ROOT
793
 
    * @static
794
 
    * @final
795
 
    * @type String
796
 
    */
797
 
    Module.IMG_ROOT = null;
798
 
    
799
 
    /**
800
 
    * Constant representing the prefix path to use for securely served images
801
 
    * @property YAHOO.widget.Module.IMG_ROOT_SSL
802
 
    * @static
803
 
    * @final
804
 
    * @type String
805
 
    */
806
 
    Module.IMG_ROOT_SSL = null;
807
 
    
808
 
    /**
809
 
    * Constant for the default CSS class name that represents a Module
810
 
    * @property YAHOO.widget.Module.CSS_MODULE
811
 
    * @static
812
 
    * @final
813
 
    * @type String
814
 
    */
815
 
    Module.CSS_MODULE = "yui-module";
816
 
    
817
 
    /**
818
 
    * Constant representing the module header
819
 
    * @property YAHOO.widget.Module.CSS_HEADER
820
 
    * @static
821
 
    * @final
822
 
    * @type String
823
 
    */
824
 
    Module.CSS_HEADER = "hd";
825
 
    
826
 
    /**
827
 
    * Constant representing the module body
828
 
    * @property YAHOO.widget.Module.CSS_BODY
829
 
    * @static
830
 
    * @final
831
 
    * @type String
832
 
    */
833
 
    Module.CSS_BODY = "bd";
834
 
    
835
 
    /**
836
 
    * Constant representing the module footer
837
 
    * @property YAHOO.widget.Module.CSS_FOOTER
838
 
    * @static
839
 
    * @final
840
 
    * @type String
841
 
    */
842
 
    Module.CSS_FOOTER = "ft";
843
 
    
844
 
    /**
845
 
    * Constant representing the url for the "src" attribute of the iframe 
846
 
    * used to monitor changes to the browser's base font size
847
 
    * @property YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL
848
 
    * @static
849
 
    * @final
850
 
    * @type String
851
 
    */
852
 
    Module.RESIZE_MONITOR_SECURE_URL = "javascript:false;";
853
 
    
854
 
    /**
855
 
    * Singleton CustomEvent fired when the font size is changed in the browser.
856
 
    * Opera's "zoom" functionality currently does not support text 
857
 
    * size detection.
858
 
    * @event YAHOO.widget.Module.textResizeEvent
859
 
    */
860
 
    Module.textResizeEvent = new CustomEvent("textResize");
861
 
 
862
 
    function createModuleTemplate() {
863
 
 
864
 
        if (!m_oModuleTemplate) {
865
 
            m_oModuleTemplate = document.createElement("div");
866
 
            
867
 
            m_oModuleTemplate.innerHTML = ("<div class=\"" + 
868
 
                Module.CSS_HEADER + "\"></div>" + "<div class=\"" + 
869
 
                Module.CSS_BODY + "\"></div><div class=\"" + 
870
 
                Module.CSS_FOOTER + "\"></div>");
871
 
 
872
 
            m_oHeaderTemplate = m_oModuleTemplate.firstChild;
873
 
            m_oBodyTemplate = m_oHeaderTemplate.nextSibling;
874
 
            m_oFooterTemplate = m_oBodyTemplate.nextSibling;
875
 
        }
876
 
 
877
 
        return m_oModuleTemplate;
878
 
    }
879
 
 
880
 
    function createHeader() {
881
 
        if (!m_oHeaderTemplate) {
882
 
            createModuleTemplate();
883
 
        }
884
 
        return (m_oHeaderTemplate.cloneNode(false));
885
 
    }
886
 
 
887
 
    function createBody() {
888
 
        if (!m_oBodyTemplate) {
889
 
            createModuleTemplate();
890
 
        }
891
 
        return (m_oBodyTemplate.cloneNode(false));
892
 
    }
893
 
 
894
 
    function createFooter() {
895
 
        if (!m_oFooterTemplate) {
896
 
            createModuleTemplate();
897
 
        }
898
 
        return (m_oFooterTemplate.cloneNode(false));
899
 
    }
900
 
 
901
 
    Module.prototype = {
902
 
 
903
 
        /**
904
 
        * The class's constructor function
905
 
        * @property contructor
906
 
        * @type Function
907
 
        */
908
 
        constructor: Module,
909
 
        
910
 
        /**
911
 
        * The main module element that contains the header, body, and footer
912
 
        * @property element
913
 
        * @type HTMLElement
914
 
        */
915
 
        element: null,
916
 
 
917
 
        /**
918
 
        * The header element, denoted with CSS class "hd"
919
 
        * @property header
920
 
        * @type HTMLElement
921
 
        */
922
 
        header: null,
923
 
 
924
 
        /**
925
 
        * The body element, denoted with CSS class "bd"
926
 
        * @property body
927
 
        * @type HTMLElement
928
 
        */
929
 
        body: null,
930
 
 
931
 
        /**
932
 
        * The footer element, denoted with CSS class "ft"
933
 
        * @property footer
934
 
        * @type HTMLElement
935
 
        */
936
 
        footer: null,
937
 
 
938
 
        /**
939
 
        * The id of the element
940
 
        * @property id
941
 
        * @type String
942
 
        */
943
 
        id: null,
944
 
 
945
 
        /**
946
 
        * A string representing the root path for all images created by
947
 
        * a Module instance.
948
 
        * @deprecated It is recommend that any images for a Module be applied
949
 
        * via CSS using the "background-image" property.
950
 
        * @property imageRoot
951
 
        * @type String
952
 
        */
953
 
        imageRoot: Module.IMG_ROOT,
954
 
 
955
 
        /**
956
 
        * Initializes the custom events for Module which are fired 
957
 
        * automatically at appropriate times by the Module class.
958
 
        * @method initEvents
959
 
        */
960
 
        initEvents: function () {
961
 
 
962
 
            var SIGNATURE = CustomEvent.LIST;
963
 
 
964
 
            /**
965
 
            * CustomEvent fired prior to class initalization.
966
 
            * @event beforeInitEvent
967
 
            * @param {class} classRef class reference of the initializing 
968
 
            * class, such as this.beforeInitEvent.fire(Module)
969
 
            */
970
 
            this.beforeInitEvent = this.createEvent(EVENT_TYPES.BEFORE_INIT);
971
 
            this.beforeInitEvent.signature = SIGNATURE;
972
 
 
973
 
            /**
974
 
            * CustomEvent fired after class initalization.
975
 
            * @event initEvent
976
 
            * @param {class} classRef class reference of the initializing 
977
 
            * class, such as this.beforeInitEvent.fire(Module)
978
 
            */  
979
 
            this.initEvent = this.createEvent(EVENT_TYPES.INIT);
980
 
            this.initEvent.signature = SIGNATURE;
981
 
 
982
 
            /**
983
 
            * CustomEvent fired when the Module is appended to the DOM
984
 
            * @event appendEvent
985
 
            */
986
 
            this.appendEvent = this.createEvent(EVENT_TYPES.APPEND);
987
 
            this.appendEvent.signature = SIGNATURE;
988
 
 
989
 
            /**
990
 
            * CustomEvent fired before the Module is rendered
991
 
            * @event beforeRenderEvent
992
 
            */
993
 
            this.beforeRenderEvent = this.createEvent(EVENT_TYPES.BEFORE_RENDER);
994
 
            this.beforeRenderEvent.signature = SIGNATURE;
995
 
        
996
 
            /**
997
 
            * CustomEvent fired after the Module is rendered
998
 
            * @event renderEvent
999
 
            */
1000
 
            this.renderEvent = this.createEvent(EVENT_TYPES.RENDER);
1001
 
            this.renderEvent.signature = SIGNATURE;
1002
 
        
1003
 
            /**
1004
 
            * CustomEvent fired when the header content of the Module 
1005
 
            * is modified
1006
 
            * @event changeHeaderEvent
1007
 
            * @param {String/HTMLElement} content String/element representing 
1008
 
            * the new header content
1009
 
            */
1010
 
            this.changeHeaderEvent = this.createEvent(EVENT_TYPES.CHANGE_HEADER);
1011
 
            this.changeHeaderEvent.signature = SIGNATURE;
1012
 
            
1013
 
            /**
1014
 
            * CustomEvent fired when the body content of the Module is modified
1015
 
            * @event changeBodyEvent
1016
 
            * @param {String/HTMLElement} content String/element representing 
1017
 
            * the new body content
1018
 
            */  
1019
 
            this.changeBodyEvent = this.createEvent(EVENT_TYPES.CHANGE_BODY);
1020
 
            this.changeBodyEvent.signature = SIGNATURE;
1021
 
            
1022
 
            /**
1023
 
            * CustomEvent fired when the footer content of the Module 
1024
 
            * is modified
1025
 
            * @event changeFooterEvent
1026
 
            * @param {String/HTMLElement} content String/element representing 
1027
 
            * the new footer content
1028
 
            */
1029
 
            this.changeFooterEvent = this.createEvent(EVENT_TYPES.CHANGE_FOOTER);
1030
 
            this.changeFooterEvent.signature = SIGNATURE;
1031
 
        
1032
 
            /**
1033
 
            * CustomEvent fired when the content of the Module is modified
1034
 
            * @event changeContentEvent
1035
 
            */
1036
 
            this.changeContentEvent = this.createEvent(EVENT_TYPES.CHANGE_CONTENT);
1037
 
            this.changeContentEvent.signature = SIGNATURE;
1038
 
 
1039
 
            /**
1040
 
            * CustomEvent fired when the Module is destroyed
1041
 
            * @event destroyEvent
1042
 
            */
1043
 
            this.destroyEvent = this.createEvent(EVENT_TYPES.DESTORY);
1044
 
            this.destroyEvent.signature = SIGNATURE;
1045
 
 
1046
 
            /**
1047
 
            * CustomEvent fired before the Module is shown
1048
 
            * @event beforeShowEvent
1049
 
            */
1050
 
            this.beforeShowEvent = this.createEvent(EVENT_TYPES.BEFORE_SHOW);
1051
 
            this.beforeShowEvent.signature = SIGNATURE;
1052
 
 
1053
 
            /**
1054
 
            * CustomEvent fired after the Module is shown
1055
 
            * @event showEvent
1056
 
            */
1057
 
            this.showEvent = this.createEvent(EVENT_TYPES.SHOW);
1058
 
            this.showEvent.signature = SIGNATURE;
1059
 
 
1060
 
            /**
1061
 
            * CustomEvent fired before the Module is hidden
1062
 
            * @event beforeHideEvent
1063
 
            */
1064
 
            this.beforeHideEvent = this.createEvent(EVENT_TYPES.BEFORE_HIDE);
1065
 
            this.beforeHideEvent.signature = SIGNATURE;
1066
 
 
1067
 
            /**
1068
 
            * CustomEvent fired after the Module is hidden
1069
 
            * @event hideEvent
1070
 
            */
1071
 
            this.hideEvent = this.createEvent(EVENT_TYPES.HIDE);
1072
 
            this.hideEvent.signature = SIGNATURE;
1073
 
        }, 
1074
 
 
1075
 
        /**
1076
 
        * String representing the current user-agent platform
1077
 
        * @property platform
1078
 
        * @type String
1079
 
        */
1080
 
        platform: function () {
1081
 
            var ua = navigator.userAgent.toLowerCase();
1082
 
 
1083
 
            if (ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1) {
1084
 
                return "windows";
1085
 
            } else if (ua.indexOf("macintosh") != -1) {
1086
 
                return "mac";
1087
 
            } else {
1088
 
                return false;
1089
 
            }
1090
 
        }(),
1091
 
        
1092
 
        /**
1093
 
        * String representing the user-agent of the browser
1094
 
        * @deprecated Use YAHOO.env.ua
1095
 
        * @property browser
1096
 
        * @type String
1097
 
        */
1098
 
        browser: function () {
1099
 
            var ua = navigator.userAgent.toLowerCase();
1100
 
            /*
1101
 
                 Check Opera first in case of spoof and check Safari before
1102
 
                 Gecko since Safari's user agent string includes "like Gecko"
1103
 
            */
1104
 
            if (ua.indexOf('opera') != -1) { 
1105
 
                return 'opera';
1106
 
            } else if (ua.indexOf('msie 7') != -1) {
1107
 
                return 'ie7';
1108
 
            } else if (ua.indexOf('msie') != -1) {
1109
 
                return 'ie';
1110
 
            } else if (ua.indexOf('safari') != -1) { 
1111
 
                return 'safari';
1112
 
            } else if (ua.indexOf('gecko') != -1) {
1113
 
                return 'gecko';
1114
 
            } else {
1115
 
                return false;
1116
 
            }
1117
 
        }(),
1118
 
        
1119
 
        /**
1120
 
        * Boolean representing whether or not the current browsing context is 
1121
 
        * secure (https)
1122
 
        * @property isSecure
1123
 
        * @type Boolean
1124
 
        */
1125
 
        isSecure: function () {
1126
 
            if (window.location.href.toLowerCase().indexOf("https") === 0) {
1127
 
                return true;
1128
 
            } else {
1129
 
                return false;
1130
 
            }
1131
 
        }(),
1132
 
        
1133
 
        /**
1134
 
        * Initializes the custom events for Module which are fired 
1135
 
        * automatically at appropriate times by the Module class.
1136
 
        */
1137
 
        initDefaultConfig: function () {
1138
 
            // Add properties //
1139
 
            /**
1140
 
            * Specifies whether the Module is visible on the page.
1141
 
            * @config visible
1142
 
            * @type Boolean
1143
 
            * @default true
1144
 
            */
1145
 
            this.cfg.addProperty(DEFAULT_CONFIG.VISIBLE.key, {
1146
 
                handler: this.configVisible, 
1147
 
                value: DEFAULT_CONFIG.VISIBLE.value, 
1148
 
                validator: DEFAULT_CONFIG.VISIBLE.validator
1149
 
            });
1150
 
 
1151
 
            /**
1152
 
            * Object or array of objects representing the ContainerEffect 
1153
 
            * classes that are active for animating the container.
1154
 
            * @config effect
1155
 
            * @type Object
1156
 
            * @default null
1157
 
            */
1158
 
            this.cfg.addProperty(DEFAULT_CONFIG.EFFECT.key, {
1159
 
                suppressEvent: DEFAULT_CONFIG.EFFECT.suppressEvent, 
1160
 
                supercedes: DEFAULT_CONFIG.EFFECT.supercedes
1161
 
            });
1162
 
 
1163
 
            /**
1164
 
            * Specifies whether to create a special proxy iframe to monitor 
1165
 
            * for user font resizing in the document
1166
 
            * @config monitorresize
1167
 
            * @type Boolean
1168
 
            * @default true
1169
 
            */
1170
 
            this.cfg.addProperty(DEFAULT_CONFIG.MONITOR_RESIZE.key, {
1171
 
                handler: this.configMonitorResize,
1172
 
                value: DEFAULT_CONFIG.MONITOR_RESIZE.value
1173
 
            });
1174
 
 
1175
 
            /**
1176
 
            * Specifies if the module should be rendered as the first child 
1177
 
            * of document.body or appended as the last child when render is called
1178
 
            * with document.body as the "appendToNode".
1179
 
            * <p>
1180
 
            * Appending to the body while the DOM is still being constructed can 
1181
 
            * lead to Operation Aborted errors in IE hence this flag is set to 
1182
 
            * false by default.
1183
 
            * </p>
1184
 
            * 
1185
 
            * @config appendtodocumentbody
1186
 
            * @type Boolean
1187
 
            * @default false
1188
 
            */
1189
 
            this.cfg.addProperty(DEFAULT_CONFIG.APPEND_TO_DOCUMENT_BODY.key, {
1190
 
                value: DEFAULT_CONFIG.APPEND_TO_DOCUMENT_BODY.value
1191
 
            });
1192
 
        },
1193
 
 
1194
 
        /**
1195
 
        * The Module class's initialization method, which is executed for
1196
 
        * Module and all of its subclasses. This method is automatically 
1197
 
        * called by the constructor, and  sets up all DOM references for 
1198
 
        * pre-existing markup, and creates required markup if it is not 
1199
 
        * already present.
1200
 
        * @method init
1201
 
        * @param {String} el The element ID representing the Module <em>OR</em>
1202
 
        * @param {HTMLElement} el The element representing the Module
1203
 
        * @param {Object} userConfig The configuration Object literal 
1204
 
        * containing the configuration that should be set for this module. 
1205
 
        * See configuration documentation for more details.
1206
 
        */
1207
 
        init: function (el, userConfig) {
1208
 
 
1209
 
            var elId, child;
1210
 
 
1211
 
            this.initEvents();
1212
 
            this.beforeInitEvent.fire(Module);
1213
 
 
1214
 
            /**
1215
 
            * The Module's Config object used for monitoring 
1216
 
            * configuration properties.
1217
 
            * @property cfg
1218
 
            * @type YAHOO.util.Config
1219
 
            */
1220
 
            this.cfg = new Config(this);
1221
 
 
1222
 
            if (this.isSecure) {
1223
 
                this.imageRoot = Module.IMG_ROOT_SSL;
1224
 
            }
1225
 
 
1226
 
            if (typeof el == "string") {
1227
 
                elId = el;
1228
 
                el = document.getElementById(el);
1229
 
                if (! el) {
1230
 
                    el = (createModuleTemplate()).cloneNode(false);
1231
 
                    el.id = elId;
1232
 
                }
1233
 
            }
1234
 
 
1235
 
            this.element = el;
1236
 
 
1237
 
            if (el.id) {
1238
 
                this.id = el.id;
1239
 
            }
1240
 
 
1241
 
            child = this.element.firstChild;
1242
 
 
1243
 
            if (child) {
1244
 
                var fndHd = false, fndBd = false, fndFt = false;
1245
 
                do {
1246
 
                    // We're looking for elements
1247
 
                    if (1 == child.nodeType) {
1248
 
                        if (!fndHd && Dom.hasClass(child, Module.CSS_HEADER)) {
1249
 
                            this.header = child;
1250
 
                            fndHd = true;
1251
 
                        } else if (!fndBd && Dom.hasClass(child, Module.CSS_BODY)) {
1252
 
                            this.body = child;
1253
 
                            fndBd = true;
1254
 
                        } else if (!fndFt && Dom.hasClass(child, Module.CSS_FOOTER)){
1255
 
                            this.footer = child;
1256
 
                            fndFt = true;
1257
 
                        }
1258
 
                    }
1259
 
                } while ((child = child.nextSibling));
1260
 
            }
1261
 
 
1262
 
            this.initDefaultConfig();
1263
 
 
1264
 
            Dom.addClass(this.element, Module.CSS_MODULE);
1265
 
 
1266
 
            if (userConfig) {
1267
 
                this.cfg.applyConfig(userConfig, true);
1268
 
            }
1269
 
 
1270
 
            /*
1271
 
                Subscribe to the fireQueue() method of Config so that any 
1272
 
                queued configuration changes are excecuted upon render of 
1273
 
                the Module
1274
 
            */ 
1275
 
 
1276
 
            if (!Config.alreadySubscribed(this.renderEvent, this.cfg.fireQueue, this.cfg)) {
1277
 
                this.renderEvent.subscribe(this.cfg.fireQueue, this.cfg, true);
1278
 
            }
1279
 
 
1280
 
            this.initEvent.fire(Module);
1281
 
        },
1282
 
 
1283
 
        /**
1284
 
        * Initialize an empty IFRAME that is placed out of the visible area 
1285
 
        * that can be used to detect text resize.
1286
 
        * @method initResizeMonitor
1287
 
        */
1288
 
        initResizeMonitor: function () {
1289
 
 
1290
 
            var isGeckoWin = (YAHOO.env.ua.gecko && this.platform == "windows");
1291
 
            if (isGeckoWin) {
1292
 
                // Help prevent spinning loading icon which 
1293
 
                // started with FireFox 2.0.0.8/Win
1294
 
                var self = this;
1295
 
                setTimeout(function(){self._initResizeMonitor();}, 0);
1296
 
            } else {
1297
 
                this._initResizeMonitor();
1298
 
            }
1299
 
        },
1300
 
 
1301
 
        /**
1302
 
         * Create and initialize the text resize monitoring iframe.
1303
 
         * 
1304
 
         * @protected
1305
 
         * @method _initResizeMonitor
1306
 
         */
1307
 
        _initResizeMonitor : function() {
1308
 
 
1309
 
            var oDoc, 
1310
 
                oIFrame, 
1311
 
                sHTML;
1312
 
 
1313
 
            function fireTextResize() {
1314
 
                Module.textResizeEvent.fire();
1315
 
            }
1316
 
 
1317
 
            if (!YAHOO.env.ua.opera) {
1318
 
                oIFrame = Dom.get("_yuiResizeMonitor");
1319
 
 
1320
 
                var supportsCWResize = this._supportsCWResize();
1321
 
 
1322
 
                if (!oIFrame) {
1323
 
                    oIFrame = document.createElement("iframe");
1324
 
 
1325
 
                    if (this.isSecure && Module.RESIZE_MONITOR_SECURE_URL && YAHOO.env.ua.ie) {
1326
 
                        oIFrame.src = Module.RESIZE_MONITOR_SECURE_URL;
1327
 
                    }
1328
 
 
1329
 
                    if (!supportsCWResize) {
1330
 
                        // Can't monitor on contentWindow, so fire from inside iframe
1331
 
                        sHTML = ["<html><head><script ",
1332
 
                                 "type=\"text/javascript\">",
1333
 
                                 "window.onresize=function(){window.parent.",
1334
 
                                 "YAHOO.widget.Module.textResizeEvent.",
1335
 
                                 "fire();};<",
1336
 
                                 "\/script></head>",
1337
 
                                 "<body></body></html>"].join('');
1338
 
 
1339
 
                        oIFrame.src = "data:text/html;charset=utf-8," + encodeURIComponent(sHTML);
1340
 
                    }
1341
 
 
1342
 
                    oIFrame.id = "_yuiResizeMonitor";
1343
 
                    /*
1344
 
                        Need to set "position" property before inserting the 
1345
 
                        iframe into the document or Safari's status bar will 
1346
 
                        forever indicate the iframe is loading 
1347
 
                        (See SourceForge bug #1723064)
1348
 
                    */
1349
 
                    oIFrame.style.position = "absolute";
1350
 
                    oIFrame.style.visibility = "hidden";
1351
 
 
1352
 
                    var db = document.body,
1353
 
                        fc = db.firstChild;
1354
 
                    if (fc) {
1355
 
                        db.insertBefore(oIFrame, fc);
1356
 
                    } else {
1357
 
                        db.appendChild(oIFrame);
1358
 
                    }
1359
 
 
1360
 
                    oIFrame.style.width = "10em";
1361
 
                    oIFrame.style.height = "10em";
1362
 
                    oIFrame.style.top = (-1 * oIFrame.offsetHeight) + "px";
1363
 
                    oIFrame.style.left = (-1 * oIFrame.offsetWidth) + "px";
1364
 
                    oIFrame.style.borderWidth = "0";
1365
 
                    oIFrame.style.visibility = "visible";
1366
 
 
1367
 
                    /*
1368
 
                       Don't open/close the document for Gecko like we used to, since it
1369
 
                       leads to duplicate cookies. (See SourceForge bug #1721755)
1370
 
                    */
1371
 
                    if (YAHOO.env.ua.webkit) {
1372
 
                        oDoc = oIFrame.contentWindow.document;
1373
 
                        oDoc.open();
1374
 
                        oDoc.close();
1375
 
                    }
1376
 
                }
1377
 
 
1378
 
                if (oIFrame && oIFrame.contentWindow) {
1379
 
                    Module.textResizeEvent.subscribe(this.onDomResize, this, true);
1380
 
 
1381
 
                    if (!Module.textResizeInitialized) {
1382
 
                        if (supportsCWResize) {
1383
 
                            if (!Event.on(oIFrame.contentWindow, "resize", fireTextResize)) {
1384
 
                                /*
1385
 
                                     This will fail in IE if document.domain has 
1386
 
                                     changed, so we must change the listener to 
1387
 
                                     use the oIFrame element instead
1388
 
                                */
1389
 
                                Event.on(oIFrame, "resize", fireTextResize);
1390
 
                            }
1391
 
                        }
1392
 
                        Module.textResizeInitialized = true;
1393
 
                    }
1394
 
                    this.resizeMonitor = oIFrame;
1395
 
                }
1396
 
            }
1397
 
        },
1398
 
 
1399
 
        /**
1400
 
         * Text resize monitor helper method.
1401
 
         * Determines if the browser supports resize events on iframe content windows.
1402
 
         * 
1403
 
         * @private
1404
 
         * @method _supportsCWResize
1405
 
         */
1406
 
        _supportsCWResize : function() {
1407
 
            /*
1408
 
                Gecko 1.8.0 (FF1.5), 1.8.1.0-5 (FF2) won't fire resize on contentWindow.
1409
 
                Gecko 1.8.1.6+ (FF2.0.0.6+) and all other browsers will fire resize on contentWindow.
1410
 
 
1411
 
                We don't want to start sniffing for patch versions, so fire textResize the same
1412
 
                way on all FF, until 1.9 (3.x) is out
1413
 
             */
1414
 
            var bSupported = true;
1415
 
            if (YAHOO.env.ua.gecko && YAHOO.env.ua.gecko <= 1.8) {
1416
 
                bSupported = false;
1417
 
                /*
1418
 
                var v = navigator.userAgent.match(/rv:([^\s\)]*)/); // From YAHOO.env.ua
1419
 
                if (v && v[0]) {
1420
 
                    var sv = v[0].match(/\d\.\d\.(\d)/);
1421
 
                    if (sv && sv[1]) {
1422
 
                        if (parseInt(sv[1], 10) > 0) {
1423
 
                            bSupported = true;
1424
 
                        }
1425
 
                    }
1426
 
                }
1427
 
                */
1428
 
            }
1429
 
            return bSupported;
1430
 
        },
1431
 
 
1432
 
        /**
1433
 
        * Event handler fired when the resize monitor element is resized.
1434
 
        * @method onDomResize
1435
 
        * @param {DOMEvent} e The DOM resize event
1436
 
        * @param {Object} obj The scope object passed to the handler
1437
 
        */
1438
 
        onDomResize: function (e, obj) {
1439
 
 
1440
 
            var nLeft = -1 * this.resizeMonitor.offsetWidth,
1441
 
                nTop = -1 * this.resizeMonitor.offsetHeight;
1442
 
        
1443
 
            this.resizeMonitor.style.top = nTop + "px";
1444
 
            this.resizeMonitor.style.left =  nLeft + "px";
1445
 
 
1446
 
        },
1447
 
 
1448
 
        /**
1449
 
        * Sets the Module's header content to the string specified, or appends 
1450
 
        * the passed element to the header. If no header is present, one will 
1451
 
        * be automatically created. An empty string can be passed to the method
1452
 
        * to clear the contents of the header.
1453
 
        * 
1454
 
        * @method setHeader
1455
 
        * @param {String} headerContent The string used to set the header.
1456
 
        * As a convenience, non HTMLElement objects can also be passed into 
1457
 
        * the method, and will be treated as strings, with the header innerHTML
1458
 
        * set to their default toString implementations.
1459
 
        * <em>OR</em>
1460
 
        * @param {HTMLElement} headerContent The HTMLElement to append to 
1461
 
        * the header
1462
 
        */
1463
 
        setHeader: function (headerContent) {
1464
 
            var oHeader = this.header || (this.header = createHeader());
1465
 
 
1466
 
            if (headerContent.tagName) {
1467
 
                oHeader.innerHTML = "";
1468
 
                oHeader.appendChild(headerContent);
1469
 
            } else {
1470
 
                oHeader.innerHTML = headerContent;
1471
 
            }
1472
 
 
1473
 
            this.changeHeaderEvent.fire(headerContent);
1474
 
            this.changeContentEvent.fire();
1475
 
 
1476
 
        },
1477
 
 
1478
 
        /**
1479
 
        * Appends the passed element to the header. If no header is present, 
1480
 
        * one will be automatically created.
1481
 
        * @method appendToHeader
1482
 
        * @param {HTMLElement} element The element to append to the header
1483
 
        */
1484
 
        appendToHeader: function (element) {
1485
 
            var oHeader = this.header || (this.header = createHeader());
1486
 
        
1487
 
            oHeader.appendChild(element);
1488
 
 
1489
 
            this.changeHeaderEvent.fire(element);
1490
 
            this.changeContentEvent.fire();
1491
 
 
1492
 
        },
1493
 
 
1494
 
        /**
1495
 
        * Sets the Module's body content to the HTML specified, or appends the
1496
 
        * passed element to the body. If no body is present, one will be 
1497
 
        * automatically created. An empty string can be passed to the method
1498
 
        * to clear the contents of the body.
1499
 
        * @method setBody
1500
 
        * @param {String} bodyContent The HTML used to set the body. 
1501
 
        * As a convenience, non HTMLElement objects can also be passed into 
1502
 
        * the method, and will be treated as strings, with the body innerHTML
1503
 
        * set to their default toString implementations.
1504
 
        * <em>OR</em>
1505
 
        * @param {HTMLElement} bodyContent The HTMLElement to append to the body
1506
 
        */
1507
 
        setBody: function (bodyContent) {
1508
 
            var oBody = this.body || (this.body = createBody());
1509
 
 
1510
 
            if (bodyContent.tagName) {
1511
 
                oBody.innerHTML = "";
1512
 
                oBody.appendChild(bodyContent);
1513
 
            } else {
1514
 
                oBody.innerHTML = bodyContent;
1515
 
            }
1516
 
 
1517
 
            this.changeBodyEvent.fire(bodyContent);
1518
 
            this.changeContentEvent.fire();
1519
 
        },
1520
 
 
1521
 
        /**
1522
 
        * Appends the passed element to the body. If no body is present, one 
1523
 
        * will be automatically created.
1524
 
        * @method appendToBody
1525
 
        * @param {HTMLElement} element The element to append to the body
1526
 
        */
1527
 
        appendToBody: function (element) {
1528
 
            var oBody = this.body || (this.body = createBody());
1529
 
        
1530
 
            oBody.appendChild(element);
1531
 
 
1532
 
            this.changeBodyEvent.fire(element);
1533
 
            this.changeContentEvent.fire();
1534
 
 
1535
 
        },
1536
 
        
1537
 
        /**
1538
 
        * Sets the Module's footer content to the HTML specified, or appends 
1539
 
        * the passed element to the footer. If no footer is present, one will 
1540
 
        * be automatically created. An empty string can be passed to the method
1541
 
        * to clear the contents of the footer.
1542
 
        * @method setFooter
1543
 
        * @param {String} footerContent The HTML used to set the footer 
1544
 
        * As a convenience, non HTMLElement objects can also be passed into 
1545
 
        * the method, and will be treated as strings, with the footer innerHTML
1546
 
        * set to their default toString implementations.
1547
 
        * <em>OR</em>
1548
 
        * @param {HTMLElement} footerContent The HTMLElement to append to 
1549
 
        * the footer
1550
 
        */
1551
 
        setFooter: function (footerContent) {
1552
 
 
1553
 
            var oFooter = this.footer || (this.footer = createFooter());
1554
 
 
1555
 
            if (footerContent.tagName) {
1556
 
                oFooter.innerHTML = "";
1557
 
                oFooter.appendChild(footerContent);
1558
 
            } else {
1559
 
                oFooter.innerHTML = footerContent;
1560
 
            }
1561
 
 
1562
 
            this.changeFooterEvent.fire(footerContent);
1563
 
            this.changeContentEvent.fire();
1564
 
 
1565
 
        },
1566
 
        
1567
 
        /**
1568
 
        * Appends the passed element to the footer. If no footer is present, 
1569
 
        * one will be automatically created.
1570
 
        * @method appendToFooter
1571
 
        * @param {HTMLElement} element The element to append to the footer
1572
 
        */
1573
 
        appendToFooter: function (element) {
1574
 
 
1575
 
            var oFooter = this.footer || (this.footer = createFooter());
1576
 
        
1577
 
            oFooter.appendChild(element);
1578
 
 
1579
 
            this.changeFooterEvent.fire(element);
1580
 
            this.changeContentEvent.fire();
1581
 
 
1582
 
        },
1583
 
        
1584
 
        /**
1585
 
        * Renders the Module by inserting the elements that are not already 
1586
 
        * in the main Module into their correct places. Optionally appends 
1587
 
        * the Module to the specified node prior to the render's execution. 
1588
 
        * <p>
1589
 
        * For Modules without existing markup, the appendToNode argument 
1590
 
        * is REQUIRED. If this argument is ommitted and the current element is 
1591
 
        * not present in the document, the function will return false, 
1592
 
        * indicating that the render was a failure.
1593
 
        * </p>
1594
 
        * <p>
1595
 
        * NOTE: As of 2.3.1, if the appendToNode is the document's body element
1596
 
        * then the module is rendered as the first child of the body element, 
1597
 
        * and not appended to it, to avoid Operation Aborted errors in IE when 
1598
 
        * rendering the module before window's load event is fired. You can 
1599
 
        * use the appendtodocumentbody configuration property to change this 
1600
 
        * to append to document.body if required.
1601
 
        * </p>
1602
 
        * @method render
1603
 
        * @param {String} appendToNode The element id to which the Module 
1604
 
        * should be appended to prior to rendering <em>OR</em>
1605
 
        * @param {HTMLElement} appendToNode The element to which the Module 
1606
 
        * should be appended to prior to rendering
1607
 
        * @param {HTMLElement} moduleElement OPTIONAL. The element that 
1608
 
        * represents the actual Standard Module container.
1609
 
        * @return {Boolean} Success or failure of the render
1610
 
        */
1611
 
        render: function (appendToNode, moduleElement) {
1612
 
 
1613
 
            var me = this,
1614
 
                firstChild;
1615
 
 
1616
 
            function appendTo(parentNode) {
1617
 
                if (typeof parentNode == "string") {
1618
 
                    parentNode = document.getElementById(parentNode);
1619
 
                }
1620
 
 
1621
 
                if (parentNode) {
1622
 
                    me._addToParent(parentNode, me.element);
1623
 
                    me.appendEvent.fire();
1624
 
                }
1625
 
            }
1626
 
 
1627
 
            this.beforeRenderEvent.fire();
1628
 
 
1629
 
            if (! moduleElement) {
1630
 
                moduleElement = this.element;
1631
 
            }
1632
 
 
1633
 
            if (appendToNode) {
1634
 
                appendTo(appendToNode);
1635
 
            } else { 
1636
 
                // No node was passed in. If the element is not already in the Dom, this fails
1637
 
                if (! Dom.inDocument(this.element)) {
1638
 
                    return false;
1639
 
                }
1640
 
            }
1641
 
 
1642
 
            // Need to get everything into the DOM if it isn't already
1643
 
            if (this.header && ! Dom.inDocument(this.header)) {
1644
 
                // There is a header, but it's not in the DOM yet. Need to add it.
1645
 
                firstChild = moduleElement.firstChild;
1646
 
                if (firstChild) {
1647
 
                    moduleElement.insertBefore(this.header, firstChild);
1648
 
                } else {
1649
 
                    moduleElement.appendChild(this.header);
1650
 
                }
1651
 
            }
1652
 
 
1653
 
            if (this.body && ! Dom.inDocument(this.body)) {
1654
 
                // There is a body, but it's not in the DOM yet. Need to add it.                
1655
 
                if (this.footer && Dom.isAncestor(this.moduleElement, this.footer)) {
1656
 
                    moduleElement.insertBefore(this.body, this.footer);
1657
 
                } else {
1658
 
                    moduleElement.appendChild(this.body);
1659
 
                }
1660
 
            }
1661
 
 
1662
 
            if (this.footer && ! Dom.inDocument(this.footer)) {
1663
 
                // There is a footer, but it's not in the DOM yet. Need to add it.
1664
 
                moduleElement.appendChild(this.footer);
1665
 
            }
1666
 
 
1667
 
            this.renderEvent.fire();
1668
 
            return true;
1669
 
        },
1670
 
 
1671
 
        /**
1672
 
        * Removes the Module element from the DOM and sets all child elements 
1673
 
        * to null.
1674
 
        * @method destroy
1675
 
        */
1676
 
        destroy: function () {
1677
 
 
1678
 
            var parent,
1679
 
                e;
1680
 
 
1681
 
            if (this.element) {
1682
 
                Event.purgeElement(this.element, true);
1683
 
                parent = this.element.parentNode;
1684
 
            }
1685
 
 
1686
 
            if (parent) {
1687
 
                parent.removeChild(this.element);
1688
 
            }
1689
 
        
1690
 
            this.element = null;
1691
 
            this.header = null;
1692
 
            this.body = null;
1693
 
            this.footer = null;
1694
 
 
1695
 
            Module.textResizeEvent.unsubscribe(this.onDomResize, this);
1696
 
 
1697
 
            this.cfg.destroy();
1698
 
            this.cfg = null;
1699
 
 
1700
 
            this.destroyEvent.fire();
1701
 
        
1702
 
            for (e in this) {
1703
 
                if (e instanceof CustomEvent) {
1704
 
                    e.unsubscribeAll();
1705
 
                }
1706
 
            }
1707
 
 
1708
 
        },
1709
 
        
1710
 
        /**
1711
 
        * Shows the Module element by setting the visible configuration 
1712
 
        * property to true. Also fires two events: beforeShowEvent prior to 
1713
 
        * the visibility change, and showEvent after.
1714
 
        * @method show
1715
 
        */
1716
 
        show: function () {
1717
 
            this.cfg.setProperty("visible", true);
1718
 
        },
1719
 
        
1720
 
        /**
1721
 
        * Hides the Module element by setting the visible configuration 
1722
 
        * property to false. Also fires two events: beforeHideEvent prior to 
1723
 
        * the visibility change, and hideEvent after.
1724
 
        * @method hide
1725
 
        */
1726
 
        hide: function () {
1727
 
            this.cfg.setProperty("visible", false);
1728
 
        },
1729
 
        
1730
 
        // BUILT-IN EVENT HANDLERS FOR MODULE //
1731
 
        /**
1732
 
        * Default event handler for changing the visibility property of a 
1733
 
        * Module. By default, this is achieved by switching the "display" style 
1734
 
        * between "block" and "none".
1735
 
        * This method is responsible for firing showEvent and hideEvent.
1736
 
        * @param {String} type The CustomEvent type (usually the property name)
1737
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
1738
 
        * handlers, args[0] will equal the newly applied value for the property.
1739
 
        * @param {Object} obj The scope object. For configuration handlers, 
1740
 
        * this will usually equal the owner.
1741
 
        * @method configVisible
1742
 
        */
1743
 
        configVisible: function (type, args, obj) {
1744
 
            var visible = args[0];
1745
 
            if (visible) {
1746
 
                this.beforeShowEvent.fire();
1747
 
                Dom.setStyle(this.element, "display", "block");
1748
 
                this.showEvent.fire();
1749
 
            } else {
1750
 
                this.beforeHideEvent.fire();
1751
 
                Dom.setStyle(this.element, "display", "none");
1752
 
                this.hideEvent.fire();
1753
 
            }
1754
 
        },
1755
 
        
1756
 
        /**
1757
 
        * Default event handler for the "monitorresize" configuration property
1758
 
        * @param {String} type The CustomEvent type (usually the property name)
1759
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
1760
 
        * handlers, args[0] will equal the newly applied value for the property.
1761
 
        * @param {Object} obj The scope object. For configuration handlers, 
1762
 
        * this will usually equal the owner.
1763
 
        * @method configMonitorResize
1764
 
        */
1765
 
        configMonitorResize: function (type, args, obj) {
1766
 
            var monitor = args[0];
1767
 
            if (monitor) {
1768
 
                this.initResizeMonitor();
1769
 
            } else {
1770
 
                Module.textResizeEvent.unsubscribe(this.onDomResize, this, true);
1771
 
                this.resizeMonitor = null;
1772
 
            }
1773
 
        },
1774
 
 
1775
 
        /**
1776
 
         * This method is a protected helper, used when constructing the DOM structure for the module 
1777
 
         * to account for situations which may cause Operation Aborted errors in IE. It should not 
1778
 
         * be used for general DOM construction.
1779
 
         * <p>
1780
 
         * If the parentNode is not document.body, the element is appended as the last element.
1781
 
         * </p>
1782
 
         * <p>
1783
 
         * If the parentNode is document.body the element is added as the first child to help
1784
 
         * prevent Operation Aborted errors in IE.
1785
 
         * </p>
1786
 
         *
1787
 
         * @param {parentNode} The HTML element to which the element will be added
1788
 
         * @param {element} The HTML element to be added to parentNode's children
1789
 
         * @method _addToParent
1790
 
         * @protected
1791
 
         */
1792
 
        _addToParent: function(parentNode, element) {
1793
 
            if (!this.cfg.getProperty("appendtodocumentbody") && parentNode === document.body && parentNode.firstChild) {
1794
 
                parentNode.insertBefore(element, parentNode.firstChild);
1795
 
            } else {
1796
 
                parentNode.appendChild(element);
1797
 
            }
1798
 
        },
1799
 
 
1800
 
        /**
1801
 
        * Returns a String representation of the Object.
1802
 
        * @method toString
1803
 
        * @return {String} The string representation of the Module
1804
 
        */
1805
 
        toString: function () {
1806
 
            return "Module " + this.id;
1807
 
        }
1808
 
    };
1809
 
 
1810
 
    YAHOO.lang.augmentProto(Module, YAHOO.util.EventProvider);
1811
 
 
1812
 
}());
1813
 
 
1814
 
(function () {
1815
 
 
1816
 
    /**
1817
 
    * Overlay is a Module that is absolutely positioned above the page flow. It 
1818
 
    * has convenience methods for positioning and sizing, as well as options for 
1819
 
    * controlling zIndex and constraining the Overlay's position to the current 
1820
 
    * visible viewport. Overlay also contains a dynamicly generated IFRAME which 
1821
 
    * is placed beneath it for Internet Explorer 6 and 5.x so that it will be 
1822
 
    * properly rendered above SELECT elements.
1823
 
    * @namespace YAHOO.widget
1824
 
    * @class Overlay
1825
 
    * @extends YAHOO.widget.Module
1826
 
    * @param {String} el The element ID representing the Overlay <em>OR</em>
1827
 
    * @param {HTMLElement} el The element representing the Overlay
1828
 
    * @param {Object} userConfig The configuration object literal containing 
1829
 
    * the configuration that should be set for this Overlay. See configuration 
1830
 
    * documentation for more details.
1831
 
    * @constructor
1832
 
    */
1833
 
    YAHOO.widget.Overlay = function (el, userConfig) {
1834
 
        YAHOO.widget.Overlay.superclass.constructor.call(this, el, userConfig);
1835
 
    };
1836
 
 
1837
 
    var Lang = YAHOO.lang,
1838
 
        CustomEvent = YAHOO.util.CustomEvent,
1839
 
        Module = YAHOO.widget.Module,
1840
 
        Event = YAHOO.util.Event,
1841
 
        Dom = YAHOO.util.Dom,
1842
 
        Config = YAHOO.util.Config,
1843
 
        Overlay = YAHOO.widget.Overlay,
1844
 
 
1845
 
        m_oIFrameTemplate,
1846
 
 
1847
 
        /**
1848
 
        * Constant representing the name of the Overlay's events
1849
 
        * @property EVENT_TYPES
1850
 
        * @private
1851
 
        * @final
1852
 
        * @type Object
1853
 
        */
1854
 
        EVENT_TYPES = {
1855
 
            "BEFORE_MOVE": "beforeMove",
1856
 
            "MOVE": "move"
1857
 
        },
1858
 
 
1859
 
        /**
1860
 
        * Constant representing the Overlay's configuration properties
1861
 
        * @property DEFAULT_CONFIG
1862
 
        * @private
1863
 
        * @final
1864
 
        * @type Object
1865
 
        */
1866
 
        DEFAULT_CONFIG = {
1867
 
 
1868
 
            "X": { 
1869
 
                key: "x", 
1870
 
                validator: Lang.isNumber, 
1871
 
                suppressEvent: true, 
1872
 
                supercedes: ["iframe"]
1873
 
            },
1874
 
 
1875
 
            "Y": { 
1876
 
                key: "y", 
1877
 
                validator: Lang.isNumber, 
1878
 
                suppressEvent: true, 
1879
 
                supercedes: ["iframe"]
1880
 
            },
1881
 
 
1882
 
            "XY": { 
1883
 
                key: "xy", 
1884
 
                suppressEvent: true, 
1885
 
                supercedes: ["iframe"] 
1886
 
            },
1887
 
 
1888
 
            "CONTEXT": { 
1889
 
                key: "context", 
1890
 
                suppressEvent: true, 
1891
 
                supercedes: ["iframe"] 
1892
 
            },
1893
 
 
1894
 
            "FIXED_CENTER": { 
1895
 
                key: "fixedcenter", 
1896
 
                value: false, 
1897
 
                validator: Lang.isBoolean, 
1898
 
                supercedes: ["iframe", "visible"] 
1899
 
            },
1900
 
 
1901
 
            "WIDTH": { 
1902
 
                key: "width", 
1903
 
                suppressEvent: true, 
1904
 
                supercedes: ["context", "fixedcenter", "iframe"] 
1905
 
            }, 
1906
 
 
1907
 
            "HEIGHT": { 
1908
 
                key: "height", 
1909
 
                suppressEvent: true, 
1910
 
                supercedes: ["context", "fixedcenter", "iframe"] 
1911
 
            },
1912
 
 
1913
 
            "ZINDEX": { 
1914
 
                key: "zindex", 
1915
 
                value: null 
1916
 
            },
1917
 
 
1918
 
            "CONSTRAIN_TO_VIEWPORT": { 
1919
 
                key: "constraintoviewport", 
1920
 
                value: false, 
1921
 
                validator: Lang.isBoolean, 
1922
 
                supercedes: ["iframe", "x", "y", "xy"]
1923
 
            }, 
1924
 
 
1925
 
            "IFRAME": { 
1926
 
                key: "iframe", 
1927
 
                value: (YAHOO.env.ua.ie == 6 ? true : false), 
1928
 
                validator: Lang.isBoolean, 
1929
 
                supercedes: ["zindex"] 
1930
 
            }
1931
 
        };
1932
 
 
1933
 
    /**
1934
 
    * The URL that will be placed in the iframe
1935
 
    * @property YAHOO.widget.Overlay.IFRAME_SRC
1936
 
    * @static
1937
 
    * @final
1938
 
    * @type String
1939
 
    */
1940
 
    Overlay.IFRAME_SRC = "javascript:false;";
1941
 
 
1942
 
    /**
1943
 
    * Number representing how much the iframe shim should be offset from each 
1944
 
    * side of an Overlay instance, in pixels.
1945
 
    * @property YAHOO.widget.Overlay.IFRAME_SRC
1946
 
    * @default 3
1947
 
    * @static
1948
 
    * @final
1949
 
    * @type Number
1950
 
    */
1951
 
    Overlay.IFRAME_OFFSET = 3;
1952
 
 
1953
 
    /**
1954
 
    * Number representing the minimum distance an Overlay instance should be 
1955
 
    * positioned relative to the boundaries of the browser's viewport, in pixels.
1956
 
    * @property YAHOO.widget.Overlay.VIEWPORT_OFFSET
1957
 
    * @default 10
1958
 
    * @static
1959
 
    * @final
1960
 
    * @type Number
1961
 
    */
1962
 
    Overlay.VIEWPORT_OFFSET = 10;
1963
 
 
1964
 
    /**
1965
 
    * Constant representing the top left corner of an element, used for 
1966
 
    * configuring the context element alignment
1967
 
    * @property YAHOO.widget.Overlay.TOP_LEFT
1968
 
    * @static
1969
 
    * @final
1970
 
    * @type String
1971
 
    */
1972
 
    Overlay.TOP_LEFT = "tl";
1973
 
 
1974
 
    /**
1975
 
    * Constant representing the top right corner of an element, used for 
1976
 
    * configuring the context element alignment
1977
 
    * @property YAHOO.widget.Overlay.TOP_RIGHT
1978
 
    * @static
1979
 
    * @final
1980
 
    * @type String
1981
 
    */
1982
 
    Overlay.TOP_RIGHT = "tr";
1983
 
 
1984
 
    /**
1985
 
    * Constant representing the top bottom left corner of an element, used for 
1986
 
    * configuring the context element alignment
1987
 
    * @property YAHOO.widget.Overlay.BOTTOM_LEFT
1988
 
    * @static
1989
 
    * @final
1990
 
    * @type String
1991
 
    */
1992
 
    Overlay.BOTTOM_LEFT = "bl";
1993
 
 
1994
 
    /**
1995
 
    * Constant representing the bottom right corner of an element, used for 
1996
 
    * configuring the context element alignment
1997
 
    * @property YAHOO.widget.Overlay.BOTTOM_RIGHT
1998
 
    * @static
1999
 
    * @final
2000
 
    * @type String
2001
 
    */
2002
 
    Overlay.BOTTOM_RIGHT = "br";
2003
 
 
2004
 
    /**
2005
 
    * Constant representing the default CSS class used for an Overlay
2006
 
    * @property YAHOO.widget.Overlay.CSS_OVERLAY
2007
 
    * @static
2008
 
    * @final
2009
 
    * @type String
2010
 
    */
2011
 
    Overlay.CSS_OVERLAY = "yui-overlay";
2012
 
 
2013
 
    /**
2014
 
    * A singleton CustomEvent used for reacting to the DOM event for 
2015
 
    * window scroll
2016
 
    * @event YAHOO.widget.Overlay.windowScrollEvent
2017
 
    */
2018
 
    Overlay.windowScrollEvent = new CustomEvent("windowScroll");
2019
 
 
2020
 
    /**
2021
 
    * A singleton CustomEvent used for reacting to the DOM event for
2022
 
    * window resize
2023
 
    * @event YAHOO.widget.Overlay.windowResizeEvent
2024
 
    */
2025
 
    Overlay.windowResizeEvent = new CustomEvent("windowResize");
2026
 
 
2027
 
    /**
2028
 
    * The DOM event handler used to fire the CustomEvent for window scroll
2029
 
    * @method YAHOO.widget.Overlay.windowScrollHandler
2030
 
    * @static
2031
 
    * @param {DOMEvent} e The DOM scroll event
2032
 
    */
2033
 
    Overlay.windowScrollHandler = function (e) {
2034
 
 
2035
 
        if (YAHOO.env.ua.ie) {
2036
 
 
2037
 
            if (! window.scrollEnd) {
2038
 
                window.scrollEnd = -1;
2039
 
            }
2040
 
 
2041
 
            clearTimeout(window.scrollEnd);
2042
 
    
2043
 
            window.scrollEnd = setTimeout(function () { 
2044
 
                Overlay.windowScrollEvent.fire(); 
2045
 
            }, 1);
2046
 
    
2047
 
        } else {
2048
 
            Overlay.windowScrollEvent.fire();
2049
 
        }
2050
 
    };
2051
 
 
2052
 
    /**
2053
 
    * The DOM event handler used to fire the CustomEvent for window resize
2054
 
    * @method YAHOO.widget.Overlay.windowResizeHandler
2055
 
    * @static
2056
 
    * @param {DOMEvent} e The DOM resize event
2057
 
    */
2058
 
    Overlay.windowResizeHandler = function (e) {
2059
 
 
2060
 
        if (YAHOO.env.ua.ie) {
2061
 
            if (! window.resizeEnd) {
2062
 
                window.resizeEnd = -1;
2063
 
            }
2064
 
 
2065
 
            clearTimeout(window.resizeEnd);
2066
 
 
2067
 
            window.resizeEnd = setTimeout(function () {
2068
 
                Overlay.windowResizeEvent.fire(); 
2069
 
            }, 100);
2070
 
        } else {
2071
 
            Overlay.windowResizeEvent.fire();
2072
 
        }
2073
 
    };
2074
 
 
2075
 
    /**
2076
 
    * A boolean that indicated whether the window resize and scroll events have 
2077
 
    * already been subscribed to.
2078
 
    * @property YAHOO.widget.Overlay._initialized
2079
 
    * @private
2080
 
    * @type Boolean
2081
 
    */
2082
 
    Overlay._initialized = null;
2083
 
 
2084
 
    if (Overlay._initialized === null) {
2085
 
        Event.on(window, "scroll", Overlay.windowScrollHandler);
2086
 
        Event.on(window, "resize", Overlay.windowResizeHandler);
2087
 
    
2088
 
        Overlay._initialized = true;
2089
 
    }
2090
 
 
2091
 
    YAHOO.extend(Overlay, Module, {
2092
 
 
2093
 
        /**
2094
 
        * The Overlay initialization method, which is executed for Overlay and  
2095
 
        * all of its subclasses. This method is automatically called by the 
2096
 
        * constructor, and  sets up all DOM references for pre-existing markup, 
2097
 
        * and creates required markup if it is not already present.
2098
 
        * @method init
2099
 
        * @param {String} el The element ID representing the Overlay <em>OR</em>
2100
 
        * @param {HTMLElement} el The element representing the Overlay
2101
 
        * @param {Object} userConfig The configuration object literal 
2102
 
        * containing the configuration that should be set for this Overlay. 
2103
 
        * See configuration documentation for more details.
2104
 
        */
2105
 
        init: function (el, userConfig) {
2106
 
    
2107
 
            /*
2108
 
                 Note that we don't pass the user config in here yet because we
2109
 
                 only want it executed once, at the lowest subclass level
2110
 
            */
2111
 
    
2112
 
            Overlay.superclass.init.call(this, el/*, userConfig*/);  
2113
 
 
2114
 
            this.beforeInitEvent.fire(Overlay);
2115
 
            
2116
 
            Dom.addClass(this.element, Overlay.CSS_OVERLAY);
2117
 
            
2118
 
            if (userConfig) {
2119
 
                this.cfg.applyConfig(userConfig, true);
2120
 
            }
2121
 
 
2122
 
            if (this.platform == "mac" && YAHOO.env.ua.gecko) {
2123
 
 
2124
 
                if (! Config.alreadySubscribed(this.showEvent,
2125
 
                    this.showMacGeckoScrollbars, this)) {
2126
 
 
2127
 
                    this.showEvent.subscribe(this.showMacGeckoScrollbars, 
2128
 
                        this, true);
2129
 
 
2130
 
                }
2131
 
 
2132
 
                if (! Config.alreadySubscribed(this.hideEvent, 
2133
 
                    this.hideMacGeckoScrollbars, this)) {
2134
 
 
2135
 
                    this.hideEvent.subscribe(this.hideMacGeckoScrollbars, 
2136
 
                        this, true);
2137
 
 
2138
 
                }
2139
 
            }
2140
 
 
2141
 
            this.initEvent.fire(Overlay);
2142
 
        },
2143
 
        
2144
 
        /**
2145
 
        * Initializes the custom events for Overlay which are fired  
2146
 
        * automatically at appropriate times by the Overlay class.
2147
 
        * @method initEvents
2148
 
        */
2149
 
        initEvents: function () {
2150
 
    
2151
 
            Overlay.superclass.initEvents.call(this);
2152
 
            
2153
 
            var SIGNATURE = CustomEvent.LIST;
2154
 
            
2155
 
            /**
2156
 
            * CustomEvent fired before the Overlay is moved.
2157
 
            * @event beforeMoveEvent
2158
 
            * @param {Number} x x coordinate
2159
 
            * @param {Number} y y coordinate
2160
 
            */
2161
 
            this.beforeMoveEvent = this.createEvent(EVENT_TYPES.BEFORE_MOVE);
2162
 
            this.beforeMoveEvent.signature = SIGNATURE;
2163
 
            
2164
 
            /**
2165
 
            * CustomEvent fired after the Overlay is moved.
2166
 
            * @event moveEvent
2167
 
            * @param {Number} x x coordinate
2168
 
            * @param {Number} y y coordinate
2169
 
            */
2170
 
            this.moveEvent = this.createEvent(EVENT_TYPES.MOVE);
2171
 
            this.moveEvent.signature = SIGNATURE;
2172
 
        
2173
 
        },
2174
 
        
2175
 
        /**
2176
 
        * Initializes the class's configurable properties which can be changed 
2177
 
        * using the Overlay's Config object (cfg).
2178
 
        * @method initDefaultConfig
2179
 
        */
2180
 
        initDefaultConfig: function () {
2181
 
    
2182
 
            Overlay.superclass.initDefaultConfig.call(this);
2183
 
            
2184
 
            
2185
 
            // Add overlay config properties //
2186
 
            
2187
 
            /**
2188
 
            * The absolute x-coordinate position of the Overlay
2189
 
            * @config x
2190
 
            * @type Number
2191
 
            * @default null
2192
 
            */
2193
 
            this.cfg.addProperty(DEFAULT_CONFIG.X.key, { 
2194
 
    
2195
 
                handler: this.configX, 
2196
 
                validator: DEFAULT_CONFIG.X.validator, 
2197
 
                suppressEvent: DEFAULT_CONFIG.X.suppressEvent, 
2198
 
                supercedes: DEFAULT_CONFIG.X.supercedes
2199
 
    
2200
 
            });
2201
 
 
2202
 
            /**
2203
 
            * The absolute y-coordinate position of the Overlay
2204
 
            * @config y
2205
 
            * @type Number
2206
 
            * @default null
2207
 
            */
2208
 
            this.cfg.addProperty(DEFAULT_CONFIG.Y.key, {
2209
 
 
2210
 
                handler: this.configY, 
2211
 
                validator: DEFAULT_CONFIG.Y.validator, 
2212
 
                suppressEvent: DEFAULT_CONFIG.Y.suppressEvent, 
2213
 
                supercedes: DEFAULT_CONFIG.Y.supercedes
2214
 
 
2215
 
            });
2216
 
    
2217
 
            /**
2218
 
            * An array with the absolute x and y positions of the Overlay
2219
 
            * @config xy
2220
 
            * @type Number[]
2221
 
            * @default null
2222
 
            */
2223
 
            this.cfg.addProperty(DEFAULT_CONFIG.XY.key, {
2224
 
            
2225
 
                handler: this.configXY, 
2226
 
                suppressEvent: DEFAULT_CONFIG.XY.suppressEvent, 
2227
 
                supercedes: DEFAULT_CONFIG.XY.supercedes
2228
 
            
2229
 
            });
2230
 
    
2231
 
            /**
2232
 
            * The array of context arguments for context-sensitive positioning.  
2233
 
            * The format is: [id or element, element corner, context corner]. 
2234
 
            * For example, setting this property to ["img1", "tl", "bl"] would 
2235
 
            * align the Overlay's top left corner to the context element's 
2236
 
            * bottom left corner.
2237
 
            * @config context
2238
 
            * @type Array
2239
 
            * @default null
2240
 
            */
2241
 
            this.cfg.addProperty(DEFAULT_CONFIG.CONTEXT.key, {
2242
 
            
2243
 
                handler: this.configContext, 
2244
 
                suppressEvent: DEFAULT_CONFIG.CONTEXT.suppressEvent, 
2245
 
                supercedes: DEFAULT_CONFIG.CONTEXT.supercedes
2246
 
            
2247
 
            });
2248
 
 
2249
 
            /**
2250
 
            * True if the Overlay should be anchored to the center of 
2251
 
            * the viewport.
2252
 
            * @config fixedcenter
2253
 
            * @type Boolean
2254
 
            * @default false
2255
 
            */
2256
 
            this.cfg.addProperty(DEFAULT_CONFIG.FIXED_CENTER.key, {
2257
 
            
2258
 
                handler: this.configFixedCenter,
2259
 
                value: DEFAULT_CONFIG.FIXED_CENTER.value, 
2260
 
                validator: DEFAULT_CONFIG.FIXED_CENTER.validator, 
2261
 
                supercedes: DEFAULT_CONFIG.FIXED_CENTER.supercedes
2262
 
            
2263
 
            });
2264
 
    
2265
 
            /**
2266
 
            * CSS width of the Overlay.
2267
 
            * @config width
2268
 
            * @type String
2269
 
            * @default null
2270
 
            */
2271
 
            this.cfg.addProperty(DEFAULT_CONFIG.WIDTH.key, {
2272
 
 
2273
 
                handler: this.configWidth, 
2274
 
                suppressEvent: DEFAULT_CONFIG.WIDTH.suppressEvent, 
2275
 
                supercedes: DEFAULT_CONFIG.WIDTH.supercedes
2276
 
 
2277
 
            });
2278
 
 
2279
 
            /**
2280
 
            * CSS height of the Overlay.
2281
 
            * @config height
2282
 
            * @type String
2283
 
            * @default null
2284
 
            */
2285
 
            this.cfg.addProperty(DEFAULT_CONFIG.HEIGHT.key, {
2286
 
 
2287
 
                handler: this.configHeight, 
2288
 
                suppressEvent: DEFAULT_CONFIG.HEIGHT.suppressEvent, 
2289
 
                supercedes: DEFAULT_CONFIG.HEIGHT.supercedes
2290
 
            
2291
 
            });
2292
 
            
2293
 
            /**
2294
 
            * CSS z-index of the Overlay.
2295
 
            * @config zIndex
2296
 
            * @type Number
2297
 
            * @default null
2298
 
            */
2299
 
            this.cfg.addProperty(DEFAULT_CONFIG.ZINDEX.key, {
2300
 
 
2301
 
                handler: this.configzIndex,
2302
 
                value: DEFAULT_CONFIG.ZINDEX.value
2303
 
 
2304
 
            });
2305
 
 
2306
 
            /**
2307
 
            * True if the Overlay should be prevented from being positioned 
2308
 
            * out of the viewport.
2309
 
            * @config constraintoviewport
2310
 
            * @type Boolean
2311
 
            * @default false
2312
 
            */
2313
 
            this.cfg.addProperty(DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.key, {
2314
 
 
2315
 
                handler: this.configConstrainToViewport, 
2316
 
                value: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.value, 
2317
 
                validator: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.validator, 
2318
 
                supercedes: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.supercedes
2319
 
 
2320
 
            });
2321
 
 
2322
 
            /**
2323
 
            * @config iframe
2324
 
            * @description Boolean indicating whether or not the Overlay should 
2325
 
            * have an IFRAME shim; used to prevent SELECT elements from 
2326
 
            * poking through an Overlay instance in IE6.  When set to "true", 
2327
 
            * the iframe shim is created when the Overlay instance is intially
2328
 
            * made visible.
2329
 
            * @type Boolean
2330
 
            * @default true for IE6 and below, false for all other browsers.
2331
 
            */
2332
 
            this.cfg.addProperty(DEFAULT_CONFIG.IFRAME.key, {
2333
 
 
2334
 
                handler: this.configIframe, 
2335
 
                value: DEFAULT_CONFIG.IFRAME.value, 
2336
 
                validator: DEFAULT_CONFIG.IFRAME.validator, 
2337
 
                supercedes: DEFAULT_CONFIG.IFRAME.supercedes
2338
 
 
2339
 
            });
2340
 
        },
2341
 
 
2342
 
        /**
2343
 
        * Moves the Overlay to the specified position. This function is  
2344
 
        * identical to calling this.cfg.setProperty("xy", [x,y]);
2345
 
        * @method moveTo
2346
 
        * @param {Number} x The Overlay's new x position
2347
 
        * @param {Number} y The Overlay's new y position
2348
 
        */
2349
 
        moveTo: function (x, y) {
2350
 
            this.cfg.setProperty("xy", [x, y]);
2351
 
        },
2352
 
 
2353
 
        /**
2354
 
        * Adds a CSS class ("hide-scrollbars") and removes a CSS class 
2355
 
        * ("show-scrollbars") to the Overlay to fix a bug in Gecko on Mac OS X 
2356
 
        * (https://bugzilla.mozilla.org/show_bug.cgi?id=187435)
2357
 
        * @method hideMacGeckoScrollbars
2358
 
        */
2359
 
        hideMacGeckoScrollbars: function () {
2360
 
    
2361
 
            Dom.removeClass(this.element, "show-scrollbars");
2362
 
            Dom.addClass(this.element, "hide-scrollbars");
2363
 
    
2364
 
        },
2365
 
 
2366
 
        /**
2367
 
        * Adds a CSS class ("show-scrollbars") and removes a CSS class 
2368
 
        * ("hide-scrollbars") to the Overlay to fix a bug in Gecko on Mac OS X 
2369
 
        * (https://bugzilla.mozilla.org/show_bug.cgi?id=187435)
2370
 
        * @method showMacGeckoScrollbars
2371
 
        */
2372
 
        showMacGeckoScrollbars: function () {
2373
 
    
2374
 
            Dom.removeClass(this.element, "hide-scrollbars");
2375
 
            Dom.addClass(this.element, "show-scrollbars");
2376
 
    
2377
 
        },
2378
 
 
2379
 
        // BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
2380
 
        /**
2381
 
        * The default event handler fired when the "visible" property is 
2382
 
        * changed.  This method is responsible for firing showEvent
2383
 
        * and hideEvent.
2384
 
        * @method configVisible
2385
 
        * @param {String} type The CustomEvent type (usually the property name)
2386
 
        * @param {Object[]} args The CustomEvent arguments. For configuration
2387
 
        * handlers, args[0] will equal the newly applied value for the property.
2388
 
        * @param {Object} obj The scope object. For configuration handlers, 
2389
 
        * this will usually equal the owner.
2390
 
        */
2391
 
        configVisible: function (type, args, obj) {
2392
 
 
2393
 
            var visible = args[0],
2394
 
                currentVis = Dom.getStyle(this.element, "visibility"),
2395
 
                effect = this.cfg.getProperty("effect"),
2396
 
                effectInstances = [],
2397
 
                isMacGecko = (this.platform == "mac" && YAHOO.env.ua.gecko),
2398
 
                alreadySubscribed = Config.alreadySubscribed,
2399
 
                eff, ei, e, i, j, k, h,
2400
 
                nEffects,
2401
 
                nEffectInstances;
2402
 
 
2403
 
            if (currentVis == "inherit") {
2404
 
                e = this.element.parentNode;
2405
 
 
2406
 
                while (e.nodeType != 9 && e.nodeType != 11) {
2407
 
                    currentVis = Dom.getStyle(e, "visibility");
2408
 
 
2409
 
                    if (currentVis != "inherit") { 
2410
 
                        break; 
2411
 
                    }
2412
 
 
2413
 
                    e = e.parentNode;
2414
 
                }
2415
 
 
2416
 
                if (currentVis == "inherit") {
2417
 
                    currentVis = "visible";
2418
 
                }
2419
 
            }
2420
 
 
2421
 
            if (effect) {
2422
 
                if (effect instanceof Array) {
2423
 
                    nEffects = effect.length;
2424
 
 
2425
 
                    for (i = 0; i < nEffects; i++) {
2426
 
                        eff = effect[i];
2427
 
                        effectInstances[effectInstances.length] = 
2428
 
                            eff.effect(this, eff.duration);
2429
 
 
2430
 
                    }
2431
 
                } else {
2432
 
                    effectInstances[effectInstances.length] = 
2433
 
                        effect.effect(this, effect.duration);
2434
 
                }
2435
 
            }
2436
 
 
2437
 
 
2438
 
            if (visible) { // Show
2439
 
                if (isMacGecko) {
2440
 
                    this.showMacGeckoScrollbars();
2441
 
                }
2442
 
 
2443
 
                if (effect) { // Animate in
2444
 
                    if (visible) { // Animate in if not showing
2445
 
                        if (currentVis != "visible" || currentVis === "") {
2446
 
                            this.beforeShowEvent.fire();
2447
 
                            nEffectInstances = effectInstances.length;
2448
 
 
2449
 
                            for (j = 0; j < nEffectInstances; j++) {
2450
 
                                ei = effectInstances[j];
2451
 
                                if (j === 0 && !alreadySubscribed(
2452
 
                                        ei.animateInCompleteEvent, 
2453
 
                                        this.showEvent.fire, this.showEvent)) {
2454
 
 
2455
 
                                    /*
2456
 
                                         Delegate showEvent until end 
2457
 
                                         of animateInComplete
2458
 
                                    */
2459
 
 
2460
 
                                    ei.animateInCompleteEvent.subscribe(
2461
 
                                     this.showEvent.fire, this.showEvent, true);
2462
 
                                }
2463
 
                                ei.animateIn();
2464
 
                            }
2465
 
                        }
2466
 
                    }
2467
 
                } else { // Show
2468
 
                    if (currentVis != "visible" || currentVis === "") {
2469
 
                        this.beforeShowEvent.fire();
2470
 
 
2471
 
                        Dom.setStyle(this.element, "visibility", "visible");
2472
 
 
2473
 
                        this.cfg.refireEvent("iframe");
2474
 
                        this.showEvent.fire();
2475
 
                    }
2476
 
                }
2477
 
            } else { // Hide
2478
 
 
2479
 
                if (isMacGecko) {
2480
 
                    this.hideMacGeckoScrollbars();
2481
 
                }
2482
 
                    
2483
 
                if (effect) { // Animate out if showing
2484
 
                    if (currentVis == "visible") {
2485
 
                        this.beforeHideEvent.fire();
2486
 
 
2487
 
                        nEffectInstances = effectInstances.length;
2488
 
                        for (k = 0; k < nEffectInstances; k++) {
2489
 
                            h = effectInstances[k];
2490
 
    
2491
 
                            if (k === 0 && !alreadySubscribed(
2492
 
                                h.animateOutCompleteEvent, this.hideEvent.fire, 
2493
 
                                this.hideEvent)) {
2494
 
    
2495
 
                                /*
2496
 
                                     Delegate hideEvent until end 
2497
 
                                     of animateOutComplete
2498
 
                                */
2499
 
    
2500
 
                                h.animateOutCompleteEvent.subscribe(
2501
 
                                    this.hideEvent.fire, this.hideEvent, true);
2502
 
    
2503
 
                            }
2504
 
                            h.animateOut();
2505
 
                        }
2506
 
 
2507
 
                    } else if (currentVis === "") {
2508
 
                        Dom.setStyle(this.element, "visibility", "hidden");
2509
 
                    }
2510
 
 
2511
 
                } else { // Simple hide
2512
 
 
2513
 
                    if (currentVis == "visible" || currentVis === "") {
2514
 
                        this.beforeHideEvent.fire();
2515
 
                        Dom.setStyle(this.element, "visibility", "hidden");
2516
 
                        this.hideEvent.fire();
2517
 
                    }
2518
 
                }
2519
 
            }
2520
 
        },
2521
 
 
2522
 
        /**
2523
 
        * Center event handler used for centering on scroll/resize, but only if 
2524
 
        * the Overlay is visible
2525
 
        * @method doCenterOnDOMEvent
2526
 
        */
2527
 
        doCenterOnDOMEvent: function () {
2528
 
            if (this.cfg.getProperty("visible")) {
2529
 
                this.center();
2530
 
            }
2531
 
        },
2532
 
 
2533
 
        /**
2534
 
        * The default event handler fired when the "fixedcenter" property 
2535
 
        * is changed.
2536
 
        * @method configFixedCenter
2537
 
        * @param {String} type The CustomEvent type (usually the property name)
2538
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
2539
 
        * handlers, args[0] will equal the newly applied value for the property.
2540
 
        * @param {Object} obj The scope object. For configuration handlers, 
2541
 
        * this will usually equal the owner.
2542
 
        */
2543
 
        configFixedCenter: function (type, args, obj) {
2544
 
 
2545
 
            var val = args[0],
2546
 
                alreadySubscribed = Config.alreadySubscribed,
2547
 
                windowResizeEvent = Overlay.windowResizeEvent,
2548
 
                windowScrollEvent = Overlay.windowScrollEvent;
2549
 
 
2550
 
            if (val) {
2551
 
                this.center();
2552
 
 
2553
 
                if (!alreadySubscribed(this.beforeShowEvent, this.center, this)) {
2554
 
                    this.beforeShowEvent.subscribe(this.center);
2555
 
                }
2556
 
 
2557
 
                if (!alreadySubscribed(windowResizeEvent, this.doCenterOnDOMEvent, this)) {
2558
 
                    windowResizeEvent.subscribe(this.doCenterOnDOMEvent, this, true);
2559
 
                }
2560
 
 
2561
 
                if (!alreadySubscribed(windowScrollEvent, this.doCenterOnDOMEvent, this)) {
2562
 
                    windowScrollEvent.subscribe(this.doCenterOnDOMEvent, this, true);
2563
 
                }
2564
 
 
2565
 
            } else {
2566
 
                this.beforeShowEvent.unsubscribe(this.center);
2567
 
 
2568
 
                windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent, this);
2569
 
                windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent, this);
2570
 
            }
2571
 
        },
2572
 
        
2573
 
        /**
2574
 
        * The default event handler fired when the "height" property is changed.
2575
 
        * @method configHeight
2576
 
        * @param {String} type The CustomEvent type (usually the property name)
2577
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
2578
 
        * handlers, args[0] will equal the newly applied value for the property.
2579
 
        * @param {Object} obj The scope object. For configuration handlers, 
2580
 
        * this will usually equal the owner.
2581
 
        */
2582
 
        configHeight: function (type, args, obj) {
2583
 
 
2584
 
            var height = args[0],
2585
 
                el = this.element;
2586
 
 
2587
 
            Dom.setStyle(el, "height", height);
2588
 
            this.cfg.refireEvent("iframe");
2589
 
        },
2590
 
 
2591
 
        /**
2592
 
        * The default event handler fired when the "width" property is changed.
2593
 
        * @method configWidth
2594
 
        * @param {String} type The CustomEvent type (usually the property name)
2595
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
2596
 
        * handlers, args[0] will equal the newly applied value for the property.
2597
 
        * @param {Object} obj The scope object. For configuration handlers, 
2598
 
        * this will usually equal the owner.
2599
 
        */
2600
 
        configWidth: function (type, args, obj) {
2601
 
 
2602
 
            var width = args[0],
2603
 
                el = this.element;
2604
 
    
2605
 
            Dom.setStyle(el, "width", width);
2606
 
            this.cfg.refireEvent("iframe");
2607
 
        },
2608
 
        
2609
 
        /**
2610
 
        * The default event handler fired when the "zIndex" property is changed.
2611
 
        * @method configzIndex
2612
 
        * @param {String} type The CustomEvent type (usually the property name)
2613
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
2614
 
        * handlers, args[0] will equal the newly applied value for the property.
2615
 
        * @param {Object} obj The scope object. For configuration handlers, 
2616
 
        * this will usually equal the owner.
2617
 
        */
2618
 
        configzIndex: function (type, args, obj) {
2619
 
 
2620
 
            var zIndex = args[0],
2621
 
                el = this.element;
2622
 
 
2623
 
            if (! zIndex) {
2624
 
                zIndex = Dom.getStyle(el, "zIndex");
2625
 
                if (! zIndex || isNaN(zIndex)) {
2626
 
                    zIndex = 0;
2627
 
                }
2628
 
            }
2629
 
 
2630
 
            if (this.iframe || this.cfg.getProperty("iframe") === true) {
2631
 
                if (zIndex <= 0) {
2632
 
                    zIndex = 1;
2633
 
                }
2634
 
            }
2635
 
 
2636
 
            Dom.setStyle(el, "zIndex", zIndex);
2637
 
            this.cfg.setProperty("zIndex", zIndex, true);
2638
 
 
2639
 
            if (this.iframe) {
2640
 
                this.stackIframe();
2641
 
            }
2642
 
        },
2643
 
 
2644
 
        /**
2645
 
        * The default event handler fired when the "xy" property is changed.
2646
 
        * @method configXY
2647
 
        * @param {String} type The CustomEvent type (usually the property name)
2648
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
2649
 
        * handlers, args[0] will equal the newly applied value for the property.
2650
 
        * @param {Object} obj The scope object. For configuration handlers, 
2651
 
        * this will usually equal the owner.
2652
 
        */
2653
 
        configXY: function (type, args, obj) {
2654
 
 
2655
 
            var pos = args[0],
2656
 
                x = pos[0],
2657
 
                y = pos[1];
2658
 
 
2659
 
            this.cfg.setProperty("x", x);
2660
 
            this.cfg.setProperty("y", y);
2661
 
 
2662
 
            this.beforeMoveEvent.fire([x, y]);
2663
 
 
2664
 
            x = this.cfg.getProperty("x");
2665
 
            y = this.cfg.getProperty("y");
2666
 
 
2667
 
 
2668
 
            this.cfg.refireEvent("iframe");
2669
 
            this.moveEvent.fire([x, y]);
2670
 
        },
2671
 
 
2672
 
        /**
2673
 
        * The default event handler fired when the "x" property is changed.
2674
 
        * @method configX
2675
 
        * @param {String} type The CustomEvent type (usually the property name)
2676
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
2677
 
        * handlers, args[0] will equal the newly applied value for the property.
2678
 
        * @param {Object} obj The scope object. For configuration handlers, 
2679
 
        * this will usually equal the owner.
2680
 
        */
2681
 
        configX: function (type, args, obj) {
2682
 
 
2683
 
            var x = args[0],
2684
 
                y = this.cfg.getProperty("y");
2685
 
 
2686
 
            this.cfg.setProperty("x", x, true);
2687
 
            this.cfg.setProperty("y", y, true);
2688
 
 
2689
 
            this.beforeMoveEvent.fire([x, y]);
2690
 
 
2691
 
            x = this.cfg.getProperty("x");
2692
 
            y = this.cfg.getProperty("y");
2693
 
            
2694
 
            Dom.setX(this.element, x, true);
2695
 
 
2696
 
            this.cfg.setProperty("xy", [x, y], true);
2697
 
 
2698
 
            this.cfg.refireEvent("iframe");
2699
 
            this.moveEvent.fire([x, y]);
2700
 
        },
2701
 
 
2702
 
        /**
2703
 
        * The default event handler fired when the "y" property is changed.
2704
 
        * @method configY
2705
 
        * @param {String} type The CustomEvent type (usually the property name)
2706
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
2707
 
        * handlers, args[0] will equal the newly applied value for the property.
2708
 
        * @param {Object} obj The scope object. For configuration handlers, 
2709
 
        * this will usually equal the owner.
2710
 
        */
2711
 
        configY: function (type, args, obj) {
2712
 
 
2713
 
            var x = this.cfg.getProperty("x"),
2714
 
                y = args[0];
2715
 
 
2716
 
            this.cfg.setProperty("x", x, true);
2717
 
            this.cfg.setProperty("y", y, true);
2718
 
 
2719
 
            this.beforeMoveEvent.fire([x, y]);
2720
 
 
2721
 
            x = this.cfg.getProperty("x");
2722
 
            y = this.cfg.getProperty("y");
2723
 
 
2724
 
            Dom.setY(this.element, y, true);
2725
 
 
2726
 
            this.cfg.setProperty("xy", [x, y], true);
2727
 
 
2728
 
            this.cfg.refireEvent("iframe");
2729
 
            this.moveEvent.fire([x, y]);
2730
 
        },
2731
 
        
2732
 
        /**
2733
 
        * Shows the iframe shim, if it has been enabled.
2734
 
        * @method showIframe
2735
 
        */
2736
 
        showIframe: function () {
2737
 
 
2738
 
            var oIFrame = this.iframe,
2739
 
                oParentNode;
2740
 
 
2741
 
            if (oIFrame) {
2742
 
                oParentNode = this.element.parentNode;
2743
 
 
2744
 
                if (oParentNode != oIFrame.parentNode) {
2745
 
                    this._addToParent(oParentNode, oIFrame);
2746
 
                }
2747
 
                oIFrame.style.display = "block";
2748
 
            }
2749
 
        },
2750
 
 
2751
 
        /**
2752
 
        * Hides the iframe shim, if it has been enabled.
2753
 
        * @method hideIframe
2754
 
        */
2755
 
        hideIframe: function () {
2756
 
            if (this.iframe) {
2757
 
                this.iframe.style.display = "none";
2758
 
            }
2759
 
        },
2760
 
 
2761
 
        /**
2762
 
        * Syncronizes the size and position of iframe shim to that of its 
2763
 
        * corresponding Overlay instance.
2764
 
        * @method syncIframe
2765
 
        */
2766
 
        syncIframe: function () {
2767
 
 
2768
 
            var oIFrame = this.iframe,
2769
 
                oElement = this.element,
2770
 
                nOffset = Overlay.IFRAME_OFFSET,
2771
 
                nDimensionOffset = (nOffset * 2),
2772
 
                aXY;
2773
 
 
2774
 
            if (oIFrame) {
2775
 
                // Size <iframe>
2776
 
                oIFrame.style.width = (oElement.offsetWidth + nDimensionOffset + "px");
2777
 
                oIFrame.style.height = (oElement.offsetHeight + nDimensionOffset + "px");
2778
 
 
2779
 
                // Position <iframe>
2780
 
                aXY = this.cfg.getProperty("xy");
2781
 
 
2782
 
                if (!Lang.isArray(aXY) || (isNaN(aXY[0]) || isNaN(aXY[1]))) {
2783
 
                    this.syncPosition();
2784
 
                    aXY = this.cfg.getProperty("xy");
2785
 
                }
2786
 
                Dom.setXY(oIFrame, [(aXY[0] - nOffset), (aXY[1] - nOffset)]);
2787
 
            }
2788
 
        },
2789
 
 
2790
 
        /**
2791
 
         * Sets the zindex of the iframe shim, if it exists, based on the zindex of
2792
 
         * the Overlay element. The zindex of the iframe is set to be one less 
2793
 
         * than the Overlay element's zindex.
2794
 
         * 
2795
 
         * <p>NOTE: This method will not bump up the zindex of the Overlay element
2796
 
         * to ensure that the iframe shim has a non-negative zindex.
2797
 
         * If you require the iframe zindex to be 0 or higher, the zindex of 
2798
 
         * the Overlay element should be set to a value greater than 0, before 
2799
 
         * this method is called.
2800
 
         * </p>
2801
 
         * @method stackIframe
2802
 
         */
2803
 
        stackIframe: function () {
2804
 
            if (this.iframe) {
2805
 
                var overlayZ = Dom.getStyle(this.element, "zIndex");
2806
 
                if (!YAHOO.lang.isUndefined(overlayZ) && !isNaN(overlayZ)) {
2807
 
                    Dom.setStyle(this.iframe, "zIndex", (overlayZ - 1));
2808
 
                }
2809
 
            }
2810
 
        },
2811
 
 
2812
 
        /**
2813
 
        * The default event handler fired when the "iframe" property is changed.
2814
 
        * @method configIframe
2815
 
        * @param {String} type The CustomEvent type (usually the property name)
2816
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
2817
 
        * handlers, args[0] will equal the newly applied value for the property.
2818
 
        * @param {Object} obj The scope object. For configuration handlers, 
2819
 
        * this will usually equal the owner.
2820
 
        */
2821
 
        configIframe: function (type, args, obj) {
2822
 
 
2823
 
            var bIFrame = args[0];
2824
 
 
2825
 
            function createIFrame() {
2826
 
 
2827
 
                var oIFrame = this.iframe,
2828
 
                    oElement = this.element,
2829
 
                    oParent;
2830
 
 
2831
 
                if (!oIFrame) {
2832
 
                    if (!m_oIFrameTemplate) {
2833
 
                        m_oIFrameTemplate = document.createElement("iframe");
2834
 
 
2835
 
                        if (this.isSecure) {
2836
 
                            m_oIFrameTemplate.src = Overlay.IFRAME_SRC;
2837
 
                        }
2838
 
 
2839
 
                        /*
2840
 
                            Set the opacity of the <iframe> to 0 so that it 
2841
 
                            doesn't modify the opacity of any transparent 
2842
 
                            elements that may be on top of it (like a shadow).
2843
 
                        */
2844
 
 
2845
 
                        if (YAHOO.env.ua.ie) {
2846
 
                            m_oIFrameTemplate.style.filter = "alpha(opacity=0)";
2847
 
                            /*
2848
 
                                 Need to set the "frameBorder" property to 0 
2849
 
                                 supress the default <iframe> border in IE.  
2850
 
                                 Setting the CSS "border" property alone 
2851
 
                                 doesn't supress it.
2852
 
                            */
2853
 
                            m_oIFrameTemplate.frameBorder = 0;
2854
 
                        }
2855
 
                        else {
2856
 
                            m_oIFrameTemplate.style.opacity = "0";
2857
 
                        }
2858
 
 
2859
 
                        m_oIFrameTemplate.style.position = "absolute";
2860
 
                        m_oIFrameTemplate.style.border = "none";
2861
 
                        m_oIFrameTemplate.style.margin = "0";
2862
 
                        m_oIFrameTemplate.style.padding = "0";
2863
 
                        m_oIFrameTemplate.style.display = "none";
2864
 
                    }
2865
 
 
2866
 
                    oIFrame = m_oIFrameTemplate.cloneNode(false);
2867
 
                    oParent = oElement.parentNode;
2868
 
 
2869
 
                    var parentNode = oParent || document.body;
2870
 
 
2871
 
                    this._addToParent(parentNode, oIFrame);
2872
 
                    this.iframe = oIFrame;
2873
 
                }
2874
 
 
2875
 
                /*
2876
 
                     Show the <iframe> before positioning it since the "setXY" 
2877
 
                     method of DOM requires the element be in the document 
2878
 
                     and visible.
2879
 
                */
2880
 
                this.showIframe();
2881
 
 
2882
 
                /*
2883
 
                     Syncronize the size and position of the <iframe> to that 
2884
 
                     of the Overlay.
2885
 
                */
2886
 
                this.syncIframe();
2887
 
                this.stackIframe();
2888
 
 
2889
 
                // Add event listeners to update the <iframe> when necessary
2890
 
                if (!this._hasIframeEventListeners) {
2891
 
                    this.showEvent.subscribe(this.showIframe);
2892
 
                    this.hideEvent.subscribe(this.hideIframe);
2893
 
                    this.changeContentEvent.subscribe(this.syncIframe);
2894
 
 
2895
 
                    this._hasIframeEventListeners = true;
2896
 
                }
2897
 
            }
2898
 
 
2899
 
            function onBeforeShow() {
2900
 
                createIFrame.call(this);
2901
 
                this.beforeShowEvent.unsubscribe(onBeforeShow);
2902
 
                this._iframeDeferred = false;
2903
 
            }
2904
 
 
2905
 
            if (bIFrame) { // <iframe> shim is enabled
2906
 
 
2907
 
                if (this.cfg.getProperty("visible")) {
2908
 
                    createIFrame.call(this);
2909
 
                } else {
2910
 
                    if (!this._iframeDeferred) {
2911
 
                        this.beforeShowEvent.subscribe(onBeforeShow);
2912
 
                        this._iframeDeferred = true;
2913
 
                    }
2914
 
                }
2915
 
 
2916
 
            } else {    // <iframe> shim is disabled
2917
 
                this.hideIframe();
2918
 
 
2919
 
                if (this._hasIframeEventListeners) {
2920
 
                    this.showEvent.unsubscribe(this.showIframe);
2921
 
                    this.hideEvent.unsubscribe(this.hideIframe);
2922
 
                    this.changeContentEvent.unsubscribe(this.syncIframe);
2923
 
 
2924
 
                    this._hasIframeEventListeners = false;
2925
 
                }
2926
 
            }
2927
 
        },
2928
 
 
2929
 
        /**
2930
 
         * Set's the container's XY value from DOM if not already set.
2931
 
         * 
2932
 
         * Differs from syncPosition, in that the XY value is only sync'd with DOM if 
2933
 
         * not already set. The method also refire's the XY config property event, so any
2934
 
         * beforeMove, Move event listeners are invoked.
2935
 
         * 
2936
 
         * @method _primeXYFromDOM
2937
 
         * @protected
2938
 
         */
2939
 
        _primeXYFromDOM : function() {
2940
 
            if (YAHOO.lang.isUndefined(this.cfg.getProperty("xy"))) {
2941
 
                // Set CFG XY based on DOM XY
2942
 
                this.syncPosition();
2943
 
                // Account for XY being set silently in syncPosition (no moveTo fired/called)
2944
 
                this.cfg.refireEvent("xy");
2945
 
                this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);
2946
 
            }
2947
 
        },
2948
 
 
2949
 
        /**
2950
 
        * The default event handler fired when the "constraintoviewport" 
2951
 
        * property is changed.
2952
 
        * @method configConstrainToViewport
2953
 
        * @param {String} type The CustomEvent type (usually the property name)
2954
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
2955
 
        * handlers, args[0] will equal the newly applied value for 
2956
 
        * the property.
2957
 
        * @param {Object} obj The scope object. For configuration handlers, 
2958
 
        * this will usually equal the owner.
2959
 
        */
2960
 
        configConstrainToViewport: function (type, args, obj) {
2961
 
            var val = args[0];
2962
 
 
2963
 
            if (val) {
2964
 
                if (! Config.alreadySubscribed(this.beforeMoveEvent, this.enforceConstraints, this)) {
2965
 
                    this.beforeMoveEvent.subscribe(this.enforceConstraints, this, true);
2966
 
                }
2967
 
                if (! Config.alreadySubscribed(this.beforeShowEvent, this._primeXYFromDOM)) {
2968
 
                    this.beforeShowEvent.subscribe(this._primeXYFromDOM);
2969
 
                }
2970
 
            } else {
2971
 
                this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);
2972
 
                this.beforeMoveEvent.unsubscribe(this.enforceConstraints, this);
2973
 
            }
2974
 
        },
2975
 
 
2976
 
         /**
2977
 
        * The default event handler fired when the "context" property 
2978
 
        * is changed.
2979
 
        * @method configContext
2980
 
        * @param {String} type The CustomEvent type (usually the property name)
2981
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
2982
 
        * handlers, args[0] will equal the newly applied value for the property.
2983
 
        * @param {Object} obj The scope object. For configuration handlers, 
2984
 
        * this will usually equal the owner.
2985
 
        */
2986
 
        configContext: function (type, args, obj) {
2987
 
    
2988
 
            var contextArgs = args[0],
2989
 
                contextEl,
2990
 
                elementMagnetCorner,
2991
 
                contextMagnetCorner;
2992
 
 
2993
 
            if (contextArgs) {
2994
 
                contextEl = contextArgs[0];
2995
 
                elementMagnetCorner = contextArgs[1];
2996
 
                contextMagnetCorner = contextArgs[2];
2997
 
                
2998
 
                if (contextEl) {
2999
 
                    if (typeof contextEl == "string") {
3000
 
                        this.cfg.setProperty("context", 
3001
 
                            [document.getElementById(contextEl), 
3002
 
                                elementMagnetCorner, contextMagnetCorner], 
3003
 
                                true);
3004
 
                    }
3005
 
                    
3006
 
                    if (elementMagnetCorner && contextMagnetCorner) {
3007
 
                        this.align(elementMagnetCorner, contextMagnetCorner);
3008
 
                    }
3009
 
                }
3010
 
            }
3011
 
        },
3012
 
 
3013
 
        // END BUILT-IN PROPERTY EVENT HANDLERS //
3014
 
        /**
3015
 
        * Aligns the Overlay to its context element using the specified corner 
3016
 
        * points (represented by the constants TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, 
3017
 
        * and BOTTOM_RIGHT.
3018
 
        * @method align
3019
 
        * @param {String} elementAlign  The String representing the corner of 
3020
 
        * the Overlay that should be aligned to the context element
3021
 
        * @param {String} contextAlign  The corner of the context element 
3022
 
        * that the elementAlign corner should stick to.
3023
 
        */
3024
 
        align: function (elementAlign, contextAlign) {
3025
 
 
3026
 
            var contextArgs = this.cfg.getProperty("context"),
3027
 
                me = this,
3028
 
                context,
3029
 
                element,
3030
 
                contextRegion;
3031
 
 
3032
 
            function doAlign(v, h) {
3033
 
    
3034
 
                switch (elementAlign) {
3035
 
    
3036
 
                case Overlay.TOP_LEFT:
3037
 
                    me.moveTo(h, v);
3038
 
                    break;
3039
 
    
3040
 
                case Overlay.TOP_RIGHT:
3041
 
                    me.moveTo((h - element.offsetWidth), v);
3042
 
                    break;
3043
 
    
3044
 
                case Overlay.BOTTOM_LEFT:
3045
 
                    me.moveTo(h, (v - element.offsetHeight));
3046
 
                    break;
3047
 
    
3048
 
                case Overlay.BOTTOM_RIGHT:
3049
 
                    me.moveTo((h - element.offsetWidth), 
3050
 
                        (v - element.offsetHeight));
3051
 
                    break;
3052
 
                }
3053
 
            }
3054
 
    
3055
 
    
3056
 
            if (contextArgs) {
3057
 
            
3058
 
                context = contextArgs[0];
3059
 
                element = this.element;
3060
 
                me = this;
3061
 
                
3062
 
                if (! elementAlign) {
3063
 
                    elementAlign = contextArgs[1];
3064
 
                }
3065
 
                
3066
 
                if (! contextAlign) {
3067
 
                    contextAlign = contextArgs[2];
3068
 
                }
3069
 
                
3070
 
                if (element && context) {
3071
 
                    contextRegion = Dom.getRegion(context);
3072
 
 
3073
 
                    switch (contextAlign) {
3074
 
    
3075
 
                    case Overlay.TOP_LEFT:
3076
 
                        doAlign(contextRegion.top, contextRegion.left);
3077
 
                        break;
3078
 
    
3079
 
                    case Overlay.TOP_RIGHT:
3080
 
                        doAlign(contextRegion.top, contextRegion.right);
3081
 
                        break;
3082
 
    
3083
 
                    case Overlay.BOTTOM_LEFT:
3084
 
                        doAlign(contextRegion.bottom, contextRegion.left);
3085
 
                        break;
3086
 
    
3087
 
                    case Overlay.BOTTOM_RIGHT:
3088
 
                        doAlign(contextRegion.bottom, contextRegion.right);
3089
 
                        break;
3090
 
                    }
3091
 
    
3092
 
                }
3093
 
    
3094
 
            }
3095
 
            
3096
 
        },
3097
 
 
3098
 
        /**
3099
 
        * The default event handler executed when the moveEvent is fired, if the 
3100
 
        * "constraintoviewport" is set to true.
3101
 
        * @method enforceConstraints
3102
 
        * @param {String} type The CustomEvent type (usually the property name)
3103
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
3104
 
        * handlers, args[0] will equal the newly applied value for the property.
3105
 
        * @param {Object} obj The scope object. For configuration handlers, 
3106
 
        * this will usually equal the owner.
3107
 
        */
3108
 
        enforceConstraints: function (type, args, obj) {
3109
 
            var pos = args[0];
3110
 
            var cXY = this.getConstrainedXY(pos[0], pos[1]);
3111
 
            this.cfg.setProperty("x", cXY[0], true);
3112
 
            this.cfg.setProperty("y", cXY[1], true);
3113
 
            this.cfg.setProperty("xy", cXY, true);
3114
 
        },
3115
 
 
3116
 
        /**
3117
 
         * Given x, y coordinate values, returns the calculated coordinates required to 
3118
 
         * position the Overlay if it is to be constrained to the viewport, based on the 
3119
 
         * current element size, viewport dimensions and scroll values.
3120
 
         *
3121
 
         * @param {Number} x The X coordinate value to be constrained
3122
 
         * @param {Number} y The Y coordinate value to be constrained
3123
 
         * @return {Array} The constrained x and y coordinates at index 0 and 1 respectively;
3124
 
         */
3125
 
        getConstrainedXY: function(x, y) {
3126
 
 
3127
 
            var nViewportOffset = Overlay.VIEWPORT_OFFSET,
3128
 
                viewPortWidth = Dom.getViewportWidth(),
3129
 
                viewPortHeight = Dom.getViewportHeight(),
3130
 
                offsetHeight = this.element.offsetHeight,
3131
 
                offsetWidth = this.element.offsetWidth,
3132
 
                scrollX = Dom.getDocumentScrollLeft(),
3133
 
                scrollY = Dom.getDocumentScrollTop();
3134
 
 
3135
 
            var xNew = x;
3136
 
            var yNew = y;
3137
 
 
3138
 
            if (offsetWidth + nViewportOffset < viewPortWidth) {
3139
 
 
3140
 
                var leftConstraint = scrollX + nViewportOffset;
3141
 
                var rightConstraint = scrollX + viewPortWidth - offsetWidth - nViewportOffset;
3142
 
 
3143
 
                if (x < leftConstraint) {
3144
 
                    xNew = leftConstraint;
3145
 
                } else if (x > rightConstraint) {
3146
 
                    xNew = rightConstraint;
3147
 
                }
3148
 
            } else {
3149
 
                xNew = nViewportOffset + scrollX;
3150
 
            }
3151
 
 
3152
 
            if (offsetHeight + nViewportOffset < viewPortHeight) {
3153
 
 
3154
 
                var topConstraint = scrollY + nViewportOffset;
3155
 
                var bottomConstraint = scrollY + viewPortHeight - offsetHeight - nViewportOffset;
3156
 
 
3157
 
                if (y < topConstraint) {
3158
 
                    yNew  = topConstraint;
3159
 
                } else if (y  > bottomConstraint) {
3160
 
                    yNew  = bottomConstraint;
3161
 
                }
3162
 
            } else {
3163
 
                yNew = nViewportOffset + scrollY;
3164
 
            }
3165
 
 
3166
 
            return [xNew, yNew];
3167
 
        },
3168
 
 
3169
 
        /**
3170
 
        * Centers the container in the viewport.
3171
 
        * @method center
3172
 
        */
3173
 
        center: function () {
3174
 
 
3175
 
            var nViewportOffset = Overlay.VIEWPORT_OFFSET,
3176
 
                elementWidth = this.element.offsetWidth,
3177
 
                elementHeight = this.element.offsetHeight,
3178
 
                viewPortWidth = Dom.getViewportWidth(),
3179
 
                viewPortHeight = Dom.getViewportHeight(),
3180
 
                x,
3181
 
                y;
3182
 
 
3183
 
            if (elementWidth < viewPortWidth) {
3184
 
                x = (viewPortWidth / 2) - (elementWidth / 2) + Dom.getDocumentScrollLeft();
3185
 
            } else {
3186
 
                x = nViewportOffset + Dom.getDocumentScrollLeft();
3187
 
            }
3188
 
 
3189
 
            if (elementHeight < viewPortHeight) {
3190
 
                y = (viewPortHeight / 2) - (elementHeight / 2) + Dom.getDocumentScrollTop();
3191
 
            } else {
3192
 
                y = nViewportOffset + Dom.getDocumentScrollTop();
3193
 
            }
3194
 
 
3195
 
            this.cfg.setProperty("xy", [parseInt(x, 10), parseInt(y, 10)]);
3196
 
            this.cfg.refireEvent("iframe");
3197
 
        },
3198
 
 
3199
 
        /**
3200
 
        * Synchronizes the Panel's "xy", "x", and "y" properties with the 
3201
 
        * Panel's position in the DOM. This is primarily used to update  
3202
 
        * position information during drag & drop.
3203
 
        * @method syncPosition
3204
 
        */
3205
 
        syncPosition: function () {
3206
 
 
3207
 
            var pos = Dom.getXY(this.element);
3208
 
 
3209
 
            this.cfg.setProperty("x", pos[0], true);
3210
 
            this.cfg.setProperty("y", pos[1], true);
3211
 
            this.cfg.setProperty("xy", pos, true);
3212
 
 
3213
 
        },
3214
 
 
3215
 
        /**
3216
 
        * Event handler fired when the resize monitor element is resized.
3217
 
        * @method onDomResize
3218
 
        * @param {DOMEvent} e The resize DOM event
3219
 
        * @param {Object} obj The scope object
3220
 
        */
3221
 
        onDomResize: function (e, obj) {
3222
 
 
3223
 
            var me = this;
3224
 
 
3225
 
            Overlay.superclass.onDomResize.call(this, e, obj);
3226
 
 
3227
 
            setTimeout(function () {
3228
 
                me.syncPosition();
3229
 
                me.cfg.refireEvent("iframe");
3230
 
                me.cfg.refireEvent("context");
3231
 
            }, 0);
3232
 
    
3233
 
        },
3234
 
 
3235
 
        /**
3236
 
        * Places the Overlay on top of all other instances of 
3237
 
        * YAHOO.widget.Overlay.
3238
 
        * @method bringToTop
3239
 
        */
3240
 
        bringToTop: function () {
3241
 
 
3242
 
            var aOverlays = [],
3243
 
                oElement = this.element;
3244
 
 
3245
 
            function compareZIndexDesc(p_oOverlay1, p_oOverlay2) {
3246
 
 
3247
 
                var sZIndex1 = Dom.getStyle(p_oOverlay1, "zIndex"),
3248
 
                    sZIndex2 = Dom.getStyle(p_oOverlay2, "zIndex"),
3249
 
 
3250
 
                    nZIndex1 = (!sZIndex1 || isNaN(sZIndex1)) ? 0 : parseInt(sZIndex1, 10),
3251
 
                    nZIndex2 = (!sZIndex2 || isNaN(sZIndex2)) ? 0 : parseInt(sZIndex2, 10);
3252
 
 
3253
 
                if (nZIndex1 > nZIndex2) {
3254
 
                    return -1;
3255
 
                } else if (nZIndex1 < nZIndex2) {
3256
 
                    return 1;
3257
 
                } else {
3258
 
                    return 0;
3259
 
                }
3260
 
            }
3261
 
 
3262
 
            function isOverlayElement(p_oElement) {
3263
 
 
3264
 
                var oOverlay = Dom.hasClass(p_oElement, Overlay.CSS_OVERLAY),
3265
 
                    Panel = YAHOO.widget.Panel;
3266
 
 
3267
 
                if (oOverlay && !Dom.isAncestor(oElement, oOverlay)) {
3268
 
                    if (Panel && Dom.hasClass(p_oElement, Panel.CSS_PANEL)) {
3269
 
                        aOverlays[aOverlays.length] = p_oElement.parentNode;
3270
 
                    } else {
3271
 
                        aOverlays[aOverlays.length] = p_oElement;
3272
 
                    }
3273
 
                }
3274
 
            }
3275
 
 
3276
 
            Dom.getElementsBy(isOverlayElement, "DIV", document.body);
3277
 
 
3278
 
            aOverlays.sort(compareZIndexDesc);
3279
 
 
3280
 
            var oTopOverlay = aOverlays[0],
3281
 
                nTopZIndex;
3282
 
 
3283
 
            if (oTopOverlay) {
3284
 
                nTopZIndex = Dom.getStyle(oTopOverlay, "zIndex");
3285
 
 
3286
 
                if (!isNaN(nTopZIndex)) {
3287
 
                    var bRequiresBump = false;
3288
 
 
3289
 
                    if (oTopOverlay != oElement) {
3290
 
                        bRequiresBump = true;
3291
 
                    } else if (aOverlays.length > 1) {
3292
 
                        var nNextZIndex = Dom.getStyle(aOverlays[1], "zIndex");
3293
 
                        // Don't rely on DOM order to stack if 2 overlays are at the same zindex.
3294
 
                        if (!isNaN(nNextZIndex) && (nTopZIndex == nNextZIndex)) {
3295
 
                            bRequiresBump = true;
3296
 
                        }
3297
 
                    }
3298
 
                    if (bRequiresBump) {
3299
 
                        this.cfg.setProperty("zindex", (parseInt(nTopZIndex, 10) + 2));
3300
 
                    }
3301
 
                }
3302
 
            }
3303
 
        },
3304
 
 
3305
 
        /**
3306
 
        * Removes the Overlay element from the DOM and sets all child 
3307
 
        * elements to null.
3308
 
        * @method destroy
3309
 
        */
3310
 
        destroy: function () {
3311
 
 
3312
 
            if (this.iframe) {
3313
 
                this.iframe.parentNode.removeChild(this.iframe);
3314
 
            }
3315
 
 
3316
 
            this.iframe = null;
3317
 
        
3318
 
            Overlay.windowResizeEvent.unsubscribe(
3319
 
                this.doCenterOnDOMEvent, this);
3320
 
    
3321
 
            Overlay.windowScrollEvent.unsubscribe(
3322
 
                this.doCenterOnDOMEvent, this);
3323
 
        
3324
 
            Overlay.superclass.destroy.call(this);
3325
 
        },
3326
 
        
3327
 
        /**
3328
 
        * Returns a String representation of the object.
3329
 
        * @method toString
3330
 
        * @return {String} The string representation of the Overlay.
3331
 
        */
3332
 
        toString: function () {
3333
 
            return "Overlay " + this.id;
3334
 
        }
3335
 
 
3336
 
    });
3337
 
}());
3338
 
 
3339
 
(function () {
3340
 
    
3341
 
    /**
3342
 
    * OverlayManager is used for maintaining the focus status of 
3343
 
    * multiple Overlays.
3344
 
    * @namespace YAHOO.widget
3345
 
    * @namespace YAHOO.widget
3346
 
    * @class OverlayManager
3347
 
    * @constructor
3348
 
    * @param {Array} overlays Optional. A collection of Overlays to register 
3349
 
    * with the manager.
3350
 
    * @param {Object} userConfig  The object literal representing the user 
3351
 
    * configuration of the OverlayManager
3352
 
    */
3353
 
    YAHOO.widget.OverlayManager = function (userConfig) {
3354
 
        this.init(userConfig);
3355
 
    };
3356
 
 
3357
 
    var Overlay = YAHOO.widget.Overlay,
3358
 
        Event = YAHOO.util.Event,
3359
 
        Dom = YAHOO.util.Dom,
3360
 
        Config = YAHOO.util.Config,
3361
 
        CustomEvent = YAHOO.util.CustomEvent,
3362
 
        OverlayManager = YAHOO.widget.OverlayManager;
3363
 
    
3364
 
    /**
3365
 
    * The CSS class representing a focused Overlay
3366
 
    * @property OverlayManager.CSS_FOCUSED
3367
 
    * @static
3368
 
    * @final
3369
 
    * @type String
3370
 
    */
3371
 
    OverlayManager.CSS_FOCUSED = "focused";
3372
 
    
3373
 
    OverlayManager.prototype = {
3374
 
    
3375
 
        /**
3376
 
        * The class's constructor function
3377
 
        * @property contructor
3378
 
        * @type Function
3379
 
        */
3380
 
        constructor: OverlayManager,
3381
 
        
3382
 
        /**
3383
 
        * The array of Overlays that are currently registered
3384
 
        * @property overlays
3385
 
        * @type YAHOO.widget.Overlay[]
3386
 
        */
3387
 
        overlays: null,
3388
 
        
3389
 
        /**
3390
 
        * Initializes the default configuration of the OverlayManager
3391
 
        * @method initDefaultConfig
3392
 
        */
3393
 
        initDefaultConfig: function () {
3394
 
        
3395
 
            /**
3396
 
            * The collection of registered Overlays in use by 
3397
 
            * the OverlayManager
3398
 
            * @config overlays
3399
 
            * @type YAHOO.widget.Overlay[]
3400
 
            * @default null
3401
 
            */
3402
 
            this.cfg.addProperty("overlays", { suppressEvent: true } );
3403
 
        
3404
 
            /**
3405
 
            * The default DOM event that should be used to focus an Overlay
3406
 
            * @config focusevent
3407
 
            * @type String
3408
 
            * @default "mousedown"
3409
 
            */
3410
 
            this.cfg.addProperty("focusevent", { value: "mousedown" } );
3411
 
 
3412
 
        },
3413
 
 
3414
 
        /**
3415
 
        * Initializes the OverlayManager
3416
 
        * @method init
3417
 
        * @param {Overlay[]} overlays Optional. A collection of Overlays to 
3418
 
        * register with the manager.
3419
 
        * @param {Object} userConfig  The object literal representing the user 
3420
 
        * configuration of the OverlayManager
3421
 
        */
3422
 
        init: function (userConfig) {
3423
 
 
3424
 
            /**
3425
 
            * The OverlayManager's Config object used for monitoring 
3426
 
            * configuration properties.
3427
 
            * @property cfg
3428
 
            * @type Config
3429
 
            */
3430
 
            this.cfg = new Config(this);
3431
 
 
3432
 
            this.initDefaultConfig();
3433
 
 
3434
 
            if (userConfig) {
3435
 
                this.cfg.applyConfig(userConfig, true);
3436
 
            }
3437
 
            this.cfg.fireQueue();
3438
 
 
3439
 
            /**
3440
 
            * The currently activated Overlay
3441
 
            * @property activeOverlay
3442
 
            * @private
3443
 
            * @type YAHOO.widget.Overlay
3444
 
            */
3445
 
            var activeOverlay = null;
3446
 
 
3447
 
            /**
3448
 
            * Returns the currently focused Overlay
3449
 
            * @method getActive
3450
 
            * @return {Overlay} The currently focused Overlay
3451
 
            */
3452
 
            this.getActive = function () {
3453
 
                return activeOverlay;
3454
 
            };
3455
 
 
3456
 
            /**
3457
 
            * Focuses the specified Overlay
3458
 
            * @method focus
3459
 
            * @param {Overlay} overlay The Overlay to focus
3460
 
            * @param {String} overlay The id of the Overlay to focus
3461
 
            */
3462
 
            this.focus = function (overlay) {
3463
 
                var o = this.find(overlay);
3464
 
                if (o) {
3465
 
                    if (activeOverlay != o) {
3466
 
                        if (activeOverlay) {
3467
 
                            activeOverlay.blur();
3468
 
                        }
3469
 
                        this.bringToTop(o);
3470
 
 
3471
 
                        activeOverlay = o;
3472
 
 
3473
 
                        Dom.addClass(activeOverlay.element, 
3474
 
                            OverlayManager.CSS_FOCUSED);
3475
 
 
3476
 
                        o.focusEvent.fire();
3477
 
                    }
3478
 
                }
3479
 
            };
3480
 
        
3481
 
            /**
3482
 
            * Removes the specified Overlay from the manager
3483
 
            * @method remove
3484
 
            * @param {Overlay} overlay The Overlay to remove
3485
 
            * @param {String} overlay The id of the Overlay to remove
3486
 
            */
3487
 
            this.remove = function (overlay) {
3488
 
                var o = this.find(overlay), 
3489
 
                        originalZ;
3490
 
                if (o) {
3491
 
                    if (activeOverlay == o) {
3492
 
                        activeOverlay = null;
3493
 
                    }
3494
 
 
3495
 
                    var bDestroyed = (o.element === null && o.cfg === null) ? true : false;
3496
 
 
3497
 
                    if (!bDestroyed) {
3498
 
                        // Set it's zindex so that it's sorted to the end.
3499
 
                        originalZ = Dom.getStyle(o.element, "zIndex");
3500
 
                        o.cfg.setProperty("zIndex", -1000, true);
3501
 
                    }
3502
 
 
3503
 
                    this.overlays.sort(this.compareZIndexDesc);
3504
 
                    this.overlays = this.overlays.slice(0, (this.overlays.length - 1));
3505
 
 
3506
 
                    o.hideEvent.unsubscribe(o.blur);
3507
 
                    o.destroyEvent.unsubscribe(this._onOverlayDestroy, o);
3508
 
 
3509
 
                    if (!bDestroyed) {
3510
 
                        Event.removeListener(o.element, 
3511
 
                                    this.cfg.getProperty("focusevent"), 
3512
 
                                    this._onOverlayElementFocus);
3513
 
 
3514
 
                        o.cfg.setProperty("zIndex", originalZ, true);
3515
 
                        o.cfg.setProperty("manager", null);
3516
 
                    }
3517
 
 
3518
 
                    o.focusEvent.unsubscribeAll();
3519
 
                    o.blurEvent.unsubscribeAll();
3520
 
 
3521
 
                    o.focusEvent = null;
3522
 
                    o.blurEvent = null;
3523
 
 
3524
 
                    o.focus = null;
3525
 
                    o.blur = null;
3526
 
                }
3527
 
            };
3528
 
 
3529
 
            /**
3530
 
            * Removes focus from all registered Overlays in the manager
3531
 
            * @method blurAll
3532
 
            */
3533
 
            this.blurAll = function () {
3534
 
    
3535
 
                var nOverlays = this.overlays.length,
3536
 
                    i;
3537
 
 
3538
 
                if (nOverlays > 0) {
3539
 
                    i = nOverlays - 1;
3540
 
 
3541
 
                    do {
3542
 
                        this.overlays[i].blur();
3543
 
                    }
3544
 
                    while(i--);
3545
 
                }
3546
 
            };
3547
 
        
3548
 
            this._onOverlayBlur = function (p_sType, p_aArgs) {
3549
 
                activeOverlay = null;
3550
 
            };
3551
 
        
3552
 
            var overlays = this.cfg.getProperty("overlays");
3553
 
        
3554
 
            if (! this.overlays) {
3555
 
                this.overlays = [];
3556
 
            }
3557
 
        
3558
 
            if (overlays) {
3559
 
                this.register(overlays);
3560
 
                this.overlays.sort(this.compareZIndexDesc);
3561
 
            }
3562
 
        },
3563
 
        
3564
 
        
3565
 
        /**
3566
 
        * @method _onOverlayElementFocus
3567
 
        * @description Event handler for the DOM event that is used to focus 
3568
 
        * the Overlay instance as specified by the "focusevent" 
3569
 
        * configuration property.
3570
 
        * @private
3571
 
        * @param {Event} p_oEvent Object representing the DOM event 
3572
 
        * object passed back by the event utility (Event).
3573
 
        */
3574
 
        _onOverlayElementFocus: function (p_oEvent) {
3575
 
        
3576
 
            var oTarget = Event.getTarget(p_oEvent),
3577
 
                oClose = this.close;
3578
 
            
3579
 
            if (oClose && (oTarget == oClose || Dom.isAncestor(oClose, oTarget))) {
3580
 
                this.blur();
3581
 
            } else {
3582
 
                this.focus();
3583
 
            }
3584
 
        },
3585
 
        
3586
 
        
3587
 
        /**
3588
 
        * @method _onOverlayDestroy
3589
 
        * @description "destroy" event handler for the Overlay.
3590
 
        * @private
3591
 
        * @param {String} p_sType String representing the name of the event  
3592
 
        * that was fired.
3593
 
        * @param {Array} p_aArgs Array of arguments sent when the event 
3594
 
        * was fired.
3595
 
        * @param {Overlay} p_oOverlay Object representing the menu that 
3596
 
        * fired the event.
3597
 
        */
3598
 
        _onOverlayDestroy: function (p_sType, p_aArgs, p_oOverlay) {
3599
 
            this.remove(p_oOverlay);
3600
 
        },
3601
 
        
3602
 
        /**
3603
 
        * Registers an Overlay or an array of Overlays with the manager. Upon 
3604
 
        * registration, the Overlay receives functions for focus and blur, 
3605
 
        * along with CustomEvents for each.
3606
 
        * @method register
3607
 
        * @param {Overlay} overlay  An Overlay to register with the manager.
3608
 
        * @param {Overlay[]} overlay  An array of Overlays to register with 
3609
 
        * the manager.
3610
 
        * @return {Boolean} True if any Overlays are registered.
3611
 
        */
3612
 
        register: function (overlay) {
3613
 
        
3614
 
            var mgr = this,
3615
 
                zIndex,
3616
 
                regcount,
3617
 
                i,
3618
 
                nOverlays;
3619
 
        
3620
 
            if (overlay instanceof Overlay) {
3621
 
 
3622
 
                overlay.cfg.addProperty("manager", { value: this } );
3623
 
 
3624
 
                overlay.focusEvent = overlay.createEvent("focus");
3625
 
                overlay.focusEvent.signature = CustomEvent.LIST;
3626
 
 
3627
 
                overlay.blurEvent = overlay.createEvent("blur");
3628
 
                overlay.blurEvent.signature = CustomEvent.LIST;
3629
 
        
3630
 
                overlay.focus = function () {
3631
 
                    mgr.focus(this);
3632
 
                };
3633
 
        
3634
 
                overlay.blur = function () {
3635
 
                    if (mgr.getActive() == this) {
3636
 
                        Dom.removeClass(this.element, OverlayManager.CSS_FOCUSED);
3637
 
                        this.blurEvent.fire();
3638
 
                    }
3639
 
                };
3640
 
        
3641
 
                overlay.blurEvent.subscribe(mgr._onOverlayBlur);
3642
 
                overlay.hideEvent.subscribe(overlay.blur);
3643
 
                
3644
 
                overlay.destroyEvent.subscribe(this._onOverlayDestroy, overlay, this);
3645
 
        
3646
 
                Event.on(overlay.element, this.cfg.getProperty("focusevent"), 
3647
 
                            this._onOverlayElementFocus, null, overlay);
3648
 
        
3649
 
                zIndex = Dom.getStyle(overlay.element, "zIndex");
3650
 
 
3651
 
                if (!isNaN(zIndex)) {
3652
 
                    overlay.cfg.setProperty("zIndex", parseInt(zIndex, 10));
3653
 
                } else {
3654
 
                    overlay.cfg.setProperty("zIndex", 0);
3655
 
                }
3656
 
 
3657
 
                this.overlays.push(overlay);
3658
 
                this.bringToTop(overlay);
3659
 
 
3660
 
                return true;
3661
 
 
3662
 
            } else if (overlay instanceof Array) {
3663
 
 
3664
 
                regcount = 0;
3665
 
                nOverlays = overlay.length;
3666
 
 
3667
 
                for (i = 0; i < nOverlays; i++) {
3668
 
                    if (this.register(overlay[i])) {
3669
 
                        regcount++;
3670
 
                    }
3671
 
                }
3672
 
 
3673
 
                if (regcount > 0) {
3674
 
                    return true;
3675
 
                }
3676
 
            } else {
3677
 
                return false;
3678
 
            }
3679
 
        },
3680
 
 
3681
 
        /**
3682
 
        * Places the specified Overlay instance on top of all other 
3683
 
        * Overlay instances.
3684
 
        * @method bringToTop
3685
 
        * @param {YAHOO.widget.Overlay} p_oOverlay Object representing an 
3686
 
        * Overlay instance.
3687
 
        * @param {String} p_oOverlay String representing the id of an 
3688
 
        * Overlay instance.
3689
 
        */        
3690
 
        bringToTop: function (p_oOverlay) {
3691
 
 
3692
 
            var oOverlay = this.find(p_oOverlay),
3693
 
                nTopZIndex,
3694
 
                oTopOverlay,
3695
 
                aOverlays;
3696
 
 
3697
 
            if (oOverlay) {
3698
 
 
3699
 
                aOverlays = this.overlays;
3700
 
                aOverlays.sort(this.compareZIndexDesc);
3701
 
 
3702
 
                oTopOverlay = aOverlays[0];
3703
 
 
3704
 
                if (oTopOverlay) {
3705
 
                    nTopZIndex = Dom.getStyle(oTopOverlay.element, "zIndex");
3706
 
 
3707
 
                    if (!isNaN(nTopZIndex)) {
3708
 
 
3709
 
                        var bRequiresBump = false;
3710
 
 
3711
 
                        if (oTopOverlay !== oOverlay) {
3712
 
                            bRequiresBump = true;
3713
 
                        } else if (aOverlays.length > 1) {
3714
 
                            var nNextZIndex = Dom.getStyle(aOverlays[1].element, "zIndex");
3715
 
                            // Don't rely on DOM order to stack if 2 overlays are at the same zindex.
3716
 
                            if (!isNaN(nNextZIndex) && (nTopZIndex == nNextZIndex)) {
3717
 
                                bRequiresBump = true;
3718
 
                            }
3719
 
                        }
3720
 
 
3721
 
                        if (bRequiresBump) {
3722
 
                            oOverlay.cfg.setProperty("zindex", (parseInt(nTopZIndex, 10) + 2));
3723
 
                        }
3724
 
                    }
3725
 
                    aOverlays.sort(this.compareZIndexDesc);
3726
 
                }
3727
 
            }
3728
 
        },
3729
 
 
3730
 
        /**
3731
 
        * Attempts to locate an Overlay by instance or ID.
3732
 
        * @method find
3733
 
        * @param {Overlay} overlay  An Overlay to locate within the manager
3734
 
        * @param {String} overlay  An Overlay id to locate within the manager
3735
 
        * @return {Overlay} The requested Overlay, if found, or null if it 
3736
 
        * cannot be located.
3737
 
        */
3738
 
        find: function (overlay) {
3739
 
 
3740
 
            var aOverlays = this.overlays,
3741
 
                nOverlays = aOverlays.length,
3742
 
                i;
3743
 
 
3744
 
            if (nOverlays > 0) {
3745
 
                i = nOverlays - 1;
3746
 
 
3747
 
                if (overlay instanceof Overlay) {
3748
 
                    do {
3749
 
                        if (aOverlays[i] == overlay) {
3750
 
                            return aOverlays[i];
3751
 
                        }
3752
 
                    }
3753
 
                    while(i--);
3754
 
 
3755
 
                } else if (typeof overlay == "string") {
3756
 
                    do {
3757
 
                        if (aOverlays[i].id == overlay) {
3758
 
                            return aOverlays[i];
3759
 
                        }
3760
 
                    }
3761
 
                    while(i--);
3762
 
                }
3763
 
                return null;
3764
 
            }
3765
 
        },
3766
 
        
3767
 
        /**
3768
 
        * Used for sorting the manager's Overlays by z-index.
3769
 
        * @method compareZIndexDesc
3770
 
        * @private
3771
 
        * @return {Number} 0, 1, or -1, depending on where the Overlay should 
3772
 
        * fall in the stacking order.
3773
 
        */
3774
 
        compareZIndexDesc: function (o1, o2) {
3775
 
 
3776
 
            var zIndex1 = (o1.cfg) ? o1.cfg.getProperty("zIndex") : null, // Sort invalid (destroyed)
3777
 
                zIndex2 = (o2.cfg) ? o2.cfg.getProperty("zIndex") : null; // objects at bottom.
3778
 
 
3779
 
            if (zIndex1 === null && zIndex2 === null) {
3780
 
                return 0;
3781
 
            } else if (zIndex1 === null){
3782
 
                return 1;
3783
 
            } else if (zIndex2 === null) {
3784
 
                return -1;
3785
 
            } else if (zIndex1 > zIndex2) {
3786
 
                return -1;
3787
 
            } else if (zIndex1 < zIndex2) {
3788
 
                return 1;
3789
 
            } else {
3790
 
                return 0;
3791
 
            }
3792
 
        },
3793
 
        
3794
 
        /**
3795
 
        * Shows all Overlays in the manager.
3796
 
        * @method showAll
3797
 
        */
3798
 
        showAll: function () {
3799
 
        
3800
 
            var aOverlays = this.overlays,
3801
 
                nOverlays = aOverlays.length,
3802
 
                i;
3803
 
 
3804
 
            if (nOverlays > 0) {
3805
 
                i = nOverlays - 1;
3806
 
                do {
3807
 
                    aOverlays[i].show();
3808
 
                }
3809
 
                while(i--);
3810
 
            }
3811
 
        },
3812
 
 
3813
 
        /**
3814
 
        * Hides all Overlays in the manager.
3815
 
        * @method hideAll
3816
 
        */
3817
 
        hideAll: function () {
3818
 
        
3819
 
            var aOverlays = this.overlays,
3820
 
                nOverlays = aOverlays.length,
3821
 
                i;
3822
 
 
3823
 
            if (nOverlays > 0) {
3824
 
                i = nOverlays - 1;
3825
 
                do {
3826
 
                    aOverlays[i].hide();
3827
 
                }
3828
 
                while(i--);
3829
 
            }
3830
 
        },
3831
 
 
3832
 
        /**
3833
 
        * Returns a string representation of the object.
3834
 
        * @method toString
3835
 
        * @return {String} The string representation of the OverlayManager
3836
 
        */
3837
 
        toString: function () {
3838
 
            return "OverlayManager";
3839
 
        }
3840
 
    };
3841
 
 
3842
 
}());
3843
 
 
3844
 
(function () {
3845
 
 
3846
 
    /**
3847
 
    * Tooltip is an implementation of Overlay that behaves like an OS tooltip, 
3848
 
    * displaying when the user mouses over a particular element, and 
3849
 
    * disappearing on mouse out.
3850
 
    * @namespace YAHOO.widget
3851
 
    * @class Tooltip
3852
 
    * @extends YAHOO.widget.Overlay
3853
 
    * @constructor
3854
 
    * @param {String} el The element ID representing the Tooltip <em>OR</em>
3855
 
    * @param {HTMLElement} el The element representing the Tooltip
3856
 
    * @param {Object} userConfig The configuration object literal containing 
3857
 
    * the configuration that should be set for this Overlay. See configuration 
3858
 
    * documentation for more details.
3859
 
    */
3860
 
    YAHOO.widget.Tooltip = function (el, userConfig) {
3861
 
        YAHOO.widget.Tooltip.superclass.constructor.call(this, el, userConfig);
3862
 
    };
3863
 
 
3864
 
    var Lang = YAHOO.lang,
3865
 
        Event = YAHOO.util.Event,
3866
 
        CustomEvent = YAHOO.util.CustomEvent,
3867
 
        Dom = YAHOO.util.Dom,
3868
 
        Tooltip = YAHOO.widget.Tooltip,
3869
 
 
3870
 
        m_oShadowTemplate,
3871
 
 
3872
 
        /**
3873
 
        * Constant representing the Tooltip's configuration properties
3874
 
        * @property DEFAULT_CONFIG
3875
 
        * @private
3876
 
        * @final
3877
 
        * @type Object
3878
 
        */
3879
 
        DEFAULT_CONFIG = {
3880
 
 
3881
 
            "PREVENT_OVERLAP": { 
3882
 
                key: "preventoverlap", 
3883
 
                value: true, 
3884
 
                validator: Lang.isBoolean, 
3885
 
                supercedes: ["x", "y", "xy"] 
3886
 
            },
3887
 
 
3888
 
            "SHOW_DELAY": { 
3889
 
                key: "showdelay", 
3890
 
                value: 200, 
3891
 
                validator: Lang.isNumber 
3892
 
            }, 
3893
 
 
3894
 
            "AUTO_DISMISS_DELAY": { 
3895
 
                key: "autodismissdelay", 
3896
 
                value: 5000, 
3897
 
                validator: Lang.isNumber 
3898
 
            }, 
3899
 
 
3900
 
            "HIDE_DELAY": { 
3901
 
                key: "hidedelay", 
3902
 
                value: 250, 
3903
 
                validator: Lang.isNumber 
3904
 
            }, 
3905
 
 
3906
 
            "TEXT": { 
3907
 
                key: "text", 
3908
 
                suppressEvent: true 
3909
 
            }, 
3910
 
 
3911
 
            "CONTAINER": { 
3912
 
                key: "container"
3913
 
            },
3914
 
 
3915
 
            "DISABLED": {
3916
 
                key: "disabled",
3917
 
                value: false,
3918
 
                suppressEvent: true
3919
 
            }
3920
 
        },
3921
 
 
3922
 
        /**
3923
 
        * Constant representing the name of the Tooltip's events
3924
 
        * @property EVENT_TYPES
3925
 
        * @private
3926
 
        * @final
3927
 
        * @type Object
3928
 
        */
3929
 
        EVENT_TYPES = {
3930
 
            "CONTEXT_MOUSE_OVER": "contextMouseOver",
3931
 
            "CONTEXT_MOUSE_OUT": "contextMouseOut",
3932
 
            "CONTEXT_TRIGGER": "contextTrigger"
3933
 
        };
3934
 
 
3935
 
    /**
3936
 
    * Constant representing the Tooltip CSS class
3937
 
    * @property YAHOO.widget.Tooltip.CSS_TOOLTIP
3938
 
    * @static
3939
 
    * @final
3940
 
    * @type String
3941
 
    */
3942
 
    Tooltip.CSS_TOOLTIP = "yui-tt";
3943
 
 
3944
 
    /* 
3945
 
        "hide" event handler that sets a Tooltip instance's "width"
3946
 
        configuration property back to its original value before 
3947
 
        "setWidthToOffsetWidth" was called.
3948
 
    */
3949
 
    function restoreOriginalWidth(p_sType, p_aArgs, p_oObject) {
3950
 
 
3951
 
        var sOriginalWidth = p_oObject[0],
3952
 
            sNewWidth = p_oObject[1],
3953
 
            oConfig = this.cfg,
3954
 
            sCurrentWidth = oConfig.getProperty("width");
3955
 
 
3956
 
        if (sCurrentWidth == sNewWidth) {
3957
 
            oConfig.setProperty("width", sOriginalWidth);
3958
 
        }
3959
 
 
3960
 
        this.unsubscribe("hide", this._onHide, p_oObject);
3961
 
    }
3962
 
 
3963
 
    /* 
3964
 
        "beforeShow" event handler that sets a Tooltip instance's "width"
3965
 
        configuration property to the value of its root HTML 
3966
 
        elements's offsetWidth
3967
 
    */
3968
 
 
3969
 
    function setWidthToOffsetWidth(p_sType, p_aArgs) {
3970
 
 
3971
 
        var oBody = document.body,
3972
 
            oConfig = this.cfg,
3973
 
            sOriginalWidth = oConfig.getProperty("width"),
3974
 
            sNewWidth,
3975
 
            oClone;
3976
 
 
3977
 
        if ((!sOriginalWidth || sOriginalWidth == "auto") && 
3978
 
            (oConfig.getProperty("container") != oBody || 
3979
 
            oConfig.getProperty("x") >= Dom.getViewportWidth() || 
3980
 
            oConfig.getProperty("y") >= Dom.getViewportHeight())) {
3981
 
 
3982
 
            oClone = this.element.cloneNode(true);
3983
 
            oClone.style.visibility = "hidden";
3984
 
            oClone.style.top = "0px";
3985
 
            oClone.style.left = "0px";
3986
 
 
3987
 
            oBody.appendChild(oClone);
3988
 
 
3989
 
            sNewWidth = (oClone.offsetWidth + "px");
3990
 
 
3991
 
            oBody.removeChild(oClone);
3992
 
            oClone = null;
3993
 
 
3994
 
            oConfig.setProperty("width", sNewWidth);
3995
 
            oConfig.refireEvent("xy");
3996
 
 
3997
 
            this.subscribe("hide", restoreOriginalWidth, [(sOriginalWidth || ""), sNewWidth]);
3998
 
        }
3999
 
    }
4000
 
 
4001
 
    // "onDOMReady" that renders the ToolTip
4002
 
 
4003
 
    function onDOMReady(p_sType, p_aArgs, p_oObject) {
4004
 
        this.render(p_oObject);
4005
 
    }
4006
 
 
4007
 
    //  "init" event handler that automatically renders the Tooltip
4008
 
 
4009
 
    function onInit() {
4010
 
        Event.onDOMReady(onDOMReady, this.cfg.getProperty("container"), this);
4011
 
    }
4012
 
 
4013
 
    YAHOO.extend(Tooltip, YAHOO.widget.Overlay, { 
4014
 
 
4015
 
        /**
4016
 
        * The Tooltip initialization method. This method is automatically 
4017
 
        * called by the constructor. A Tooltip is automatically rendered by 
4018
 
        * the init method, and it also is set to be invisible by default, 
4019
 
        * and constrained to viewport by default as well.
4020
 
        * @method init
4021
 
        * @param {String} el The element ID representing the Tooltip <em>OR</em>
4022
 
        * @param {HTMLElement} el The element representing the Tooltip
4023
 
        * @param {Object} userConfig The configuration object literal 
4024
 
        * containing the configuration that should be set for this Tooltip. 
4025
 
        * See configuration documentation for more details.
4026
 
        */
4027
 
        init: function (el, userConfig) {
4028
 
 
4029
 
 
4030
 
            Tooltip.superclass.init.call(this, el);
4031
 
 
4032
 
            this.beforeInitEvent.fire(Tooltip);
4033
 
 
4034
 
            Dom.addClass(this.element, Tooltip.CSS_TOOLTIP);
4035
 
 
4036
 
            if (userConfig) {
4037
 
                this.cfg.applyConfig(userConfig, true);
4038
 
            }
4039
 
 
4040
 
            this.cfg.queueProperty("visible", false);
4041
 
            this.cfg.queueProperty("constraintoviewport", true);
4042
 
 
4043
 
            this.setBody("");
4044
 
 
4045
 
            this.subscribe("beforeShow", setWidthToOffsetWidth);
4046
 
            this.subscribe("init", onInit);
4047
 
            this.subscribe("render", this.onRender);
4048
 
 
4049
 
            this.initEvent.fire(Tooltip);
4050
 
        },
4051
 
 
4052
 
        /**
4053
 
        * Initializes the custom events for Tooltip
4054
 
        * @method initEvents
4055
 
        */
4056
 
        initEvents: function () {
4057
 
 
4058
 
            Tooltip.superclass.initEvents.call(this);
4059
 
            var SIGNATURE = CustomEvent.LIST;
4060
 
 
4061
 
            /**
4062
 
            * CustomEvent fired when user mouses over a context element. Returning false from
4063
 
            * a subscriber to this event will prevent the tooltip from being displayed for
4064
 
            * the current context element.
4065
 
            * 
4066
 
            * @event contextMouseOverEvent
4067
 
            * @param {HTMLElement} context The context element which the user just moused over
4068
 
            * @param {DOMEvent} e The DOM event object, associated with the mouse over
4069
 
            */
4070
 
            this.contextMouseOverEvent = this.createEvent(EVENT_TYPES.CONTEXT_MOUSE_OVER);
4071
 
            this.contextMouseOverEvent.signature = SIGNATURE;
4072
 
 
4073
 
            /**
4074
 
            * CustomEvent fired when the user mouses out of a context element.
4075
 
            * 
4076
 
            * @event contextMouseOutEvent
4077
 
            * @param {HTMLElement} context The context element which the user just moused out of
4078
 
            * @param {DOMEvent} e The DOM event object, associated with the mouse out
4079
 
            */
4080
 
            this.contextMouseOutEvent = this.createEvent(EVENT_TYPES.CONTEXT_MOUSE_OUT);
4081
 
            this.contextMouseOutEvent.signature = SIGNATURE;
4082
 
 
4083
 
            /**
4084
 
            * CustomEvent fired just before the tooltip is displayed for the current context.
4085
 
            * <p>
4086
 
            *  You can subscribe to this event if you need to set up the text for the 
4087
 
            *  tooltip based on the context element for which it is about to be displayed.
4088
 
            * </p>
4089
 
            * <p>This event differs from the beforeShow event in following respects:</p>
4090
 
            * <ol>
4091
 
            *   <li>
4092
 
            *    When moving from one context element to another, if the tooltip is not
4093
 
            *    hidden (the <code>hidedelay</code> is not reached), the beforeShow and Show events will not
4094
 
            *    be fired when the tooltip is displayed for the new context since it is already visible.
4095
 
            *    However the contextTrigger event is always fired before displaying the tooltip for
4096
 
            *    a new context.
4097
 
            *   </li>
4098
 
            *   <li>
4099
 
            *    The trigger event provides access to the context element, allowing you to 
4100
 
            *    set the text of the tooltip based on context element for which the tooltip is
4101
 
            *    triggered.
4102
 
            *   </li>
4103
 
            * </ol>
4104
 
            * <p>
4105
 
            *  It is not possible to prevent the tooltip from being displayed
4106
 
            *  using this event. You can use the contextMouseOverEvent if you need to prevent
4107
 
            *  the tooltip from being displayed.
4108
 
            * </p>
4109
 
            * @event contextTriggerEvent
4110
 
            * @param {HTMLElement} context The context element for which the tooltip is triggered
4111
 
            */
4112
 
            this.contextTriggerEvent = this.createEvent(EVENT_TYPES.CONTEXT_TRIGGER);
4113
 
            this.contextTriggerEvent.signature = SIGNATURE;
4114
 
        },
4115
 
 
4116
 
        /**
4117
 
        * Initializes the class's configurable properties which can be 
4118
 
        * changed using the Overlay's Config object (cfg).
4119
 
        * @method initDefaultConfig
4120
 
        */
4121
 
        initDefaultConfig: function () {
4122
 
 
4123
 
            Tooltip.superclass.initDefaultConfig.call(this);
4124
 
 
4125
 
            /**
4126
 
            * Specifies whether the Tooltip should be kept from overlapping 
4127
 
            * its context element.
4128
 
            * @config preventoverlap
4129
 
            * @type Boolean
4130
 
            * @default true
4131
 
            */
4132
 
            this.cfg.addProperty(DEFAULT_CONFIG.PREVENT_OVERLAP.key, {
4133
 
                value: DEFAULT_CONFIG.PREVENT_OVERLAP.value, 
4134
 
                validator: DEFAULT_CONFIG.PREVENT_OVERLAP.validator, 
4135
 
                supercedes: DEFAULT_CONFIG.PREVENT_OVERLAP.supercedes
4136
 
            });
4137
 
 
4138
 
            /**
4139
 
            * The number of milliseconds to wait before showing a Tooltip 
4140
 
            * on mouseover.
4141
 
            * @config showdelay
4142
 
            * @type Number
4143
 
            * @default 200
4144
 
            */
4145
 
            this.cfg.addProperty(DEFAULT_CONFIG.SHOW_DELAY.key, {
4146
 
                handler: this.configShowDelay,
4147
 
                value: 200, 
4148
 
                validator: DEFAULT_CONFIG.SHOW_DELAY.validator
4149
 
            });
4150
 
 
4151
 
            /**
4152
 
            * The number of milliseconds to wait before automatically 
4153
 
            * dismissing a Tooltip after the mouse has been resting on the 
4154
 
            * context element.
4155
 
            * @config autodismissdelay
4156
 
            * @type Number
4157
 
            * @default 5000
4158
 
            */
4159
 
            this.cfg.addProperty(DEFAULT_CONFIG.AUTO_DISMISS_DELAY.key, {
4160
 
                handler: this.configAutoDismissDelay,
4161
 
                value: DEFAULT_CONFIG.AUTO_DISMISS_DELAY.value,
4162
 
                validator: DEFAULT_CONFIG.AUTO_DISMISS_DELAY.validator
4163
 
            });
4164
 
 
4165
 
            /**
4166
 
            * The number of milliseconds to wait before hiding a Tooltip 
4167
 
            * on mouseover.
4168
 
            * @config hidedelay
4169
 
            * @type Number
4170
 
            * @default 250
4171
 
            */
4172
 
            this.cfg.addProperty(DEFAULT_CONFIG.HIDE_DELAY.key, {
4173
 
                handler: this.configHideDelay,
4174
 
                value: DEFAULT_CONFIG.HIDE_DELAY.value, 
4175
 
                validator: DEFAULT_CONFIG.HIDE_DELAY.validator
4176
 
            });
4177
 
 
4178
 
            /**
4179
 
            * Specifies the Tooltip's text. 
4180
 
            * @config text
4181
 
            * @type String
4182
 
            * @default null
4183
 
            */
4184
 
            this.cfg.addProperty(DEFAULT_CONFIG.TEXT.key, {
4185
 
                handler: this.configText,
4186
 
                suppressEvent: DEFAULT_CONFIG.TEXT.suppressEvent
4187
 
            });
4188
 
 
4189
 
            /**
4190
 
            * Specifies the container element that the Tooltip's markup 
4191
 
            * should be rendered into.
4192
 
            * @config container
4193
 
            * @type HTMLElement/String
4194
 
            * @default document.body
4195
 
            */
4196
 
            this.cfg.addProperty(DEFAULT_CONFIG.CONTAINER.key, {
4197
 
                handler: this.configContainer,
4198
 
                value: document.body
4199
 
            });
4200
 
 
4201
 
            /**
4202
 
            * Specifies whether or not the tooltip is disabled. Disabled tooltips
4203
 
            * will not be displayed. If the tooltip is driven by the title attribute
4204
 
            * of the context element, the title attribute will still be removed for 
4205
 
            * disabled tooltips, to prevent default tooltip behavior.
4206
 
            * 
4207
 
            * @config disabled
4208
 
            * @type Boolean
4209
 
            * @default false
4210
 
            */
4211
 
            this.cfg.addProperty(DEFAULT_CONFIG.DISABLED.key, {
4212
 
                handler: this.configContainer,
4213
 
                value: DEFAULT_CONFIG.DISABLED.value,
4214
 
                supressEvent: DEFAULT_CONFIG.DISABLED.suppressEvent
4215
 
            });
4216
 
 
4217
 
            /**
4218
 
            * Specifies the element or elements that the Tooltip should be 
4219
 
            * anchored to on mouseover.
4220
 
            * @config context
4221
 
            * @type HTMLElement[]/String[]
4222
 
            * @default null
4223
 
            */ 
4224
 
 
4225
 
            /**
4226
 
            * String representing the width of the Tooltip.  <em>Please note:
4227
 
            * </em> As of version 2.3 if either no value or a value of "auto" 
4228
 
            * is specified, and the Toolip's "container" configuration property
4229
 
            * is set to something other than <code>document.body</code> or 
4230
 
            * its "context" element resides outside the immediately visible 
4231
 
            * portion of the document, the width of the Tooltip will be 
4232
 
            * calculated based on the offsetWidth of its root HTML and set just 
4233
 
            * before it is made visible.  The original value will be 
4234
 
            * restored when the Tooltip is hidden. This ensures the Tooltip is 
4235
 
            * rendered at a usable width.  For more information see 
4236
 
            * SourceForge bug #1685496 and SourceForge 
4237
 
            * bug #1735423.
4238
 
            * @config width
4239
 
            * @type String
4240
 
            * @default null
4241
 
            */
4242
 
        
4243
 
        },
4244
 
        
4245
 
        // BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
4246
 
        
4247
 
        /**
4248
 
        * The default event handler fired when the "text" property is changed.
4249
 
        * @method configText
4250
 
        * @param {String} type The CustomEvent type (usually the property name)
4251
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
4252
 
        * handlers, args[0] will equal the newly applied value for the property.
4253
 
        * @param {Object} obj The scope object. For configuration handlers, 
4254
 
        * this will usually equal the owner.
4255
 
        */
4256
 
        configText: function (type, args, obj) {
4257
 
            var text = args[0];
4258
 
            if (text) {
4259
 
                this.setBody(text);
4260
 
            }
4261
 
        },
4262
 
        
4263
 
        /**
4264
 
        * The default event handler fired when the "container" property 
4265
 
        * is changed.
4266
 
        * @method configContainer
4267
 
        * @param {String} type The CustomEvent type (usually the property name)
4268
 
        * @param {Object[]} args The CustomEvent arguments. For 
4269
 
        * configuration handlers, args[0] will equal the newly applied value 
4270
 
        * for the property.
4271
 
        * @param {Object} obj The scope object. For configuration handlers,
4272
 
        * this will usually equal the owner.
4273
 
        */
4274
 
        configContainer: function (type, args, obj) {
4275
 
            var container = args[0];
4276
 
 
4277
 
            if (typeof container == 'string') {
4278
 
                this.cfg.setProperty("container", document.getElementById(container), true);
4279
 
            }
4280
 
        },
4281
 
        
4282
 
        /**
4283
 
        * @method _removeEventListeners
4284
 
        * @description Removes all of the DOM event handlers from the HTML
4285
 
        *  element(s) that trigger the display of the tooltip.
4286
 
        * @protected
4287
 
        */
4288
 
        _removeEventListeners: function () {
4289
 
        
4290
 
            var aElements = this._context,
4291
 
                nElements,
4292
 
                oElement,
4293
 
                i;
4294
 
 
4295
 
            if (aElements) {
4296
 
                nElements = aElements.length;
4297
 
                if (nElements > 0) {
4298
 
                    i = nElements - 1;
4299
 
                    do {
4300
 
                        oElement = aElements[i];
4301
 
                        Event.removeListener(oElement, "mouseover", this.onContextMouseOver);
4302
 
                        Event.removeListener(oElement, "mousemove", this.onContextMouseMove);
4303
 
                        Event.removeListener(oElement, "mouseout", this.onContextMouseOut);
4304
 
                    }
4305
 
                    while (i--);
4306
 
                }
4307
 
            }
4308
 
        },
4309
 
        
4310
 
        /**
4311
 
        * The default event handler fired when the "context" property 
4312
 
        * is changed.
4313
 
        * @method configContext
4314
 
        * @param {String} type The CustomEvent type (usually the property name)
4315
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
4316
 
        * handlers, args[0] will equal the newly applied value for the property.
4317
 
        * @param {Object} obj The scope object. For configuration handlers,
4318
 
        * this will usually equal the owner.
4319
 
        */
4320
 
        configContext: function (type, args, obj) {
4321
 
        
4322
 
            var context = args[0],
4323
 
                aElements,
4324
 
                nElements,
4325
 
                oElement,
4326
 
                i;
4327
 
 
4328
 
            if (context) {
4329
 
 
4330
 
                // Normalize parameter into an array
4331
 
                if (! (context instanceof Array)) {
4332
 
                    if (typeof context == "string") {
4333
 
                        this.cfg.setProperty("context", [document.getElementById(context)], true);
4334
 
                    } else { // Assuming this is an element
4335
 
                        this.cfg.setProperty("context", [context], true);
4336
 
                    }
4337
 
                    context = this.cfg.getProperty("context");
4338
 
                }
4339
 
 
4340
 
                // Remove any existing mouseover/mouseout listeners
4341
 
                this._removeEventListeners();
4342
 
 
4343
 
                // Add mouseover/mouseout listeners to context elements
4344
 
                this._context = context;
4345
 
 
4346
 
                aElements = this._context;
4347
 
 
4348
 
                if (aElements) {
4349
 
                    nElements = aElements.length;
4350
 
                    if (nElements > 0) {
4351
 
                        i = nElements - 1;
4352
 
                        do {
4353
 
                            oElement = aElements[i];
4354
 
                            Event.on(oElement, "mouseover", this.onContextMouseOver, this);
4355
 
                            Event.on(oElement, "mousemove", this.onContextMouseMove, this);
4356
 
                            Event.on(oElement, "mouseout", this.onContextMouseOut, this);
4357
 
                        }
4358
 
                        while (i--);
4359
 
                    }
4360
 
                }
4361
 
            }
4362
 
        },
4363
 
 
4364
 
        // END BUILT-IN PROPERTY EVENT HANDLERS //
4365
 
 
4366
 
        // BEGIN BUILT-IN DOM EVENT HANDLERS //
4367
 
 
4368
 
        /**
4369
 
        * The default event handler fired when the user moves the mouse while 
4370
 
        * over the context element.
4371
 
        * @method onContextMouseMove
4372
 
        * @param {DOMEvent} e The current DOM event
4373
 
        * @param {Object} obj The object argument
4374
 
        */
4375
 
        onContextMouseMove: function (e, obj) {
4376
 
            obj.pageX = Event.getPageX(e);
4377
 
            obj.pageY = Event.getPageY(e);
4378
 
        },
4379
 
 
4380
 
        /**
4381
 
        * The default event handler fired when the user mouses over the 
4382
 
        * context element.
4383
 
        * @method onContextMouseOver
4384
 
        * @param {DOMEvent} e The current DOM event
4385
 
        * @param {Object} obj The object argument
4386
 
        */
4387
 
        onContextMouseOver: function (e, obj) {
4388
 
            var context = this;
4389
 
 
4390
 
            if (context.title) {
4391
 
                obj._tempTitle = context.title;
4392
 
                context.title = "";
4393
 
            }
4394
 
 
4395
 
            // Fire first, to honor disabled set in the listner
4396
 
            if (obj.fireEvent("contextMouseOver", context, e) !== false 
4397
 
                    && !obj.cfg.getProperty("disabled")) {
4398
 
 
4399
 
                // Stop the tooltip from being hidden (set on last mouseout)
4400
 
                if (obj.hideProcId) {
4401
 
                    clearTimeout(obj.hideProcId);
4402
 
                    obj.hideProcId = null;
4403
 
                }
4404
 
 
4405
 
                Event.on(context, "mousemove", obj.onContextMouseMove, obj);
4406
 
 
4407
 
                /**
4408
 
                * The unique process ID associated with the thread responsible 
4409
 
                * for showing the Tooltip.
4410
 
                * @type int
4411
 
                */
4412
 
                obj.showProcId = obj.doShow(e, context);
4413
 
            }
4414
 
        },
4415
 
 
4416
 
        /**
4417
 
        * The default event handler fired when the user mouses out of 
4418
 
        * the context element.
4419
 
        * @method onContextMouseOut
4420
 
        * @param {DOMEvent} e The current DOM event
4421
 
        * @param {Object} obj The object argument
4422
 
        */
4423
 
        onContextMouseOut: function (e, obj) {
4424
 
            var el = this;
4425
 
 
4426
 
            if (obj._tempTitle) {
4427
 
                el.title = obj._tempTitle;
4428
 
                obj._tempTitle = null;
4429
 
            }
4430
 
 
4431
 
            if (obj.showProcId) {
4432
 
                clearTimeout(obj.showProcId);
4433
 
                obj.showProcId = null;
4434
 
            }
4435
 
 
4436
 
            if (obj.hideProcId) {
4437
 
                clearTimeout(obj.hideProcId);
4438
 
                obj.hideProcId = null;
4439
 
            }
4440
 
 
4441
 
            obj.fireEvent("contextMouseOut", el, e);
4442
 
 
4443
 
            obj.hideProcId = setTimeout(function () {
4444
 
                obj.hide();
4445
 
            }, obj.cfg.getProperty("hidedelay"));
4446
 
        },
4447
 
 
4448
 
        // END BUILT-IN DOM EVENT HANDLERS //
4449
 
 
4450
 
        /**
4451
 
        * Processes the showing of the Tooltip by setting the timeout delay 
4452
 
        * and offset of the Tooltip.
4453
 
        * @method doShow
4454
 
        * @param {DOMEvent} e The current DOM event
4455
 
        * @return {Number} The process ID of the timeout function associated 
4456
 
        * with doShow
4457
 
        */
4458
 
        doShow: function (e, context) {
4459
 
 
4460
 
            var yOffset = 25,
4461
 
                me = this;
4462
 
 
4463
 
            if (YAHOO.env.ua.opera && context.tagName && 
4464
 
                context.tagName.toUpperCase() == "A") {
4465
 
                yOffset += 12;
4466
 
            }
4467
 
 
4468
 
            return setTimeout(function () {
4469
 
 
4470
 
                var txt = me.cfg.getProperty("text");
4471
 
 
4472
 
                // title does not over-ride text
4473
 
                if (me._tempTitle && (txt === "" || YAHOO.lang.isUndefined(txt) || YAHOO.lang.isNull(txt))) {
4474
 
                    me.setBody(me._tempTitle);
4475
 
                } else {
4476
 
                    me.cfg.refireEvent("text");
4477
 
                }
4478
 
 
4479
 
                me.moveTo(me.pageX, me.pageY + yOffset);
4480
 
 
4481
 
                if (me.cfg.getProperty("preventoverlap")) {
4482
 
                    me.preventOverlap(me.pageX, me.pageY);
4483
 
                }
4484
 
 
4485
 
                Event.removeListener(context, "mousemove", me.onContextMouseMove);
4486
 
 
4487
 
                me.contextTriggerEvent.fire(context);
4488
 
 
4489
 
                me.show();
4490
 
 
4491
 
                me.hideProcId = me.doHide();
4492
 
 
4493
 
            }, this.cfg.getProperty("showdelay"));
4494
 
        },
4495
 
 
4496
 
        /**
4497
 
        * Sets the timeout for the auto-dismiss delay, which by default is 5 
4498
 
        * seconds, meaning that a tooltip will automatically dismiss itself 
4499
 
        * after 5 seconds of being displayed.
4500
 
        * @method doHide
4501
 
        */
4502
 
        doHide: function () {
4503
 
 
4504
 
            var me = this;
4505
 
 
4506
 
 
4507
 
            return setTimeout(function () {
4508
 
 
4509
 
                me.hide();
4510
 
 
4511
 
            }, this.cfg.getProperty("autodismissdelay"));
4512
 
 
4513
 
        },
4514
 
        
4515
 
        /**
4516
 
        * Fired when the Tooltip is moved, this event handler is used to 
4517
 
        * prevent the Tooltip from overlapping with its context element.
4518
 
        * @method preventOverlay
4519
 
        * @param {Number} pageX The x coordinate position of the mouse pointer
4520
 
        * @param {Number} pageY The y coordinate position of the mouse pointer
4521
 
        */
4522
 
        preventOverlap: function (pageX, pageY) {
4523
 
        
4524
 
            var height = this.element.offsetHeight,
4525
 
                mousePoint = new YAHOO.util.Point(pageX, pageY),
4526
 
                elementRegion = Dom.getRegion(this.element);
4527
 
        
4528
 
            elementRegion.top -= 5;
4529
 
            elementRegion.left -= 5;
4530
 
            elementRegion.right += 5;
4531
 
            elementRegion.bottom += 5;
4532
 
        
4533
 
        
4534
 
            if (elementRegion.contains(mousePoint)) {
4535
 
                this.cfg.setProperty("y", (pageY - height - 5));
4536
 
            }
4537
 
        },
4538
 
 
4539
 
 
4540
 
        /**
4541
 
        * @method onRender
4542
 
        * @description "render" event handler for the Tooltip.
4543
 
        * @param {String} p_sType String representing the name of the event  
4544
 
        * that was fired.
4545
 
        * @param {Array} p_aArgs Array of arguments sent when the event 
4546
 
        * was fired.
4547
 
        */
4548
 
        onRender: function (p_sType, p_aArgs) {
4549
 
    
4550
 
            function sizeShadow() {
4551
 
    
4552
 
                var oElement = this.element,
4553
 
                    oShadow = this._shadow;
4554
 
            
4555
 
                if (oShadow) {
4556
 
                    oShadow.style.width = (oElement.offsetWidth + 6) + "px";
4557
 
                    oShadow.style.height = (oElement.offsetHeight + 1) + "px"; 
4558
 
                }
4559
 
            
4560
 
            }
4561
 
 
4562
 
            function addShadowVisibleClass() {
4563
 
                Dom.addClass(this._shadow, "yui-tt-shadow-visible");
4564
 
            }
4565
 
            
4566
 
 
4567
 
            function removeShadowVisibleClass() {
4568
 
                Dom.removeClass(this._shadow, "yui-tt-shadow-visible");
4569
 
            }
4570
 
 
4571
 
            function createShadow() {
4572
 
    
4573
 
                var oShadow = this._shadow,
4574
 
                    oElement,
4575
 
                    Module,
4576
 
                    nIE,
4577
 
                    me;
4578
 
    
4579
 
                if (!oShadow) {
4580
 
    
4581
 
                    oElement = this.element;
4582
 
                    Module = YAHOO.widget.Module;
4583
 
                    nIE = YAHOO.env.ua.ie;
4584
 
                    me = this;
4585
 
 
4586
 
                    if (!m_oShadowTemplate) {
4587
 
                        m_oShadowTemplate = document.createElement("div");
4588
 
                        m_oShadowTemplate.className = "yui-tt-shadow";
4589
 
                    }
4590
 
 
4591
 
                    oShadow = m_oShadowTemplate.cloneNode(false);
4592
 
 
4593
 
                    oElement.appendChild(oShadow);
4594
 
 
4595
 
                    this._shadow = oShadow;
4596
 
 
4597
 
                    addShadowVisibleClass.call(this);
4598
 
 
4599
 
                    this.subscribe("beforeShow", addShadowVisibleClass);
4600
 
                    this.subscribe("beforeHide", removeShadowVisibleClass);
4601
 
 
4602
 
                    if (nIE == 6 || (nIE == 7 && document.compatMode == "BackCompat")) {
4603
 
                        window.setTimeout(function () { 
4604
 
                            sizeShadow.call(me); 
4605
 
                        }, 0);
4606
 
    
4607
 
                        this.cfg.subscribeToConfigEvent("width", sizeShadow);
4608
 
                        this.cfg.subscribeToConfigEvent("height", sizeShadow);
4609
 
                        this.subscribe("changeContent", sizeShadow);
4610
 
 
4611
 
                        Module.textResizeEvent.subscribe(sizeShadow, this, true);
4612
 
                        this.subscribe("destroy", function () {
4613
 
                            Module.textResizeEvent.unsubscribe(sizeShadow, this);
4614
 
                        });
4615
 
                    }
4616
 
                }
4617
 
            }
4618
 
 
4619
 
            function onBeforeShow() {
4620
 
                createShadow.call(this);
4621
 
                this.unsubscribe("beforeShow", onBeforeShow);
4622
 
            }
4623
 
 
4624
 
            if (this.cfg.getProperty("visible")) {
4625
 
                createShadow.call(this);
4626
 
            } else {
4627
 
                this.subscribe("beforeShow", onBeforeShow);
4628
 
            }
4629
 
        
4630
 
        },
4631
 
        
4632
 
        /**
4633
 
        * Removes the Tooltip element from the DOM and sets all child 
4634
 
        * elements to null.
4635
 
        * @method destroy
4636
 
        */
4637
 
        destroy: function () {
4638
 
        
4639
 
            // Remove any existing mouseover/mouseout listeners
4640
 
            this._removeEventListeners();
4641
 
 
4642
 
            Tooltip.superclass.destroy.call(this);  
4643
 
        
4644
 
        },
4645
 
        
4646
 
        /**
4647
 
        * Returns a string representation of the object.
4648
 
        * @method toString
4649
 
        * @return {String} The string representation of the Tooltip
4650
 
        */
4651
 
        toString: function () {
4652
 
            return "Tooltip " + this.id;
4653
 
        }
4654
 
    
4655
 
    });
4656
 
 
4657
 
}());
4658
 
 
4659
 
(function () {
4660
 
 
4661
 
    /**
4662
 
    * Panel is an implementation of Overlay that behaves like an OS window, 
4663
 
    * with a draggable header and an optional close icon at the top right.
4664
 
    * @namespace YAHOO.widget
4665
 
    * @class Panel
4666
 
    * @extends YAHOO.widget.Overlay
4667
 
    * @constructor
4668
 
    * @param {String} el The element ID representing the Panel <em>OR</em>
4669
 
    * @param {HTMLElement} el The element representing the Panel
4670
 
    * @param {Object} userConfig The configuration object literal containing 
4671
 
    * the configuration that should be set for this Panel. See configuration 
4672
 
    * documentation for more details.
4673
 
    */
4674
 
    YAHOO.widget.Panel = function (el, userConfig) {
4675
 
        YAHOO.widget.Panel.superclass.constructor.call(this, el, userConfig);
4676
 
    };
4677
 
 
4678
 
    var Lang = YAHOO.lang,
4679
 
        DD = YAHOO.util.DD,
4680
 
        Dom = YAHOO.util.Dom,
4681
 
        Event = YAHOO.util.Event,
4682
 
        Overlay = YAHOO.widget.Overlay,
4683
 
        CustomEvent = YAHOO.util.CustomEvent,
4684
 
        Config = YAHOO.util.Config,
4685
 
        Panel = YAHOO.widget.Panel,
4686
 
 
4687
 
        m_oMaskTemplate,
4688
 
        m_oUnderlayTemplate,
4689
 
        m_oCloseIconTemplate,
4690
 
 
4691
 
        /**
4692
 
        * Constant representing the name of the Panel's events
4693
 
        * @property EVENT_TYPES
4694
 
        * @private
4695
 
        * @final
4696
 
        * @type Object
4697
 
        */
4698
 
        EVENT_TYPES = {
4699
 
        
4700
 
            "SHOW_MASK": "showMask",
4701
 
            "HIDE_MASK": "hideMask",
4702
 
            "DRAG": "drag"
4703
 
        
4704
 
        },
4705
 
 
4706
 
        /**
4707
 
        * Constant representing the Panel's configuration properties
4708
 
        * @property DEFAULT_CONFIG
4709
 
        * @private
4710
 
        * @final
4711
 
        * @type Object
4712
 
        */
4713
 
        DEFAULT_CONFIG = {
4714
 
 
4715
 
            "CLOSE": { 
4716
 
                key: "close", 
4717
 
                value: true, 
4718
 
                validator: Lang.isBoolean, 
4719
 
                supercedes: ["visible"] 
4720
 
            },
4721
 
 
4722
 
            "DRAGGABLE": { 
4723
 
                key: "draggable", 
4724
 
                value: (DD ? true : false), 
4725
 
                validator: Lang.isBoolean, 
4726
 
                supercedes: ["visible"]  
4727
 
            },
4728
 
 
4729
 
            "DRAG_ONLY" : {
4730
 
                key: "dragonly",
4731
 
                value: false,
4732
 
                validator: Lang.isBoolean,
4733
 
                supercedes: ["draggable"]
4734
 
            },
4735
 
 
4736
 
            "UNDERLAY": { 
4737
 
                key: "underlay", 
4738
 
                value: "shadow", 
4739
 
                supercedes: ["visible"] 
4740
 
            },
4741
 
 
4742
 
            "MODAL": { 
4743
 
                key: "modal", 
4744
 
                value: false, 
4745
 
                validator: Lang.isBoolean, 
4746
 
                supercedes: ["visible", "zindex"]
4747
 
            },
4748
 
 
4749
 
            "KEY_LISTENERS": {
4750
 
                key: "keylisteners",
4751
 
                suppressEvent: true,
4752
 
                supercedes: ["visible"]
4753
 
            }
4754
 
        };
4755
 
 
4756
 
    /**
4757
 
    * Constant representing the default CSS class used for a Panel
4758
 
    * @property YAHOO.widget.Panel.CSS_PANEL
4759
 
    * @static
4760
 
    * @final
4761
 
    * @type String
4762
 
    */
4763
 
    Panel.CSS_PANEL = "yui-panel";
4764
 
    
4765
 
    /**
4766
 
    * Constant representing the default CSS class used for a Panel's 
4767
 
    * wrapping container
4768
 
    * @property YAHOO.widget.Panel.CSS_PANEL_CONTAINER
4769
 
    * @static
4770
 
    * @final
4771
 
    * @type String
4772
 
    */
4773
 
    Panel.CSS_PANEL_CONTAINER = "yui-panel-container";
4774
 
 
4775
 
    // Private CustomEvent listeners
4776
 
 
4777
 
    /* 
4778
 
        "beforeRender" event handler that creates an empty header for a Panel 
4779
 
        instance if its "draggable" configuration property is set to "true" 
4780
 
        and no header has been created.
4781
 
    */
4782
 
 
4783
 
    function createHeader(p_sType, p_aArgs) {
4784
 
        if (!this.header && this.cfg.getProperty("draggable")) {
4785
 
            this.setHeader("&#160;");
4786
 
        }
4787
 
    }
4788
 
 
4789
 
    /* 
4790
 
        "hide" event handler that sets a Panel instance's "width"
4791
 
        configuration property back to its original value before 
4792
 
        "setWidthToOffsetWidth" was called.
4793
 
    */
4794
 
    
4795
 
    function restoreOriginalWidth(p_sType, p_aArgs, p_oObject) {
4796
 
 
4797
 
        var sOriginalWidth = p_oObject[0],
4798
 
            sNewWidth = p_oObject[1],
4799
 
            oConfig = this.cfg,
4800
 
            sCurrentWidth = oConfig.getProperty("width");
4801
 
 
4802
 
        if (sCurrentWidth == sNewWidth) {
4803
 
            oConfig.setProperty("width", sOriginalWidth);
4804
 
        }
4805
 
 
4806
 
        this.unsubscribe("hide", restoreOriginalWidth, p_oObject);
4807
 
    }
4808
 
 
4809
 
    /* 
4810
 
        "beforeShow" event handler that sets a Panel instance's "width"
4811
 
        configuration property to the value of its root HTML 
4812
 
        elements's offsetWidth
4813
 
    */
4814
 
 
4815
 
    function setWidthToOffsetWidth(p_sType, p_aArgs) {
4816
 
 
4817
 
        var nIE = YAHOO.env.ua.ie,
4818
 
            oConfig,
4819
 
            sOriginalWidth,
4820
 
            sNewWidth;
4821
 
 
4822
 
        if (nIE == 6 || (nIE == 7 && document.compatMode == "BackCompat")) {
4823
 
 
4824
 
            oConfig = this.cfg;
4825
 
            sOriginalWidth = oConfig.getProperty("width");
4826
 
            
4827
 
            if (!sOriginalWidth || sOriginalWidth == "auto") {
4828
 
    
4829
 
                sNewWidth = (this.element.offsetWidth + "px");
4830
 
    
4831
 
                oConfig.setProperty("width", sNewWidth);
4832
 
                
4833
 
                this.subscribe("hide", restoreOriginalWidth, 
4834
 
                    [(sOriginalWidth || ""), sNewWidth]);
4835
 
            
4836
 
            }
4837
 
        }
4838
 
    }
4839
 
 
4840
 
    /* 
4841
 
        "focus" event handler for a focuable element.  Used to automatically 
4842
 
        blur the element when it receives focus to ensure that a Panel 
4843
 
        instance's modality is not compromised.
4844
 
    */
4845
 
 
4846
 
    function onElementFocus() {
4847
 
        this.blur();
4848
 
    }
4849
 
 
4850
 
    /* 
4851
 
        "showMask" event handler that adds a "focus" event handler to all
4852
 
        focusable elements in the document to enforce a Panel instance's 
4853
 
        modality from being compromised.
4854
 
    */
4855
 
 
4856
 
    function addFocusEventHandlers(p_sType, p_aArgs) {
4857
 
 
4858
 
        var me = this;
4859
 
 
4860
 
        function isFocusable(el) {
4861
 
 
4862
 
            var sTagName = el.tagName.toUpperCase(),
4863
 
                bFocusable = false;
4864
 
            
4865
 
            switch (sTagName) {
4866
 
            
4867
 
            case "A":
4868
 
            case "BUTTON":
4869
 
            case "SELECT":
4870
 
            case "TEXTAREA":
4871
 
 
4872
 
                if (!Dom.isAncestor(me.element, el)) {
4873
 
                    Event.on(el, "focus", onElementFocus, el, true);
4874
 
                    bFocusable = true;
4875
 
                }
4876
 
 
4877
 
                break;
4878
 
 
4879
 
            case "INPUT":
4880
 
 
4881
 
                if (el.type != "hidden" && 
4882
 
                    !Dom.isAncestor(me.element, el)) {
4883
 
 
4884
 
                    Event.on(el, "focus", onElementFocus, el, true);
4885
 
                    bFocusable = true;
4886
 
 
4887
 
                }
4888
 
 
4889
 
                break;
4890
 
            
4891
 
            }
4892
 
 
4893
 
            return bFocusable;
4894
 
 
4895
 
        }
4896
 
 
4897
 
        this.focusableElements = Dom.getElementsBy(isFocusable);
4898
 
    
4899
 
    }
4900
 
 
4901
 
    /* 
4902
 
        "hideMask" event handler that removes all "focus" event handlers added 
4903
 
        by the "addFocusEventHandlers" method.
4904
 
    */
4905
 
    
4906
 
    function removeFocusEventHandlers(p_sType, p_aArgs) {
4907
 
 
4908
 
        var aElements = this.focusableElements,
4909
 
            nElements = aElements.length,
4910
 
            el2,
4911
 
            i;
4912
 
 
4913
 
        for (i = 0; i < nElements; i++) {
4914
 
            el2 = aElements[i];
4915
 
            Event.removeListener(el2, "focus", onElementFocus);
4916
 
        }
4917
 
 
4918
 
    }
4919
 
 
4920
 
    YAHOO.extend(Panel, Overlay, {
4921
 
 
4922
 
        /**
4923
 
        * The Overlay initialization method, which is executed for Overlay and 
4924
 
        * all of its subclasses. This method is automatically called by the 
4925
 
        * constructor, and  sets up all DOM references for pre-existing markup, 
4926
 
        * and creates required markup if it is not already present.
4927
 
        * @method init
4928
 
        * @param {String} el The element ID representing the Overlay <em>OR</em>
4929
 
        * @param {HTMLElement} el The element representing the Overlay
4930
 
        * @param {Object} userConfig The configuration object literal 
4931
 
        * containing the configuration that should be set for this Overlay. 
4932
 
        * See configuration documentation for more details.
4933
 
        */
4934
 
        init: function (el, userConfig) {
4935
 
    
4936
 
            /*
4937
 
                 Note that we don't pass the user config in here yet because 
4938
 
                 we only want it executed once, at the lowest subclass level
4939
 
            */
4940
 
 
4941
 
            Panel.superclass.init.call(this, el/*, userConfig*/);  
4942
 
 
4943
 
            this.beforeInitEvent.fire(Panel);
4944
 
 
4945
 
            Dom.addClass(this.element, Panel.CSS_PANEL);
4946
 
 
4947
 
            this.buildWrapper();
4948
 
 
4949
 
            if (userConfig) {
4950
 
                this.cfg.applyConfig(userConfig, true);
4951
 
            }
4952
 
 
4953
 
            this.subscribe("showMask", addFocusEventHandlers);
4954
 
            this.subscribe("hideMask", removeFocusEventHandlers);
4955
 
            this.subscribe("beforeRender", createHeader);
4956
 
 
4957
 
            this.initEvent.fire(Panel);
4958
 
        },
4959
 
        
4960
 
        /**
4961
 
        * Initializes the custom events for Module which are fired 
4962
 
        * automatically at appropriate times by the Module class.
4963
 
        */
4964
 
        initEvents: function () {
4965
 
            Panel.superclass.initEvents.call(this);
4966
 
        
4967
 
            var SIGNATURE = CustomEvent.LIST;
4968
 
        
4969
 
            /**
4970
 
            * CustomEvent fired after the modality mask is shown
4971
 
            * @event showMaskEvent
4972
 
            */
4973
 
            this.showMaskEvent = this.createEvent(EVENT_TYPES.SHOW_MASK);
4974
 
            this.showMaskEvent.signature = SIGNATURE;
4975
 
        
4976
 
            /**
4977
 
            * CustomEvent fired after the modality mask is hidden
4978
 
            * @event hideMaskEvent
4979
 
            */
4980
 
            this.hideMaskEvent = this.createEvent(EVENT_TYPES.HIDE_MASK);
4981
 
            this.hideMaskEvent.signature = SIGNATURE;
4982
 
        
4983
 
            /**
4984
 
            * CustomEvent when the Panel is dragged
4985
 
            * @event dragEvent
4986
 
            */
4987
 
            this.dragEvent = this.createEvent(EVENT_TYPES.DRAG);
4988
 
            this.dragEvent.signature = SIGNATURE;
4989
 
        
4990
 
        },
4991
 
        
4992
 
        /**
4993
 
        * Initializes the class's configurable properties which can be changed 
4994
 
        * using the Panel's Config object (cfg).
4995
 
        * @method initDefaultConfig
4996
 
        */
4997
 
        initDefaultConfig: function () {
4998
 
            Panel.superclass.initDefaultConfig.call(this);
4999
 
        
5000
 
            // Add panel config properties //
5001
 
        
5002
 
            /**
5003
 
            * True if the Panel should display a "close" button
5004
 
            * @config close
5005
 
            * @type Boolean
5006
 
            * @default true
5007
 
            */
5008
 
            this.cfg.addProperty(DEFAULT_CONFIG.CLOSE.key, { 
5009
 
                handler: this.configClose, 
5010
 
                value: DEFAULT_CONFIG.CLOSE.value, 
5011
 
                validator: DEFAULT_CONFIG.CLOSE.validator, 
5012
 
                supercedes: DEFAULT_CONFIG.CLOSE.supercedes 
5013
 
            });
5014
 
        
5015
 
            /**
5016
 
            * Boolean specifying if the Panel should be draggable.  The default 
5017
 
            * value is "true" if the Drag and Drop utility is included, 
5018
 
            * otherwise it is "false." <strong>PLEASE NOTE:</strong> There is a 
5019
 
            * known issue in IE 6 (Strict Mode and Quirks Mode) and IE 7 
5020
 
            * (Quirks Mode) where Panels that either don't have a value set for 
5021
 
            * their "width" configuration property, or their "width" 
5022
 
            * configuration property is set to "auto" will only be draggable by
5023
 
            * placing the mouse on the text of the Panel's header element.
5024
 
            * To fix this bug, draggable Panels missing a value for their 
5025
 
            * "width" configuration property, or whose "width" configuration 
5026
 
            * property is set to "auto" will have it set to the value of 
5027
 
            * their root HTML element's offsetWidth before they are made 
5028
 
            * visible.  The calculated width is then removed when the Panel is   
5029
 
            * hidden. <em>This fix is only applied to draggable Panels in IE 6 
5030
 
            * (Strict Mode and Quirks Mode) and IE 7 (Quirks Mode)</em>. For 
5031
 
            * more information on this issue see:
5032
 
            * SourceForge bugs #1726972 and #1589210.
5033
 
            * @config draggable
5034
 
            * @type Boolean
5035
 
            * @default true
5036
 
            */
5037
 
            this.cfg.addProperty(DEFAULT_CONFIG.DRAGGABLE.key, { 
5038
 
                handler: this.configDraggable, 
5039
 
                value: DEFAULT_CONFIG.DRAGGABLE.value, 
5040
 
                validator: DEFAULT_CONFIG.DRAGGABLE.validator, 
5041
 
                supercedes: DEFAULT_CONFIG.DRAGGABLE.supercedes 
5042
 
            });
5043
 
 
5044
 
            /**
5045
 
            * Boolean specifying if the draggable Panel should be drag only, not interacting with drop 
5046
 
            * targets on the page.
5047
 
            * <p>
5048
 
            * When set to true, draggable Panels will not check to see if they are over drop targets,
5049
 
            * or fire the DragDrop events required to support drop target interaction (onDragEnter, 
5050
 
            * onDragOver, onDragOut, onDragDrop etc.).
5051
 
            * If the Panel is not designed to be dropped on any target elements on the page, then this 
5052
 
            * flag can be set to true to improve performance.
5053
 
            * </p>
5054
 
            * <p>
5055
 
            * When set to false, all drop target related events will be fired.
5056
 
            * </p>
5057
 
            * <p>
5058
 
            * The property is set to false by default to maintain backwards compatibility but should be 
5059
 
            * set to true if drop target interaction is not required for the Panel, to improve performance.</p>
5060
 
            * 
5061
 
            * @config dragOnly
5062
 
            * @type Boolean
5063
 
            * @default false
5064
 
            */
5065
 
            this.cfg.addProperty(DEFAULT_CONFIG.DRAG_ONLY.key, { 
5066
 
                value: DEFAULT_CONFIG.DRAG_ONLY.value, 
5067
 
                validator: DEFAULT_CONFIG.DRAG_ONLY.validator, 
5068
 
                supercedes: DEFAULT_CONFIG.DRAG_ONLY.supercedes 
5069
 
            });
5070
 
 
5071
 
            /**
5072
 
            * Sets the type of underlay to display for the Panel. Valid values 
5073
 
            * are "shadow," "matte," and "none".  <strong>PLEASE NOTE:</strong> 
5074
 
            * The creation of the underlay element is deferred until the Panel 
5075
 
            * is initially made visible.  For Gecko-based browsers on Mac
5076
 
            * OS X the underlay elment is always created as it is used as a 
5077
 
            * shim to prevent Aqua scrollbars below a Panel instance from poking 
5078
 
            * through it (See SourceForge bug #836476).
5079
 
            * @config underlay
5080
 
            * @type String
5081
 
            * @default shadow
5082
 
            */
5083
 
            this.cfg.addProperty(DEFAULT_CONFIG.UNDERLAY.key, { 
5084
 
                handler: this.configUnderlay, 
5085
 
                value: DEFAULT_CONFIG.UNDERLAY.value, 
5086
 
                supercedes: DEFAULT_CONFIG.UNDERLAY.supercedes 
5087
 
            });
5088
 
        
5089
 
            /**
5090
 
            * True if the Panel should be displayed in a modal fashion, 
5091
 
            * automatically creating a transparent mask over the document that
5092
 
            * will not be removed until the Panel is dismissed.
5093
 
            * @config modal
5094
 
            * @type Boolean
5095
 
            * @default false
5096
 
            */
5097
 
            this.cfg.addProperty(DEFAULT_CONFIG.MODAL.key, { 
5098
 
                handler: this.configModal, 
5099
 
                value: DEFAULT_CONFIG.MODAL.value,
5100
 
                validator: DEFAULT_CONFIG.MODAL.validator, 
5101
 
                supercedes: DEFAULT_CONFIG.MODAL.supercedes 
5102
 
            });
5103
 
        
5104
 
            /**
5105
 
            * A KeyListener (or array of KeyListeners) that will be enabled 
5106
 
            * when the Panel is shown, and disabled when the Panel is hidden.
5107
 
            * @config keylisteners
5108
 
            * @type YAHOO.util.KeyListener[]
5109
 
            * @default null
5110
 
            */
5111
 
            this.cfg.addProperty(DEFAULT_CONFIG.KEY_LISTENERS.key, { 
5112
 
                handler: this.configKeyListeners, 
5113
 
                suppressEvent: DEFAULT_CONFIG.KEY_LISTENERS.suppressEvent, 
5114
 
                supercedes: DEFAULT_CONFIG.KEY_LISTENERS.supercedes 
5115
 
            });
5116
 
        
5117
 
        },
5118
 
        
5119
 
        // BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
5120
 
        
5121
 
        /**
5122
 
        * The default event handler fired when the "close" property is changed.
5123
 
        * The method controls the appending or hiding of the close icon at the 
5124
 
        * top right of the Panel.
5125
 
        * @method configClose
5126
 
        * @param {String} type The CustomEvent type (usually the property name)
5127
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
5128
 
        * handlers, args[0] will equal the newly applied value for the property.
5129
 
        * @param {Object} obj The scope object. For configuration handlers, 
5130
 
        * this will usually equal the owner.
5131
 
        */
5132
 
        configClose: function (type, args, obj) {
5133
 
 
5134
 
            var val = args[0],
5135
 
                oClose = this.close;
5136
 
        
5137
 
            function doHide(e, obj) {
5138
 
                obj.hide();
5139
 
            }
5140
 
        
5141
 
            if (val) {
5142
 
                if (!oClose) {
5143
 
                    if (!m_oCloseIconTemplate) {
5144
 
                        m_oCloseIconTemplate = document.createElement("span");
5145
 
                        m_oCloseIconTemplate.innerHTML = "&#160;";
5146
 
                        m_oCloseIconTemplate.className = "container-close";
5147
 
                    }
5148
 
 
5149
 
                    oClose = m_oCloseIconTemplate.cloneNode(true);
5150
 
                    this.innerElement.appendChild(oClose);
5151
 
                    Event.on(oClose, "click", doHide, this);
5152
 
                    
5153
 
                    this.close = oClose;
5154
 
 
5155
 
                } else {
5156
 
                    oClose.style.display = "block";
5157
 
                }
5158
 
 
5159
 
            } else {
5160
 
                if (oClose) {
5161
 
                    oClose.style.display = "none";
5162
 
                }
5163
 
            }
5164
 
 
5165
 
        },
5166
 
 
5167
 
        /**
5168
 
        * The default event handler fired when the "draggable" property 
5169
 
        * is changed.
5170
 
        * @method configDraggable
5171
 
        * @param {String} type The CustomEvent type (usually the property name)
5172
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
5173
 
        * handlers, args[0] will equal the newly applied value for the property.
5174
 
        * @param {Object} obj The scope object. For configuration handlers, 
5175
 
        * this will usually equal the owner.
5176
 
        */
5177
 
        configDraggable: function (type, args, obj) {
5178
 
            var val = args[0];
5179
 
 
5180
 
            if (val) {
5181
 
                if (!DD) {
5182
 
                    this.cfg.setProperty("draggable", false);
5183
 
                    return;
5184
 
                }
5185
 
 
5186
 
                if (this.header) {
5187
 
                    Dom.setStyle(this.header, "cursor", "move");
5188
 
                    this.registerDragDrop();
5189
 
                }
5190
 
 
5191
 
                this.subscribe("beforeShow", setWidthToOffsetWidth);
5192
 
 
5193
 
            } else {
5194
 
 
5195
 
                if (this.dd) {
5196
 
                    this.dd.unreg();
5197
 
                }
5198
 
 
5199
 
                if (this.header) {
5200
 
                    Dom.setStyle(this.header,"cursor","auto");
5201
 
                }
5202
 
 
5203
 
                this.unsubscribe("beforeShow", setWidthToOffsetWidth);
5204
 
            }
5205
 
        },
5206
 
      
5207
 
        /**
5208
 
        * The default event handler fired when the "underlay" property 
5209
 
        * is changed.
5210
 
        * @method configUnderlay
5211
 
        * @param {String} type The CustomEvent type (usually the property name)
5212
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
5213
 
        * handlers, args[0] will equal the newly applied value for the property.
5214
 
        * @param {Object} obj The scope object. For configuration handlers, 
5215
 
        * this will usually equal the owner.
5216
 
        */
5217
 
        configUnderlay: function (type, args, obj) {
5218
 
 
5219
 
            var UA = YAHOO.env.ua,
5220
 
                bMacGecko = (this.platform == "mac" && UA.gecko),
5221
 
                bIEQuirks = (UA.ie == 6 || (UA.ie == 7 && document.compatMode == "BackCompat")),
5222
 
                sUnderlay = args[0].toLowerCase(),
5223
 
                oUnderlay = this.underlay,
5224
 
                oElement = this.element;
5225
 
                
5226
 
            function fixWebkitUnderlay() {
5227
 
                // Webkit 419.3 (Safari 2.x) does not update
5228
 
                // it's Render Tree for the Container when content changes. 
5229
 
                // We need to force it to update using this contentChange 
5230
 
                // listener
5231
 
 
5232
 
                // Webkit 523.6 doesn't have this problem and doesn't 
5233
 
                // need the fix
5234
 
                var u = this.underlay;
5235
 
                Dom.addClass(u, "yui-force-redraw");
5236
 
                window.setTimeout(function(){Dom.removeClass(u, "yui-force-redraw");}, 0);
5237
 
            }
5238
 
 
5239
 
            function createUnderlay() {
5240
 
                var bNew = false;
5241
 
                if (!oUnderlay) { // create if not already in DOM
5242
 
 
5243
 
                    if (!m_oUnderlayTemplate) {
5244
 
                        m_oUnderlayTemplate = document.createElement("div");
5245
 
                        m_oUnderlayTemplate.className = "underlay";
5246
 
                    }
5247
 
 
5248
 
                    oUnderlay = m_oUnderlayTemplate.cloneNode(false);
5249
 
                    this.element.appendChild(oUnderlay);
5250
 
 
5251
 
                    this.underlay = oUnderlay;
5252
 
 
5253
 
                    if (bIEQuirks) {
5254
 
                        this.sizeUnderlay();
5255
 
                        this.cfg.subscribeToConfigEvent("width", this.sizeUnderlay);
5256
 
                        this.cfg.subscribeToConfigEvent("height",this.sizeUnderlay);
5257
 
                        this.changeContentEvent.subscribe(this.sizeUnderlay);
5258
 
                        YAHOO.widget.Module.textResizeEvent.subscribe(this.sizeUnderlay, this, true);
5259
 
                    }
5260
 
 
5261
 
                    if (UA.webkit && UA.webkit < 420) {
5262
 
                        this.changeContentEvent.subscribe(fixWebkitUnderlay);
5263
 
                    }
5264
 
                    bNew = true;
5265
 
                }
5266
 
            }
5267
 
 
5268
 
            function onBeforeShow() {
5269
 
                var bNew = createUnderlay.call(this);
5270
 
                if (!bNew && bIEQuirks) {
5271
 
                    this.sizeUnderlay();
5272
 
                }
5273
 
                this._underlayDeferred = false;
5274
 
                this.beforeShowEvent.unsubscribe(onBeforeShow);
5275
 
            }
5276
 
 
5277
 
            function destroyUnderlay() {
5278
 
                if (this._underlayDeferred) {
5279
 
                    this.beforeShowEvent.unsubscribe(onBeforeShow);
5280
 
                    this._underlayDeferred = false;
5281
 
                }
5282
 
 
5283
 
                if (oUnderlay) {
5284
 
                    this.cfg.unsubscribeFromConfigEvent("width", this.sizeUnderlay);
5285
 
                    this.cfg.unsubscribeFromConfigEvent("height",this.sizeUnderlay);
5286
 
                    this.changeContentEvent.unsubscribe(this.sizeUnderlay);
5287
 
                    this.changeContentEvent.unsubscribe(fixWebkitUnderlay);
5288
 
                    YAHOO.widget.Module.textResizeEvent.unsubscribe(this.sizeUnderlay, this, true);
5289
 
 
5290
 
                    this.element.removeChild(oUnderlay);
5291
 
 
5292
 
                    this.underlay = null;
5293
 
                }
5294
 
            }
5295
 
 
5296
 
            switch (sUnderlay) {
5297
 
                case "shadow":
5298
 
                    Dom.removeClass(oElement, "matte");
5299
 
                    Dom.addClass(oElement, "shadow");
5300
 
                    break;
5301
 
                case "matte":
5302
 
                    if (!bMacGecko) {
5303
 
                        destroyUnderlay.call(this);
5304
 
                    }
5305
 
                    Dom.removeClass(oElement, "shadow");
5306
 
                    Dom.addClass(oElement, "matte");
5307
 
                    break;
5308
 
                default:
5309
 
                    if (!bMacGecko) {
5310
 
                        destroyUnderlay.call(this);
5311
 
                    }
5312
 
                    Dom.removeClass(oElement, "shadow");
5313
 
                    Dom.removeClass(oElement, "matte");
5314
 
                    break;
5315
 
            }
5316
 
 
5317
 
            if ((sUnderlay == "shadow") || (bMacGecko && !oUnderlay)) {
5318
 
                if (this.cfg.getProperty("visible")) {
5319
 
                    var bNew = createUnderlay.call(this);
5320
 
                    if (!bNew && bIEQuirks) {
5321
 
                        this.sizeUnderlay();
5322
 
                    }
5323
 
                } else {
5324
 
                    if (!this._underlayDeferred) {
5325
 
                        this.beforeShowEvent.subscribe(onBeforeShow);
5326
 
                        this._underlayDeferred = true;
5327
 
                    }
5328
 
                }
5329
 
            }
5330
 
        },
5331
 
        
5332
 
        /**
5333
 
        * The default event handler fired when the "modal" property is 
5334
 
        * changed. This handler subscribes or unsubscribes to the show and hide
5335
 
        * events to handle the display or hide of the modality mask.
5336
 
        * @method configModal
5337
 
        * @param {String} type The CustomEvent type (usually the property name)
5338
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
5339
 
        * handlers, args[0] will equal the newly applied value for the property.
5340
 
        * @param {Object} obj The scope object. For configuration handlers, 
5341
 
        * this will usually equal the owner.
5342
 
        */
5343
 
        configModal: function (type, args, obj) {
5344
 
 
5345
 
            var modal = args[0];
5346
 
            if (modal) {
5347
 
                if (!this._hasModalityEventListeners) {
5348
 
 
5349
 
                    this.subscribe("beforeShow", this.buildMask);
5350
 
                    this.subscribe("beforeShow", this.bringToTop);
5351
 
                    this.subscribe("beforeShow", this.showMask);
5352
 
                    this.subscribe("hide", this.hideMask);
5353
 
 
5354
 
                    Overlay.windowResizeEvent.subscribe(this.sizeMask, 
5355
 
                        this, true);
5356
 
 
5357
 
                    this._hasModalityEventListeners = true;
5358
 
                }
5359
 
            } else {
5360
 
                if (this._hasModalityEventListeners) {
5361
 
 
5362
 
                    if (this.cfg.getProperty("visible")) {
5363
 
                        this.hideMask();
5364
 
                        this.removeMask();
5365
 
                    }
5366
 
 
5367
 
                    this.unsubscribe("beforeShow", this.buildMask);
5368
 
                    this.unsubscribe("beforeShow", this.bringToTop);
5369
 
                    this.unsubscribe("beforeShow", this.showMask);
5370
 
                    this.unsubscribe("hide", this.hideMask);
5371
 
 
5372
 
                    Overlay.windowResizeEvent.unsubscribe(this.sizeMask, this);
5373
 
                    
5374
 
                    this._hasModalityEventListeners = false;
5375
 
                }
5376
 
            }
5377
 
        },
5378
 
        
5379
 
        /**
5380
 
        * Removes the modality mask.
5381
 
        * @method removeMask
5382
 
        */
5383
 
        removeMask: function () {
5384
 
        
5385
 
            var oMask = this.mask,
5386
 
                oParentNode;
5387
 
        
5388
 
            if (oMask) {
5389
 
                /*
5390
 
                    Hide the mask before destroying it to ensure that DOM
5391
 
                    event handlers on focusable elements get removed.
5392
 
                */
5393
 
                this.hideMask();
5394
 
                
5395
 
                oParentNode = oMask.parentNode;
5396
 
                if (oParentNode) {
5397
 
                    oParentNode.removeChild(oMask);
5398
 
                }
5399
 
 
5400
 
                this.mask = null;
5401
 
            }
5402
 
        },
5403
 
        
5404
 
        /**
5405
 
        * The default event handler fired when the "keylisteners" property 
5406
 
        * is changed.
5407
 
        * @method configKeyListeners
5408
 
        * @param {String} type The CustomEvent type (usually the property name)
5409
 
        * @param {Object[]} args The CustomEvent arguments. For configuration
5410
 
        * handlers, args[0] will equal the newly applied value for the property.
5411
 
        * @param {Object} obj The scope object. For configuration handlers, 
5412
 
        * this will usually equal the owner.
5413
 
        */
5414
 
        configKeyListeners: function (type, args, obj) {
5415
 
 
5416
 
            var listeners = args[0],
5417
 
                listener,
5418
 
                nListeners,
5419
 
                i;
5420
 
        
5421
 
            if (listeners) {
5422
 
 
5423
 
                if (listeners instanceof Array) {
5424
 
 
5425
 
                    nListeners = listeners.length;
5426
 
 
5427
 
                    for (i = 0; i < nListeners; i++) {
5428
 
 
5429
 
                        listener = listeners[i];
5430
 
        
5431
 
                        if (!Config.alreadySubscribed(this.showEvent, 
5432
 
                            listener.enable, listener)) {
5433
 
 
5434
 
                            this.showEvent.subscribe(listener.enable, 
5435
 
                                listener, true);
5436
 
 
5437
 
                        }
5438
 
 
5439
 
                        if (!Config.alreadySubscribed(this.hideEvent, 
5440
 
                            listener.disable, listener)) {
5441
 
 
5442
 
                            this.hideEvent.subscribe(listener.disable, 
5443
 
                                listener, true);
5444
 
 
5445
 
                            this.destroyEvent.subscribe(listener.disable, 
5446
 
                                listener, true);
5447
 
                        }
5448
 
 
5449
 
                    }
5450
 
 
5451
 
                } else {
5452
 
 
5453
 
                    if (!Config.alreadySubscribed(this.showEvent, 
5454
 
                        listeners.enable, listeners)) {
5455
 
 
5456
 
                        this.showEvent.subscribe(listeners.enable, 
5457
 
                            listeners, true);
5458
 
                    }
5459
 
 
5460
 
                    if (!Config.alreadySubscribed(this.hideEvent, 
5461
 
                        listeners.disable, listeners)) {
5462
 
 
5463
 
                        this.hideEvent.subscribe(listeners.disable, 
5464
 
                            listeners, true);
5465
 
 
5466
 
                        this.destroyEvent.subscribe(listeners.disable, 
5467
 
                            listeners, true);
5468
 
 
5469
 
                    }
5470
 
 
5471
 
                }
5472
 
 
5473
 
            }
5474
 
 
5475
 
        },
5476
 
        
5477
 
        /**
5478
 
        * The default event handler fired when the "height" property is changed.
5479
 
        * @method configHeight
5480
 
        * @param {String} type The CustomEvent type (usually the property name)
5481
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
5482
 
        * handlers, args[0] will equal the newly applied value for the property.
5483
 
        * @param {Object} obj The scope object. For configuration handlers, 
5484
 
        * this will usually equal the owner.
5485
 
        */
5486
 
        configHeight: function (type, args, obj) {
5487
 
    
5488
 
            var height = args[0],
5489
 
                el = this.innerElement;
5490
 
    
5491
 
            Dom.setStyle(el, "height", height);
5492
 
            this.cfg.refireEvent("iframe");
5493
 
    
5494
 
        },
5495
 
        
5496
 
        /**
5497
 
        * The default event handler fired when the "width" property is changed.
5498
 
        * @method configWidth
5499
 
        * @param {String} type The CustomEvent type (usually the property name)
5500
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
5501
 
        * handlers, args[0] will equal the newly applied value for the property.
5502
 
        * @param {Object} obj The scope object. For configuration handlers, 
5503
 
        * this will usually equal the owner.
5504
 
        */
5505
 
        configWidth: function (type, args, obj) {
5506
 
    
5507
 
            var width = args[0],
5508
 
                el = this.innerElement;
5509
 
    
5510
 
            Dom.setStyle(el, "width", width);
5511
 
            this.cfg.refireEvent("iframe");
5512
 
    
5513
 
        },
5514
 
        
5515
 
        /**
5516
 
        * The default event handler fired when the "zIndex" property is changed.
5517
 
        * @method configzIndex
5518
 
        * @param {String} type The CustomEvent type (usually the property name)
5519
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
5520
 
        * handlers, args[0] will equal the newly applied value for the property.
5521
 
        * @param {Object} obj The scope object. For configuration handlers, 
5522
 
        * this will usually equal the owner.
5523
 
        */
5524
 
        configzIndex: function (type, args, obj) {
5525
 
            Panel.superclass.configzIndex.call(this, type, args, obj);
5526
 
 
5527
 
            if (this.mask || this.cfg.getProperty("modal") === true) {
5528
 
                var panelZ = Dom.getStyle(this.element, "zIndex");
5529
 
                if (!panelZ || isNaN(panelZ)) {
5530
 
                    panelZ = 0;
5531
 
                }
5532
 
 
5533
 
                if (panelZ === 0) {
5534
 
                    // Recursive call to configzindex (which should be stopped
5535
 
                    // from going further because panelZ should no longer === 0)
5536
 
                    this.cfg.setProperty("zIndex", 1);
5537
 
                } else {
5538
 
                    this.stackMask();
5539
 
                }
5540
 
            }
5541
 
        },
5542
 
 
5543
 
        // END BUILT-IN PROPERTY EVENT HANDLERS //
5544
 
        /**
5545
 
        * Builds the wrapping container around the Panel that is used for 
5546
 
        * positioning the shadow and matte underlays. The container element is 
5547
 
        * assigned to a  local instance variable called container, and the 
5548
 
        * element is reinserted inside of it.
5549
 
        * @method buildWrapper
5550
 
        */
5551
 
        buildWrapper: function () {
5552
 
 
5553
 
            var elementParent = this.element.parentNode,
5554
 
                originalElement = this.element,
5555
 
                wrapper = document.createElement("div");
5556
 
 
5557
 
            wrapper.className = Panel.CSS_PANEL_CONTAINER;
5558
 
            wrapper.id = originalElement.id + "_c";
5559
 
 
5560
 
            if (elementParent) {
5561
 
                elementParent.insertBefore(wrapper, originalElement);
5562
 
            }
5563
 
 
5564
 
            wrapper.appendChild(originalElement);
5565
 
 
5566
 
            this.element = wrapper;
5567
 
            this.innerElement = originalElement;
5568
 
 
5569
 
            Dom.setStyle(this.innerElement, "visibility", "inherit");
5570
 
        },
5571
 
 
5572
 
        /**
5573
 
        * Adjusts the size of the shadow based on the size of the element.
5574
 
        * @method sizeUnderlay
5575
 
        */
5576
 
        sizeUnderlay: function () {
5577
 
            var oUnderlay = this.underlay,
5578
 
                oElement;
5579
 
 
5580
 
            if (oUnderlay) {
5581
 
                oElement = this.element;
5582
 
                oUnderlay.style.width = oElement.offsetWidth + "px";
5583
 
                oUnderlay.style.height = oElement.offsetHeight + "px";
5584
 
            }
5585
 
        },
5586
 
 
5587
 
        
5588
 
        /**
5589
 
        * Registers the Panel's header for drag & drop capability.
5590
 
        * @method registerDragDrop
5591
 
        */
5592
 
        registerDragDrop: function () {
5593
 
 
5594
 
            var me = this;
5595
 
 
5596
 
            if (this.header) {
5597
 
 
5598
 
                if (!DD) {
5599
 
                    return;
5600
 
                }
5601
 
 
5602
 
                var bDragOnly = (this.cfg.getProperty("dragonly") === true);
5603
 
                this.dd = new DD(this.element.id, this.id, {dragOnly: bDragOnly});
5604
 
 
5605
 
                if (!this.header.id) {
5606
 
                    this.header.id = this.id + "_h";
5607
 
                }
5608
 
 
5609
 
                this.dd.startDrag = function () {
5610
 
 
5611
 
                    var offsetHeight,
5612
 
                        offsetWidth,
5613
 
                        viewPortWidth,
5614
 
                        viewPortHeight,
5615
 
                        scrollX,
5616
 
                        scrollY;
5617
 
 
5618
 
                    if (YAHOO.env.ua.ie == 6) {
5619
 
                        Dom.addClass(me.element,"drag");
5620
 
                    }
5621
 
 
5622
 
                    if (me.cfg.getProperty("constraintoviewport")) {
5623
 
 
5624
 
                        var nViewportOffset = Overlay.VIEWPORT_OFFSET;
5625
 
 
5626
 
                        offsetHeight = me.element.offsetHeight;
5627
 
                        offsetWidth = me.element.offsetWidth;
5628
 
 
5629
 
                        viewPortWidth = Dom.getViewportWidth();
5630
 
                        viewPortHeight = Dom.getViewportHeight();
5631
 
 
5632
 
                        scrollX = Dom.getDocumentScrollLeft();
5633
 
                        scrollY = Dom.getDocumentScrollTop();
5634
 
 
5635
 
                        if (offsetHeight + nViewportOffset < viewPortHeight) {
5636
 
                            this.minY = scrollY + nViewportOffset;
5637
 
                            this.maxY = scrollY + viewPortHeight - offsetHeight - nViewportOffset;
5638
 
                        } else {
5639
 
                            this.minY = scrollY + nViewportOffset;
5640
 
                            this.maxY = scrollY + nViewportOffset;
5641
 
                        }
5642
 
 
5643
 
                        if (offsetWidth + nViewportOffset < viewPortWidth) {
5644
 
                            this.minX = scrollX + nViewportOffset;
5645
 
                            this.maxX = scrollX + viewPortWidth - offsetWidth - nViewportOffset;
5646
 
                        } else {
5647
 
                            this.minX = scrollX + nViewportOffset;
5648
 
                            this.maxX = scrollX + nViewportOffset;
5649
 
                        }
5650
 
 
5651
 
                        this.constrainX = true;
5652
 
                        this.constrainY = true;
5653
 
                    } else {
5654
 
                        this.constrainX = false;
5655
 
                        this.constrainY = false;
5656
 
                    }
5657
 
 
5658
 
                    me.dragEvent.fire("startDrag", arguments);
5659
 
                };
5660
 
 
5661
 
                this.dd.onDrag = function () {
5662
 
                    me.syncPosition();
5663
 
                    me.cfg.refireEvent("iframe");
5664
 
                    if (this.platform == "mac" && YAHOO.env.ua.gecko) {
5665
 
                        this.showMacGeckoScrollbars();
5666
 
                    }
5667
 
 
5668
 
                    me.dragEvent.fire("onDrag", arguments);
5669
 
                };
5670
 
 
5671
 
                this.dd.endDrag = function () {
5672
 
 
5673
 
                    if (YAHOO.env.ua.ie == 6) {
5674
 
                        Dom.removeClass(me.element,"drag");
5675
 
                    }
5676
 
 
5677
 
                    me.dragEvent.fire("endDrag", arguments);
5678
 
                    me.moveEvent.fire(me.cfg.getProperty("xy"));
5679
 
 
5680
 
                };
5681
 
 
5682
 
                this.dd.setHandleElId(this.header.id);
5683
 
                this.dd.addInvalidHandleType("INPUT");
5684
 
                this.dd.addInvalidHandleType("SELECT");
5685
 
                this.dd.addInvalidHandleType("TEXTAREA");
5686
 
            }
5687
 
        },
5688
 
        
5689
 
        /**
5690
 
        * Builds the mask that is laid over the document when the Panel is 
5691
 
        * configured to be modal.
5692
 
        * @method buildMask
5693
 
        */
5694
 
        buildMask: function () {
5695
 
            var oMask = this.mask;
5696
 
            if (!oMask) {
5697
 
                if (!m_oMaskTemplate) {
5698
 
                    m_oMaskTemplate = document.createElement("div");
5699
 
                    m_oMaskTemplate.className = "mask";
5700
 
                    m_oMaskTemplate.innerHTML = "&#160;";
5701
 
                }
5702
 
                oMask = m_oMaskTemplate.cloneNode(true);
5703
 
                oMask.id = this.id + "_mask";
5704
 
 
5705
 
                document.body.insertBefore(oMask, document.body.firstChild);
5706
 
 
5707
 
                this.mask = oMask;
5708
 
 
5709
 
                if (YAHOO.env.ua.gecko && this.platform == "mac") {
5710
 
                    Dom.addClass(this.mask, "block-scrollbars");
5711
 
                }
5712
 
 
5713
 
                // Stack mask based on the element zindex
5714
 
                this.stackMask();
5715
 
            }
5716
 
        },
5717
 
 
5718
 
        /**
5719
 
        * Hides the modality mask.
5720
 
        * @method hideMask
5721
 
        */
5722
 
        hideMask: function () {
5723
 
            if (this.cfg.getProperty("modal") && this.mask) {
5724
 
                this.mask.style.display = "none";
5725
 
                this.hideMaskEvent.fire();
5726
 
                Dom.removeClass(document.body, "masked");
5727
 
            }
5728
 
        },
5729
 
 
5730
 
        /**
5731
 
        * Shows the modality mask.
5732
 
        * @method showMask
5733
 
        */
5734
 
        showMask: function () {
5735
 
            if (this.cfg.getProperty("modal") && this.mask) {
5736
 
                Dom.addClass(document.body, "masked");
5737
 
                this.sizeMask();
5738
 
                this.mask.style.display = "block";
5739
 
                this.showMaskEvent.fire();
5740
 
            }
5741
 
        },
5742
 
 
5743
 
        /**
5744
 
        * Sets the size of the modality mask to cover the entire scrollable 
5745
 
        * area of the document
5746
 
        * @method sizeMask
5747
 
        */
5748
 
        sizeMask: function () {
5749
 
            if (this.mask) {
5750
 
                this.mask.style.height = Dom.getDocumentHeight() + "px";
5751
 
                this.mask.style.width = Dom.getDocumentWidth() + "px";
5752
 
            }
5753
 
        },
5754
 
 
5755
 
        /**
5756
 
         * Sets the zindex of the mask, if it exists, based on the zindex of 
5757
 
         * the Panel element. The zindex of the mask is set to be one less 
5758
 
         * than the Panel element's zindex.
5759
 
         * 
5760
 
         * <p>NOTE: This method will not bump up the zindex of the Panel
5761
 
         * to ensure that the mask has a non-negative zindex. If you require the
5762
 
         * mask zindex to be 0 or higher, the zindex of the Panel 
5763
 
         * should be set to a value higher than 0, before this method is called.
5764
 
         * </p>
5765
 
         * @method stackMask
5766
 
         */
5767
 
        stackMask: function() {
5768
 
            if (this.mask) {
5769
 
                var panelZ = Dom.getStyle(this.element, "zIndex");
5770
 
                if (!YAHOO.lang.isUndefined(panelZ) && !isNaN(panelZ)) {
5771
 
                    Dom.setStyle(this.mask, "zIndex", panelZ - 1);
5772
 
                }
5773
 
            }
5774
 
        },
5775
 
 
5776
 
        /**
5777
 
        * Renders the Panel by inserting the elements that are not already in 
5778
 
        * the main Panel into their correct places. Optionally appends the 
5779
 
        * Panel to the specified node prior to the render's execution. NOTE: 
5780
 
        * For Panels without existing markup, the appendToNode argument is 
5781
 
        * REQUIRED. If this argument is ommitted and the current element is 
5782
 
        * not present in the document, the function will return false, 
5783
 
        * indicating that the render was a failure.
5784
 
        * @method render
5785
 
        * @param {String} appendToNode The element id to which the Module 
5786
 
        * should be appended to prior to rendering <em>OR</em>
5787
 
        * @param {HTMLElement} appendToNode The element to which the Module 
5788
 
        * should be appended to prior to rendering
5789
 
        * @return {boolean} Success or failure of the render
5790
 
        */
5791
 
        render: function (appendToNode) {
5792
 
 
5793
 
            return Panel.superclass.render.call(this, 
5794
 
                appendToNode, this.innerElement);
5795
 
 
5796
 
        },
5797
 
        
5798
 
        /**
5799
 
        * Removes the Panel element from the DOM and sets all child elements
5800
 
        * to null.
5801
 
        * @method destroy
5802
 
        */
5803
 
        destroy: function () {
5804
 
        
5805
 
            Overlay.windowResizeEvent.unsubscribe(this.sizeMask, this);
5806
 
            
5807
 
            this.removeMask();
5808
 
        
5809
 
            if (this.close) {
5810
 
            
5811
 
                Event.purgeElement(this.close);
5812
 
        
5813
 
            }
5814
 
        
5815
 
            Panel.superclass.destroy.call(this);  
5816
 
        
5817
 
        },
5818
 
        
5819
 
        /**
5820
 
        * Returns a String representation of the object.
5821
 
        * @method toString
5822
 
        * @return {String} The string representation of the Panel.
5823
 
        */
5824
 
        toString: function () {
5825
 
            return "Panel " + this.id;
5826
 
        }
5827
 
    
5828
 
    });
5829
 
 
5830
 
}());
5831
 
 
5832
 
(function () {
5833
 
 
5834
 
    /**
5835
 
    * <p>
5836
 
    * Dialog is an implementation of Panel that can be used to submit form 
5837
 
    * data.
5838
 
    * </p>
5839
 
    * <p>
5840
 
    * Built-in functionality for buttons with event handlers is included. 
5841
 
    * If the optional YUI Button dependancy is included on the page, the buttons
5842
 
    * created will be instances of YAHOO.widget.Button, otherwise regular HTML buttons
5843
 
    * will be created.
5844
 
    * </p>
5845
 
    * <p>
5846
 
    * Forms can be processed in 3 ways -- via an asynchronous Connection utility call, 
5847
 
    * a simple form POST or GET, or manually. The YUI Connection utility should be
5848
 
    * included if you're using the default "async" postmethod, but is not required if
5849
 
    * you're using any of the other postmethod values.
5850
 
    * </p>
5851
 
    * @namespace YAHOO.widget
5852
 
    * @class Dialog
5853
 
    * @extends YAHOO.widget.Panel
5854
 
    * @constructor
5855
 
    * @param {String} el The element ID representing the Dialog <em>OR</em>
5856
 
    * @param {HTMLElement} el The element representing the Dialog
5857
 
    * @param {Object} userConfig The configuration object literal containing 
5858
 
    * the configuration that should be set for this Dialog. See configuration 
5859
 
    * documentation for more details.
5860
 
    */
5861
 
    YAHOO.widget.Dialog = function (el, userConfig) {
5862
 
        YAHOO.widget.Dialog.superclass.constructor.call(this, el, userConfig);
5863
 
    };
5864
 
 
5865
 
    var Event = YAHOO.util.Event,
5866
 
        CustomEvent = YAHOO.util.CustomEvent,
5867
 
        Dom = YAHOO.util.Dom,
5868
 
        KeyListener = YAHOO.util.KeyListener,
5869
 
        Connect = YAHOO.util.Connect,
5870
 
        Dialog = YAHOO.widget.Dialog,
5871
 
        Lang = YAHOO.lang,
5872
 
 
5873
 
        /**
5874
 
        * Constant representing the name of the Dialog's events
5875
 
        * @property EVENT_TYPES
5876
 
        * @private
5877
 
        * @final
5878
 
        * @type Object
5879
 
        */
5880
 
        EVENT_TYPES = {
5881
 
        
5882
 
            "BEFORE_SUBMIT": "beforeSubmit",
5883
 
            "SUBMIT": "submit",
5884
 
            "MANUAL_SUBMIT": "manualSubmit",
5885
 
            "ASYNC_SUBMIT": "asyncSubmit",
5886
 
            "FORM_SUBMIT": "formSubmit",
5887
 
            "CANCEL": "cancel"
5888
 
        
5889
 
        },
5890
 
 
5891
 
        /**
5892
 
        * Constant representing the Dialog's configuration properties
5893
 
        * @property DEFAULT_CONFIG
5894
 
        * @private
5895
 
        * @final
5896
 
        * @type Object
5897
 
        */
5898
 
        DEFAULT_CONFIG = {
5899
 
 
5900
 
            "POST_METHOD": { 
5901
 
                key: "postmethod", 
5902
 
                value: "async" 
5903
 
            },
5904
 
 
5905
 
            "BUTTONS": { 
5906
 
                key: "buttons", 
5907
 
                value: "none" 
5908
 
            },
5909
 
 
5910
 
            "HIDEAFTERSUBMIT" : {
5911
 
                key: "hideaftersubmit",
5912
 
                value: true
5913
 
            }
5914
 
        };
5915
 
 
5916
 
    /**
5917
 
    * Constant representing the default CSS class used for a Dialog
5918
 
    * @property YAHOO.widget.Dialog.CSS_DIALOG
5919
 
    * @static
5920
 
    * @final
5921
 
    * @type String
5922
 
    */
5923
 
    Dialog.CSS_DIALOG = "yui-dialog";
5924
 
 
5925
 
    function removeButtonEventHandlers() {
5926
 
 
5927
 
        var aButtons = this._aButtons,
5928
 
            nButtons,
5929
 
            oButton,
5930
 
            i;
5931
 
 
5932
 
        if (Lang.isArray(aButtons)) {
5933
 
            nButtons = aButtons.length;
5934
 
 
5935
 
            if (nButtons > 0) {
5936
 
                i = nButtons - 1;
5937
 
                do {
5938
 
                    oButton = aButtons[i];
5939
 
 
5940
 
                    if (YAHOO.widget.Button && oButton instanceof YAHOO.widget.Button) {
5941
 
                        oButton.destroy();
5942
 
                    }
5943
 
                    else if (oButton.tagName.toUpperCase() == "BUTTON") {
5944
 
                        Event.purgeElement(oButton);
5945
 
                        Event.purgeElement(oButton, false);
5946
 
                    }
5947
 
                }
5948
 
                while (i--);
5949
 
            }
5950
 
        }
5951
 
    }
5952
 
    
5953
 
    YAHOO.extend(Dialog, YAHOO.widget.Panel, { 
5954
 
 
5955
 
        /**
5956
 
        * @property form
5957
 
        * @description Object reference to the Dialog's 
5958
 
        * <code>&#60;form&#62;</code> element.
5959
 
        * @default null 
5960
 
        * @type <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/
5961
 
        * level-one-html.html#ID-40002357">HTMLFormElement</a>
5962
 
        */
5963
 
        form: null,
5964
 
    
5965
 
        /**
5966
 
        * Initializes the class's configurable properties which can be changed 
5967
 
        * using the Dialog's Config object (cfg).
5968
 
        * @method initDefaultConfig
5969
 
        */
5970
 
        initDefaultConfig: function () {
5971
 
            Dialog.superclass.initDefaultConfig.call(this);
5972
 
 
5973
 
            /**
5974
 
            * The internally maintained callback object for use with the 
5975
 
            * Connection utility. The format of the callback object is 
5976
 
            * similar to Connection Manager's callback object and is 
5977
 
            * simply passed through to Connection Manager when the async 
5978
 
            * request is made.
5979
 
            * @property callback
5980
 
            * @type Object
5981
 
            */
5982
 
            this.callback = {
5983
 
 
5984
 
                /**
5985
 
                * The function to execute upon success of the 
5986
 
                * Connection submission (when the form does not
5987
 
                * contain a file input element).
5988
 
                * 
5989
 
                * @property callback.success
5990
 
                * @type Function
5991
 
                */
5992
 
                success: null,
5993
 
 
5994
 
                /**
5995
 
                * The function to execute upon failure of the 
5996
 
                * Connection submission
5997
 
                * @property callback.failure
5998
 
                * @type Function
5999
 
                */
6000
 
                failure: null,
6001
 
 
6002
 
                /**
6003
 
                 *<p>
6004
 
                * The function to execute upon success of the 
6005
 
                * Connection submission, when the form contains
6006
 
                * a file input element.
6007
 
                * </p>
6008
 
                * <p>
6009
 
                * <em>NOTE:</em> Connection manager will not
6010
 
                * invoke the success or failure handlers for the file
6011
 
                * upload use case. This will be the only callback
6012
 
                * handler invoked.
6013
 
                * </p>
6014
 
                * <p>
6015
 
                * For more information, see the <a href="http://developer.yahoo.com/yui/connection/#file">
6016
 
                * Connection Manager documenation on file uploads</a>.
6017
 
                * </p>
6018
 
                * @property callback.upload
6019
 
                * @type Function
6020
 
                */
6021
 
 
6022
 
                /**
6023
 
                * The arbitraty argument or arguments to pass to the Connection 
6024
 
                * callback functions
6025
 
                * @property callback.argument
6026
 
                * @type Object
6027
 
                */
6028
 
                argument: null
6029
 
 
6030
 
            };
6031
 
 
6032
 
            // Add form dialog config properties //
6033
 
            /**
6034
 
            * The method to use for posting the Dialog's form. Possible values 
6035
 
            * are "async", "form", and "manual".
6036
 
            * @config postmethod
6037
 
            * @type String
6038
 
            * @default async
6039
 
            */
6040
 
            this.cfg.addProperty(DEFAULT_CONFIG.POST_METHOD.key, {
6041
 
                handler: this.configPostMethod, 
6042
 
                value: DEFAULT_CONFIG.POST_METHOD.value, 
6043
 
                validator: function (val) {
6044
 
                    if (val != "form" && val != "async" && val != "none" && 
6045
 
                        val != "manual") {
6046
 
                        return false;
6047
 
                    } else {
6048
 
                        return true;
6049
 
                    }
6050
 
                }
6051
 
            });
6052
 
 
6053
 
            /**
6054
 
            * This property is used to configure whether or not the 
6055
 
            * dialog should be automatically hidden after submit.
6056
 
            * 
6057
 
            * @config hideaftersubmit
6058
 
            * @type Boolean
6059
 
            * @default true
6060
 
            */
6061
 
            this.cfg.addProperty(DEFAULT_CONFIG.HIDEAFTERSUBMIT.key, {
6062
 
                value: DEFAULT_CONFIG.HIDEAFTERSUBMIT.value
6063
 
            }); 
6064
 
 
6065
 
            /**
6066
 
            * Array of object literals, each containing a set of properties 
6067
 
            * defining a button to be appended into the Dialog's footer.
6068
 
            * 
6069
 
            * Each button object in the buttons array can have three properties:
6070
 
            * <dt>text:</dt>
6071
 
            * <dd>The text that will display on the face of the button. The text can 
6072
 
            * include HTML, as long as it is compliant with HTML Button specifications.
6073
 
            * </dd>
6074
 
            * <dt>handler:</dt>
6075
 
            * <dd>Can be either:
6076
 
            *     <ol>
6077
 
            *         <li>A reference to a function that should fire when the 
6078
 
            * button is clicked.  (In this case scope of this function is 
6079
 
            * always its Dialog instance.)</li>
6080
 
            *         <li>An object literal representing the code to be 
6081
 
            * executed when the button is clicked.  Format:<br> <code> {<br>
6082
 
            * <strong>fn:</strong> Function,   &#47;&#47; The handler to call 
6083
 
            * when  the event fires.<br> <strong>obj:</strong> Object,
6084
 
            * &#47;&#47; An  object to pass back to the handler.<br> <strong>
6085
 
            * scope:</strong>  Object &#47;&#47; The object to use for the 
6086
 
            * scope of the handler. <br> } </code> <br></li>
6087
 
            *     </ol>
6088
 
            * </dd>
6089
 
            * <dt>isDefault:</dt>
6090
 
            * <dd>An optional boolean value that specifies that a button 
6091
 
            * should be highlighted and focused by default.</dd>
6092
 
            * 
6093
 
            * <em>NOTE:</em>If the YUI Button Widget is included on the page, 
6094
 
            * the buttons created will be instances of YAHOO.widget.Button. 
6095
 
            * Otherwise, HTML Buttons (<code>&#60;BUTTON&#62;</code>) will be 
6096
 
            * created.
6097
 
            * 
6098
 
            * @config buttons
6099
 
            * @type {Array|String}
6100
 
            * @default "none"
6101
 
            */
6102
 
            this.cfg.addProperty(DEFAULT_CONFIG.BUTTONS.key, {
6103
 
                handler: this.configButtons,
6104
 
                value: DEFAULT_CONFIG.BUTTONS.value
6105
 
            }); 
6106
 
 
6107
 
        },
6108
 
 
6109
 
        /**
6110
 
        * Initializes the custom events for Dialog which are fired 
6111
 
        * automatically at appropriate times by the Dialog class.
6112
 
        * @method initEvents
6113
 
        */
6114
 
        initEvents: function () {
6115
 
            Dialog.superclass.initEvents.call(this);
6116
 
 
6117
 
            var SIGNATURE = CustomEvent.LIST;
6118
 
 
6119
 
            /**
6120
 
            * CustomEvent fired prior to submission
6121
 
            * @event beforeSubmitEvent
6122
 
            */ 
6123
 
            this.beforeSubmitEvent = 
6124
 
                this.createEvent(EVENT_TYPES.BEFORE_SUBMIT);
6125
 
            this.beforeSubmitEvent.signature = SIGNATURE;
6126
 
            
6127
 
            /**
6128
 
            * CustomEvent fired after submission
6129
 
            * @event submitEvent
6130
 
            */
6131
 
            this.submitEvent = this.createEvent(EVENT_TYPES.SUBMIT);
6132
 
            this.submitEvent.signature = SIGNATURE;
6133
 
        
6134
 
            /**
6135
 
            * CustomEvent fired prior to manual submission
6136
 
            * @event manualSubmitEvent
6137
 
            */
6138
 
            this.manualSubmitEvent = 
6139
 
                this.createEvent(EVENT_TYPES.MANUAL_SUBMIT);
6140
 
            this.manualSubmitEvent.signature = SIGNATURE;
6141
 
        
6142
 
            /**
6143
 
            * CustomEvent fired prior to asynchronous submission
6144
 
            * @event asyncSubmitEvent
6145
 
            */ 
6146
 
            this.asyncSubmitEvent = this.createEvent(EVENT_TYPES.ASYNC_SUBMIT);
6147
 
            this.asyncSubmitEvent.signature = SIGNATURE;
6148
 
        
6149
 
            /**
6150
 
            * CustomEvent fired prior to form-based submission
6151
 
            * @event formSubmitEvent
6152
 
            */
6153
 
            this.formSubmitEvent = this.createEvent(EVENT_TYPES.FORM_SUBMIT);
6154
 
            this.formSubmitEvent.signature = SIGNATURE;
6155
 
        
6156
 
            /**
6157
 
            * CustomEvent fired after cancel
6158
 
            * @event cancelEvent
6159
 
            */
6160
 
            this.cancelEvent = this.createEvent(EVENT_TYPES.CANCEL);
6161
 
            this.cancelEvent.signature = SIGNATURE;
6162
 
        
6163
 
        },
6164
 
        
6165
 
        /**
6166
 
        * The Dialog initialization method, which is executed for Dialog and 
6167
 
        * all of its subclasses. This method is automatically called by the 
6168
 
        * constructor, and  sets up all DOM references for pre-existing markup, 
6169
 
        * and creates required markup if it is not already present.
6170
 
        * @method init
6171
 
        * @param {String} el The element ID representing the Dialog <em>OR</em>
6172
 
        * @param {HTMLElement} el The element representing the Dialog
6173
 
        * @param {Object} userConfig The configuration object literal 
6174
 
        * containing the configuration that should be set for this Dialog. 
6175
 
        * See configuration documentation for more details.
6176
 
        */
6177
 
        init: function (el, userConfig) {
6178
 
 
6179
 
            /*
6180
 
                 Note that we don't pass the user config in here yet because 
6181
 
                 we only want it executed once, at the lowest subclass level
6182
 
            */
6183
 
 
6184
 
            Dialog.superclass.init.call(this, el/*, userConfig*/); 
6185
 
        
6186
 
            this.beforeInitEvent.fire(Dialog);
6187
 
        
6188
 
            Dom.addClass(this.element, Dialog.CSS_DIALOG);
6189
 
        
6190
 
            this.cfg.setProperty("visible", false);
6191
 
        
6192
 
            if (userConfig) {
6193
 
                this.cfg.applyConfig(userConfig, true);
6194
 
            }
6195
 
        
6196
 
            this.showEvent.subscribe(this.focusFirst, this, true);
6197
 
            this.beforeHideEvent.subscribe(this.blurButtons, this, true);
6198
 
 
6199
 
            this.subscribe("changeBody", this.registerForm);
6200
 
        
6201
 
            this.initEvent.fire(Dialog);
6202
 
        },
6203
 
        
6204
 
        /**
6205
 
        * Submits the Dialog's form depending on the value of the 
6206
 
        * "postmethod" configuration property.  <strong>Please note:
6207
 
        * </strong> As of version 2.3 this method will automatically handle 
6208
 
        * asyncronous file uploads should the Dialog instance's form contain 
6209
 
        * <code>&#60;input type="file"&#62;</code> elements.  If a Dialog 
6210
 
        * instance will be handling asyncronous file uploads, its 
6211
 
        * <code>callback</code> property will need to be setup with a 
6212
 
        * <code>upload</code> handler rather than the standard 
6213
 
        * <code>success</code> and, or <code>failure</code> handlers.  For more 
6214
 
        * information, see the <a href="http://developer.yahoo.com/yui/
6215
 
        * connection/#file">Connection Manager documenation on file uploads</a>.
6216
 
        * @method doSubmit
6217
 
        */
6218
 
        doSubmit: function () {
6219
 
    
6220
 
            var oForm = this.form,
6221
 
                bUseFileUpload = false,
6222
 
                bUseSecureFileUpload = false,
6223
 
                aElements,
6224
 
                nElements,
6225
 
                i,
6226
 
                sMethod;
6227
 
 
6228
 
            switch (this.cfg.getProperty("postmethod")) {
6229
 
    
6230
 
            case "async":
6231
 
 
6232
 
                aElements = oForm.elements;
6233
 
                nElements = aElements.length;
6234
 
 
6235
 
                if (nElements > 0) {
6236
 
                    i = nElements - 1;
6237
 
                    do {
6238
 
                        if (aElements[i].type == "file") {
6239
 
                            bUseFileUpload = true;
6240
 
                            break;
6241
 
                        }
6242
 
                    }
6243
 
                    while(i--);
6244
 
                }
6245
 
 
6246
 
                if (bUseFileUpload && YAHOO.env.ua.ie && this.isSecure) {
6247
 
                    bUseSecureFileUpload = true;
6248
 
                }
6249
 
 
6250
 
                sMethod = (oForm.getAttribute("method") || "POST").toUpperCase();
6251
 
 
6252
 
                Connect.setForm(oForm, bUseFileUpload, bUseSecureFileUpload);
6253
 
                Connect.asyncRequest(sMethod, oForm.getAttribute("action"), this.callback);
6254
 
 
6255
 
                this.asyncSubmitEvent.fire();
6256
 
 
6257
 
                break;
6258
 
 
6259
 
            case "form":
6260
 
 
6261
 
                oForm.submit();
6262
 
                this.formSubmitEvent.fire();
6263
 
 
6264
 
                break;
6265
 
 
6266
 
            case "none":
6267
 
            case "manual":
6268
 
 
6269
 
                this.manualSubmitEvent.fire();
6270
 
 
6271
 
                break;
6272
 
    
6273
 
            }
6274
 
    
6275
 
        },
6276
 
        
6277
 
        
6278
 
        /**
6279
 
        * Prepares the Dialog's internal FORM object, creating one if one is
6280
 
        * not currently present.
6281
 
        * @method registerForm
6282
 
        */
6283
 
        registerForm: function () {
6284
 
    
6285
 
            var form = this.element.getElementsByTagName("form")[0],
6286
 
                me = this,
6287
 
                firstElement,
6288
 
                lastElement;
6289
 
 
6290
 
 
6291
 
            if (this.form) {
6292
 
                if (this.form == form && 
6293
 
                    Dom.isAncestor(this.element, this.form)) {
6294
 
    
6295
 
                    return;
6296
 
                } else {
6297
 
                    Event.purgeElement(this.form);
6298
 
                    this.form = null;                
6299
 
                }
6300
 
            }
6301
 
 
6302
 
            if (!form) {
6303
 
                form = document.createElement("form");
6304
 
                form.name = "frm_" + this.id;
6305
 
 
6306
 
                this.body.appendChild(form);
6307
 
            }
6308
 
 
6309
 
            if (form) {
6310
 
                this.form = form;
6311
 
 
6312
 
                Event.on(form, "submit", function (e) {
6313
 
                    Event.stopEvent(e);
6314
 
                    this.submit();
6315
 
                    this.form.blur();
6316
 
                }, this, true);
6317
 
 
6318
 
                this.firstFormElement = function () {
6319
 
                    var f, el, nElements = form.elements.length;
6320
 
 
6321
 
                    for (f = 0; f < nElements; f++) {
6322
 
                        el = form.elements[f];
6323
 
                        if (el.focus && !el.disabled && el.type != "hidden") {
6324
 
                            return el;
6325
 
                        }
6326
 
                    }
6327
 
                    return null;
6328
 
                }();
6329
 
            
6330
 
                this.lastFormElement = function () {
6331
 
                    var f, el, nElements = form.elements.length;
6332
 
                    
6333
 
                    for (f = nElements - 1; f >= 0; f--) {
6334
 
                        el = form.elements[f];
6335
 
                        if (el.focus && !el.disabled && el.type != "hidden") {
6336
 
                            return el;
6337
 
                        }
6338
 
                    }
6339
 
                    return null;
6340
 
                }();
6341
 
            
6342
 
                if (this.cfg.getProperty("modal")) {
6343
 
                    firstElement = this.firstFormElement || this.firstButton;
6344
 
                    if (firstElement) {
6345
 
                        this.preventBackTab = new KeyListener(firstElement, 
6346
 
                            { shift: true, keys: 9 }, 
6347
 
                            { fn: me.focusLast, scope: me, 
6348
 
                            correctScope: true });
6349
 
    
6350
 
                        this.showEvent.subscribe(this.preventBackTab.enable, 
6351
 
                            this.preventBackTab, true);
6352
 
    
6353
 
                        this.hideEvent.subscribe(this.preventBackTab.disable, 
6354
 
                            this.preventBackTab, true);
6355
 
                    }
6356
 
            
6357
 
                    lastElement = this.lastButton || this.lastFormElement;
6358
 
    
6359
 
                    if (lastElement) {
6360
 
                        this.preventTabOut = new KeyListener(lastElement, 
6361
 
                            { shift: false, keys: 9 }, 
6362
 
                            { fn: me.focusFirst, scope: me, 
6363
 
                            correctScope: true });
6364
 
    
6365
 
                        this.showEvent.subscribe(this.preventTabOut.enable, 
6366
 
                            this.preventTabOut, true);
6367
 
    
6368
 
                        this.hideEvent.subscribe(this.preventTabOut.disable, 
6369
 
                            this.preventTabOut, true);
6370
 
                    }
6371
 
                }
6372
 
            }
6373
 
        },
6374
 
        
6375
 
        // BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
6376
 
        
6377
 
        /**
6378
 
        * The default event handler fired when the "close" property is 
6379
 
        * changed. The method controls the appending or hiding of the close
6380
 
        * icon at the top right of the Dialog.
6381
 
        * @method configClose
6382
 
        * @param {String} type The CustomEvent type (usually the property name)
6383
 
        * @param {Object[]} args The CustomEvent arguments. For 
6384
 
        * configuration handlers, args[0] will equal the newly applied value 
6385
 
        * for the property.
6386
 
        * @param {Object} obj The scope object. For configuration handlers, 
6387
 
        * this will usually equal the owner.
6388
 
        */
6389
 
        configClose: function (type, args, obj) {
6390
 
            var val = args[0];
6391
 
        
6392
 
            function doCancel(e, obj) {
6393
 
                obj.cancel();
6394
 
            }
6395
 
        
6396
 
            if (val) {
6397
 
                if (! this.close) {
6398
 
                    this.close = document.createElement("div");
6399
 
                    Dom.addClass(this.close, "container-close");
6400
 
        
6401
 
                    this.close.innerHTML = "&#160;";
6402
 
                    this.innerElement.appendChild(this.close);
6403
 
                    Event.on(this.close, "click", doCancel, this);
6404
 
                } else {
6405
 
                    this.close.style.display = "block";
6406
 
                }
6407
 
            } else {
6408
 
                if (this.close) {
6409
 
                    this.close.style.display = "none";
6410
 
                }
6411
 
            }
6412
 
        },
6413
 
        
6414
 
        /**
6415
 
        * The default event handler for the "buttons" configuration property
6416
 
        * @method configButtons
6417
 
        * @param {String} type The CustomEvent type (usually the property name)
6418
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
6419
 
        * handlers, args[0] will equal the newly applied value for the property.
6420
 
        * @param {Object} obj The scope object. For configuration handlers, 
6421
 
        * this will usually equal the owner.
6422
 
        */
6423
 
        configButtons: function (type, args, obj) {
6424
 
    
6425
 
            var Button = YAHOO.widget.Button,
6426
 
                aButtons = args[0],
6427
 
                oInnerElement = this.innerElement,
6428
 
                oButton,
6429
 
                oButtonEl,
6430
 
                oYUIButton,
6431
 
                nButtons,
6432
 
                oSpan,
6433
 
                oFooter,
6434
 
                i;
6435
 
 
6436
 
            removeButtonEventHandlers.call(this);
6437
 
            
6438
 
            this._aButtons = null;
6439
 
 
6440
 
            if (Lang.isArray(aButtons)) {
6441
 
 
6442
 
                oSpan = document.createElement("span");
6443
 
                oSpan.className = "button-group";
6444
 
 
6445
 
                nButtons = aButtons.length;
6446
 
 
6447
 
                this._aButtons = [];
6448
 
        
6449
 
                for (i = 0; i < nButtons; i++) {
6450
 
 
6451
 
                    oButton = aButtons[i];
6452
 
 
6453
 
                    if (Button) {
6454
 
 
6455
 
                        oYUIButton = new Button({ label: oButton.text, 
6456
 
                                            container: oSpan });
6457
 
 
6458
 
                        oButtonEl = oYUIButton.get("element");
6459
 
 
6460
 
                        if (oButton.isDefault) {
6461
 
 
6462
 
                            oYUIButton.addClass("default");
6463
 
 
6464
 
                            this.defaultHtmlButton = oButtonEl;
6465
 
 
6466
 
                        }
6467
 
    
6468
 
                        if (Lang.isFunction(oButton.handler)) {
6469
 
    
6470
 
                            oYUIButton.set("onclick", { fn: oButton.handler, 
6471
 
                                obj: this, scope: this });
6472
 
            
6473
 
                        }
6474
 
                        else if (Lang.isObject(oButton.handler) && 
6475
 
                            Lang.isFunction(oButton.handler.fn)) {
6476
 
 
6477
 
                            oYUIButton.set("onclick", { fn: oButton.handler.fn, 
6478
 
                                obj: ((!Lang.isUndefined(oButton.handler.obj)) ? 
6479
 
                                oButton.handler.obj : this), 
6480
 
                                scope: (oButton.handler.scope || this) });
6481
 
    
6482
 
                        }
6483
 
 
6484
 
                        this._aButtons[this._aButtons.length] = oYUIButton;
6485
 
 
6486
 
                    }
6487
 
                    else {
6488
 
        
6489
 
                        oButtonEl = document.createElement("button");
6490
 
                        oButtonEl.setAttribute("type", "button");
6491
 
            
6492
 
                        if (oButton.isDefault) {
6493
 
                            oButtonEl.className = "default";
6494
 
                            this.defaultHtmlButton = oButtonEl;
6495
 
                        }
6496
 
    
6497
 
                        oButtonEl.innerHTML = oButton.text;
6498
 
    
6499
 
                        if (Lang.isFunction(oButton.handler)) {
6500
 
    
6501
 
                            Event.on(oButtonEl, "click", oButton.handler, 
6502
 
                                this, true);
6503
 
            
6504
 
                        }
6505
 
                        else if (Lang.isObject(oButton.handler) && 
6506
 
                            Lang.isFunction(oButton.handler.fn)) {
6507
 
    
6508
 
                            Event.on(oButtonEl, "click", oButton.handler.fn, 
6509
 
                                ((!Lang.isUndefined(oButton.handler.obj)) ? 
6510
 
                                oButton.handler.obj : this), 
6511
 
                                (oButton.handler.scope || this));
6512
 
    
6513
 
                        }
6514
 
            
6515
 
                        oSpan.appendChild(oButtonEl);
6516
 
                        
6517
 
                        this._aButtons[this._aButtons.length] = oButtonEl;
6518
 
                        
6519
 
                    }
6520
 
 
6521
 
                    oButton.htmlButton = oButtonEl;
6522
 
        
6523
 
                    if (i === 0) {
6524
 
                        this.firstButton = oButtonEl;
6525
 
                    }
6526
 
        
6527
 
                    if (i == (nButtons - 1)) {
6528
 
                        this.lastButton = oButtonEl;
6529
 
                    }
6530
 
        
6531
 
                }
6532
 
        
6533
 
                this.setFooter(oSpan);
6534
 
 
6535
 
                oFooter = this.footer;
6536
 
                
6537
 
                if (Dom.inDocument(this.element) && 
6538
 
                    !Dom.isAncestor(oInnerElement, oFooter)) {
6539
 
    
6540
 
                    oInnerElement.appendChild(oFooter);
6541
 
                
6542
 
                }
6543
 
 
6544
 
                this.buttonSpan = oSpan;
6545
 
 
6546
 
            } else { // Do cleanup
6547
 
 
6548
 
                oSpan = this.buttonSpan;
6549
 
                oFooter = this.footer;
6550
 
 
6551
 
                if (oSpan && oFooter) {
6552
 
 
6553
 
                    oFooter.removeChild(oSpan);
6554
 
 
6555
 
                    this.buttonSpan = null;
6556
 
                    this.firstButton = null;
6557
 
                    this.lastButton = null;
6558
 
                    this.defaultHtmlButton = null;
6559
 
 
6560
 
                }
6561
 
 
6562
 
            }
6563
 
 
6564
 
            this.cfg.refireEvent("iframe");
6565
 
            this.cfg.refireEvent("underlay");
6566
 
        },
6567
 
 
6568
 
        /**
6569
 
        * @method getButtons
6570
 
        * @description Returns an array containing each of the Dialog's 
6571
 
        * buttons, by default an array of HTML <code>&#60;BUTTON&#62;</code> 
6572
 
        * elements.  If the Dialog's buttons were created using the 
6573
 
        * YAHOO.widget.Button class (via the inclusion of the optional Button 
6574
 
        * dependancy on the page), an array of YAHOO.widget.Button instances 
6575
 
        * is returned.
6576
 
        * @return {Array}
6577
 
        */
6578
 
        getButtons: function () {
6579
 
            var aButtons = this._aButtons;
6580
 
            if (aButtons) {
6581
 
                return aButtons;
6582
 
            }
6583
 
        },
6584
 
        
6585
 
        /**
6586
 
        * Sets focus to the first element in the Dialog's form or the first 
6587
 
        * button defined via the "buttons" configuration property. Called 
6588
 
        * when the Dialog is made visible.
6589
 
        * @method focusFirst
6590
 
        */
6591
 
        focusFirst: function (type, args, obj) {
6592
 
    
6593
 
            var oElement = this.firstFormElement,
6594
 
                oEvent;
6595
 
 
6596
 
            if (args) {
6597
 
                oEvent = args[1];
6598
 
                if (oEvent) {
6599
 
                    Event.stopEvent(oEvent);
6600
 
                }
6601
 
            }
6602
 
 
6603
 
            if (oElement) {
6604
 
                /*
6605
 
                    Place the call to the "focus" method inside a try/catch
6606
 
                    block to prevent IE from throwing JavaScript errors if
6607
 
                    the element is disabled or hidden.
6608
 
                */
6609
 
                try {
6610
 
                    oElement.focus();
6611
 
                }
6612
 
                catch(oException) {
6613
 
                }
6614
 
 
6615
 
            } else {
6616
 
                this.focusDefaultButton();
6617
 
            }
6618
 
        },
6619
 
        
6620
 
        /**
6621
 
        * Sets focus to the last element in the Dialog's form or the last 
6622
 
        * button defined via the "buttons" configuration property.
6623
 
        * @method focusLast
6624
 
        */
6625
 
        focusLast: function (type, args, obj) {
6626
 
    
6627
 
            var aButtons = this.cfg.getProperty("buttons"),
6628
 
                oElement = this.lastFormElement,
6629
 
                oEvent;
6630
 
    
6631
 
            if (args) {
6632
 
                oEvent = args[1];
6633
 
                if (oEvent) {
6634
 
                    Event.stopEvent(oEvent);
6635
 
                }
6636
 
            }
6637
 
            
6638
 
            if (aButtons && Lang.isArray(aButtons)) {
6639
 
                this.focusLastButton();
6640
 
            } else {
6641
 
                if (oElement) {
6642
 
                    /*
6643
 
                        Place the call to the "focus" method inside a try/catch
6644
 
                        block to prevent IE from throwing JavaScript errors if
6645
 
                        the element is disabled or hidden.
6646
 
                    */
6647
 
    
6648
 
                    try {
6649
 
                        oElement.focus();
6650
 
                    } catch(oException) {
6651
 
                    }
6652
 
                }
6653
 
            }
6654
 
        },
6655
 
        
6656
 
        /**
6657
 
        * Sets the focus to the button that is designated as the default via 
6658
 
        * the "buttons" configuration property. By default, this method is 
6659
 
        * called when the Dialog is made visible.
6660
 
        * @method focusDefaultButton
6661
 
        */
6662
 
        focusDefaultButton: function () {
6663
 
        
6664
 
            var oElement = this.defaultHtmlButton;
6665
 
        
6666
 
            if (oElement) {
6667
 
 
6668
 
                /*
6669
 
                    Place the call to the "focus" method inside a try/catch
6670
 
                    block to prevent IE from throwing JavaScript errors if
6671
 
                    the element is disabled or hidden.
6672
 
                */
6673
 
                try {
6674
 
                    oElement.focus();
6675
 
                } catch(oException) {
6676
 
                }
6677
 
 
6678
 
            }
6679
 
        },
6680
 
        
6681
 
        /**
6682
 
        * Blurs all the buttons defined via the "buttons" 
6683
 
        * configuration property.
6684
 
        * @method blurButtons
6685
 
        */
6686
 
        blurButtons: function () {
6687
 
            
6688
 
            var aButtons = this.cfg.getProperty("buttons"),
6689
 
                nButtons,
6690
 
                oButton,
6691
 
                oElement,
6692
 
                i;
6693
 
 
6694
 
            if (aButtons && Lang.isArray(aButtons)) {
6695
 
            
6696
 
                nButtons = aButtons.length;
6697
 
                
6698
 
                if (nButtons > 0) {
6699
 
                
6700
 
                    i = (nButtons - 1);
6701
 
                    
6702
 
                    do {
6703
 
                        oButton = aButtons[i];
6704
 
                        
6705
 
                        if (oButton) {
6706
 
 
6707
 
                            oElement = oButton.htmlButton;
6708
 
 
6709
 
                            if (oElement) {
6710
 
                                /*
6711
 
                                    Place the call to the "blur" method inside  
6712
 
                                    a try/catch block to prevent IE from  
6713
 
                                    throwing JavaScript errors if the element 
6714
 
                                    is disabled or hidden.
6715
 
                                */
6716
 
                                try {
6717
 
                                    oElement.blur();
6718
 
                                } catch(oException) {
6719
 
                                }
6720
 
                            }
6721
 
                        }
6722
 
                    
6723
 
                    } while(i--);
6724
 
                }
6725
 
            }
6726
 
        },
6727
 
        
6728
 
        /**
6729
 
        * Sets the focus to the first button created via the "buttons"
6730
 
        * configuration property.
6731
 
        * @method focusFirstButton
6732
 
        */
6733
 
        focusFirstButton: function () {
6734
 
    
6735
 
            var aButtons = this.cfg.getProperty("buttons"),
6736
 
                oButton,
6737
 
                oElement;
6738
 
 
6739
 
            if (aButtons && Lang.isArray(aButtons)) {
6740
 
 
6741
 
                oButton = aButtons[0];
6742
 
 
6743
 
                if (oButton) {
6744
 
 
6745
 
                    oElement = oButton.htmlButton;
6746
 
                    
6747
 
                    if (oElement) {
6748
 
 
6749
 
                        /*
6750
 
                            Place the call to the "focus" method inside a 
6751
 
                            try/catch block to prevent IE from throwing 
6752
 
                            JavaScript errors if the element is disabled 
6753
 
                            or hidden.
6754
 
                        */
6755
 
    
6756
 
                        try {
6757
 
                            oElement.focus();
6758
 
                        }
6759
 
                        catch(oException) {
6760
 
                        }
6761
 
                    }
6762
 
                }
6763
 
            }
6764
 
        },
6765
 
        
6766
 
        /**
6767
 
        * Sets the focus to the last button created via the "buttons" 
6768
 
        * configuration property.
6769
 
        * @method focusLastButton
6770
 
        */
6771
 
        focusLastButton: function () {
6772
 
    
6773
 
            var aButtons = this.cfg.getProperty("buttons"),
6774
 
                nButtons,
6775
 
                oButton,
6776
 
                oElement;
6777
 
 
6778
 
            if (aButtons && Lang.isArray(aButtons)) {
6779
 
 
6780
 
                nButtons = aButtons.length;
6781
 
                
6782
 
                if (nButtons > 0) {
6783
 
                    oButton = aButtons[(nButtons - 1)];
6784
 
                    
6785
 
                    if (oButton) {
6786
 
                        oElement = oButton.htmlButton;
6787
 
                        if (oElement) {
6788
 
                            /*
6789
 
                                Place the call to the "focus" method inside a 
6790
 
                                try/catch block to prevent IE from throwing 
6791
 
                                JavaScript errors if the element is disabled
6792
 
                                or hidden.
6793
 
                            */
6794
 
        
6795
 
                            try {
6796
 
                                oElement.focus();
6797
 
                            } catch(oException) {
6798
 
                            }
6799
 
                        }
6800
 
                    }
6801
 
                }
6802
 
            }
6803
 
        },
6804
 
        
6805
 
        /**
6806
 
        * The default event handler for the "postmethod" configuration property
6807
 
        * @method configPostMethod
6808
 
        * @param {String} type The CustomEvent type (usually the property name)
6809
 
        * @param {Object[]} args The CustomEvent arguments. For 
6810
 
        * configuration handlers, args[0] will equal the newly applied value 
6811
 
        * for the property.
6812
 
        * @param {Object} obj The scope object. For configuration handlers, 
6813
 
        * this will usually equal the owner.
6814
 
        */
6815
 
        configPostMethod: function (type, args, obj) {
6816
 
            this.registerForm();
6817
 
        },
6818
 
        
6819
 
        // END BUILT-IN PROPERTY EVENT HANDLERS //
6820
 
        
6821
 
        /**
6822
 
        * Built-in function hook for writing a validation function that will 
6823
 
        * be checked for a "true" value prior to a submit. This function, as 
6824
 
        * implemented by default, always returns true, so it should be 
6825
 
        * overridden if validation is necessary.
6826
 
        * @method validate
6827
 
        */
6828
 
        validate: function () {
6829
 
            return true;
6830
 
        },
6831
 
        
6832
 
        /**
6833
 
        * Executes a submit of the Dialog if validation 
6834
 
        * is successful. By default the Dialog is hidden
6835
 
        * after submission, but you can set the "hideaftersubmit"
6836
 
        * configuration property to false, to prevent the Dialog
6837
 
        * from being hidden.
6838
 
        * 
6839
 
        * @method submit
6840
 
        */
6841
 
        submit: function () {
6842
 
            if (this.validate()) {
6843
 
                this.beforeSubmitEvent.fire();
6844
 
                this.doSubmit();
6845
 
                this.submitEvent.fire();
6846
 
 
6847
 
                if (this.cfg.getProperty("hideaftersubmit")) {
6848
 
                    this.hide();
6849
 
                }
6850
 
 
6851
 
                return true;
6852
 
            } else {
6853
 
                return false;
6854
 
            }
6855
 
        },
6856
 
 
6857
 
        /**
6858
 
        * Executes the cancel of the Dialog followed by a hide.
6859
 
        * @method cancel
6860
 
        */
6861
 
        cancel: function () {
6862
 
            this.cancelEvent.fire();
6863
 
            this.hide();
6864
 
        },
6865
 
        
6866
 
        /**
6867
 
        * Returns a JSON-compatible data structure representing the data 
6868
 
        * currently contained in the form.
6869
 
        * @method getData
6870
 
        * @return {Object} A JSON object reprsenting the data of the 
6871
 
        * current form.
6872
 
        */
6873
 
        getData: function () {
6874
 
        
6875
 
            var oForm = this.form,
6876
 
                aElements,
6877
 
                nTotalElements,
6878
 
                oData,
6879
 
                sName,
6880
 
                oElement,
6881
 
                nElements,
6882
 
                sType,
6883
 
                sTagName,
6884
 
                aOptions,
6885
 
                nOptions,
6886
 
                aValues,
6887
 
                oOption,
6888
 
                sValue,
6889
 
                oRadio,
6890
 
                oCheckbox,
6891
 
                i,
6892
 
                n;    
6893
 
    
6894
 
            function isFormElement(p_oElement) {
6895
 
            
6896
 
                var sTag = p_oElement.tagName.toUpperCase();
6897
 
                
6898
 
                return ((sTag == "INPUT" || sTag == "TEXTAREA" || 
6899
 
                        sTag == "SELECT") && p_oElement.name == sName);
6900
 
    
6901
 
            }
6902
 
    
6903
 
    
6904
 
            if (oForm) {
6905
 
        
6906
 
                aElements = oForm.elements;
6907
 
                nTotalElements = aElements.length;
6908
 
                oData = {};
6909
 
    
6910
 
        
6911
 
                for (i = 0; i < nTotalElements; i++) {
6912
 
        
6913
 
                    sName = aElements[i].name;
6914
 
        
6915
 
                    /*
6916
 
                        Using "Dom.getElementsBy" to safeguard user from JS 
6917
 
                        errors that result from giving a form field (or set of 
6918
 
                        fields) the same name as a native method of a form 
6919
 
                        (like "submit") or a DOM collection (such as the "item"
6920
 
                        method). Originally tried accessing fields via the 
6921
 
                        "namedItem" method of the "element" collection, but 
6922
 
                        discovered that it won't return a collection of fields 
6923
 
                        in Gecko.
6924
 
                    */
6925
 
        
6926
 
                    oElement = Dom.getElementsBy(isFormElement, "*", oForm);
6927
 
                    nElements = oElement.length;
6928
 
        
6929
 
                    if (nElements > 0) {
6930
 
        
6931
 
                        if (nElements == 1) {
6932
 
        
6933
 
                            oElement = oElement[0];
6934
 
        
6935
 
                            sType = oElement.type;
6936
 
                            sTagName = oElement.tagName.toUpperCase();
6937
 
        
6938
 
                            switch (sTagName) {
6939
 
        
6940
 
                            case "INPUT":
6941
 
    
6942
 
                                if (sType == "checkbox") {
6943
 
    
6944
 
                                    oData[sName] = oElement.checked;
6945
 
    
6946
 
                                }
6947
 
                                else if (sType != "radio") {
6948
 
    
6949
 
                                    oData[sName] = oElement.value;
6950
 
    
6951
 
                                }
6952
 
    
6953
 
                                break;
6954
 
    
6955
 
                            case "TEXTAREA":
6956
 
    
6957
 
                                oData[sName] = oElement.value;
6958
 
    
6959
 
                                break;
6960
 
    
6961
 
                            case "SELECT":
6962
 
    
6963
 
                                aOptions = oElement.options;
6964
 
                                nOptions = aOptions.length;
6965
 
                                aValues = [];
6966
 
    
6967
 
                                for (n = 0; n < nOptions; n++) {
6968
 
    
6969
 
                                    oOption = aOptions[n];
6970
 
    
6971
 
                                    if (oOption.selected) {
6972
 
    
6973
 
                                        sValue = oOption.value;
6974
 
    
6975
 
                                        if (!sValue || sValue === "") {
6976
 
    
6977
 
                                            sValue = oOption.text;
6978
 
    
6979
 
                                        }
6980
 
    
6981
 
                                        aValues[aValues.length] = sValue;
6982
 
    
6983
 
                                    }
6984
 
    
6985
 
                                }
6986
 
    
6987
 
                                oData[sName] = aValues;
6988
 
    
6989
 
                                break;
6990
 
        
6991
 
                            }
6992
 
        
6993
 
        
6994
 
                        }
6995
 
                        else {
6996
 
        
6997
 
                            sType = oElement[0].type;
6998
 
        
6999
 
                            switch (sType) {
7000
 
        
7001
 
                            case "radio":
7002
 
    
7003
 
                                for (n = 0; n < nElements; n++) {
7004
 
    
7005
 
                                    oRadio = oElement[n];
7006
 
    
7007
 
                                    if (oRadio.checked) {
7008
 
    
7009
 
                                        oData[sName] = oRadio.value;
7010
 
                                        break;
7011
 
    
7012
 
                                    }
7013
 
    
7014
 
                                }
7015
 
    
7016
 
                                break;
7017
 
    
7018
 
                            case "checkbox":
7019
 
    
7020
 
                                aValues = [];
7021
 
    
7022
 
                                for (n = 0; n < nElements; n++) {
7023
 
    
7024
 
                                    oCheckbox = oElement[n];
7025
 
    
7026
 
                                    if (oCheckbox.checked) {
7027
 
    
7028
 
                                        aValues[aValues.length] = 
7029
 
                                            oCheckbox.value;
7030
 
    
7031
 
                                    }
7032
 
    
7033
 
                                }
7034
 
    
7035
 
                                oData[sName] = aValues;
7036
 
    
7037
 
                                break;
7038
 
        
7039
 
                            }
7040
 
        
7041
 
                        }
7042
 
        
7043
 
                    }
7044
 
        
7045
 
                }
7046
 
        
7047
 
            }
7048
 
        
7049
 
        
7050
 
            return oData;
7051
 
        
7052
 
        },
7053
 
        
7054
 
        /**
7055
 
        * Removes the Panel element from the DOM and sets all child elements 
7056
 
        * to null.
7057
 
        * @method destroy
7058
 
        */
7059
 
        destroy: function () {
7060
 
        
7061
 
            removeButtonEventHandlers.call(this);
7062
 
            
7063
 
            this._aButtons = null;
7064
 
 
7065
 
            var aForms = this.element.getElementsByTagName("form"),
7066
 
                oForm;
7067
 
            
7068
 
            if (aForms.length > 0) {
7069
 
 
7070
 
                oForm = aForms[0];
7071
 
 
7072
 
                if (oForm) {
7073
 
                    Event.purgeElement(oForm);
7074
 
                    if (oForm.parentNode) {
7075
 
                        oForm.parentNode.removeChild(oForm);
7076
 
                    }
7077
 
                    this.form = null;
7078
 
                }
7079
 
            }
7080
 
        
7081
 
            Dialog.superclass.destroy.call(this);  
7082
 
        
7083
 
        },
7084
 
        
7085
 
        /**
7086
 
        * Returns a string representation of the object.
7087
 
        * @method toString
7088
 
        * @return {String} The string representation of the Dialog
7089
 
        */
7090
 
        toString: function () {
7091
 
            return "Dialog " + this.id;
7092
 
        }
7093
 
    
7094
 
    });
7095
 
 
7096
 
}());
7097
 
 
7098
 
(function () {
7099
 
 
7100
 
    /**
7101
 
    * SimpleDialog is a simple implementation of Dialog that can be used to 
7102
 
    * submit a single value. Forms can be processed in 3 ways -- via an 
7103
 
    * asynchronous Connection utility call, a simple form POST or GET, 
7104
 
    * or manually.
7105
 
    * @namespace YAHOO.widget
7106
 
    * @class SimpleDialog
7107
 
    * @extends YAHOO.widget.Dialog
7108
 
    * @constructor
7109
 
    * @param {String} el The element ID representing the SimpleDialog 
7110
 
    * <em>OR</em>
7111
 
    * @param {HTMLElement} el The element representing the SimpleDialog
7112
 
    * @param {Object} userConfig The configuration object literal containing 
7113
 
    * the configuration that should be set for this SimpleDialog. See 
7114
 
    * configuration documentation for more details.
7115
 
    */
7116
 
    YAHOO.widget.SimpleDialog = function (el, userConfig) {
7117
 
    
7118
 
        YAHOO.widget.SimpleDialog.superclass.constructor.call(this, 
7119
 
            el, userConfig);
7120
 
    
7121
 
    };
7122
 
 
7123
 
    var Dom = YAHOO.util.Dom,
7124
 
        SimpleDialog = YAHOO.widget.SimpleDialog,
7125
 
    
7126
 
        /**
7127
 
        * Constant representing the SimpleDialog's configuration properties
7128
 
        * @property DEFAULT_CONFIG
7129
 
        * @private
7130
 
        * @final
7131
 
        * @type Object
7132
 
        */
7133
 
        DEFAULT_CONFIG = {
7134
 
        
7135
 
            "ICON": { 
7136
 
                key: "icon", 
7137
 
                value: "none", 
7138
 
                suppressEvent: true  
7139
 
            },
7140
 
        
7141
 
            "TEXT": { 
7142
 
                key: "text", 
7143
 
                value: "", 
7144
 
                suppressEvent: true, 
7145
 
                supercedes: ["icon"] 
7146
 
            }
7147
 
        
7148
 
        };
7149
 
 
7150
 
    /**
7151
 
    * Constant for the standard network icon for a blocking action
7152
 
    * @property YAHOO.widget.SimpleDialog.ICON_BLOCK
7153
 
    * @static
7154
 
    * @final
7155
 
    * @type String
7156
 
    */
7157
 
    SimpleDialog.ICON_BLOCK = "blckicon";
7158
 
    
7159
 
    /**
7160
 
    * Constant for the standard network icon for alarm
7161
 
    * @property YAHOO.widget.SimpleDialog.ICON_ALARM
7162
 
    * @static
7163
 
    * @final
7164
 
    * @type String
7165
 
    */
7166
 
    SimpleDialog.ICON_ALARM = "alrticon";
7167
 
    
7168
 
    /**
7169
 
    * Constant for the standard network icon for help
7170
 
    * @property YAHOO.widget.SimpleDialog.ICON_HELP
7171
 
    * @static
7172
 
    * @final
7173
 
    * @type String
7174
 
    */
7175
 
    SimpleDialog.ICON_HELP  = "hlpicon";
7176
 
    
7177
 
    /**
7178
 
    * Constant for the standard network icon for info
7179
 
    * @property YAHOO.widget.SimpleDialog.ICON_INFO
7180
 
    * @static
7181
 
    * @final
7182
 
    * @type String
7183
 
    */
7184
 
    SimpleDialog.ICON_INFO  = "infoicon";
7185
 
    
7186
 
    /**
7187
 
    * Constant for the standard network icon for warn
7188
 
    * @property YAHOO.widget.SimpleDialog.ICON_WARN
7189
 
    * @static
7190
 
    * @final
7191
 
    * @type String
7192
 
    */
7193
 
    SimpleDialog.ICON_WARN  = "warnicon";
7194
 
    
7195
 
    /**
7196
 
    * Constant for the standard network icon for a tip
7197
 
    * @property YAHOO.widget.SimpleDialog.ICON_TIP
7198
 
    * @static
7199
 
    * @final
7200
 
    * @type String
7201
 
    */
7202
 
    SimpleDialog.ICON_TIP   = "tipicon";
7203
 
 
7204
 
    /**
7205
 
    * Constant representing the name of the CSS class applied to the element 
7206
 
    * created by the "icon" configuration property.
7207
 
    * @property YAHOO.widget.SimpleDialog.ICON_CSS_CLASSNAME
7208
 
    * @static
7209
 
    * @final
7210
 
    * @type String
7211
 
    */
7212
 
    SimpleDialog.ICON_CSS_CLASSNAME = "yui-icon";
7213
 
    
7214
 
    /**
7215
 
    * Constant representing the default CSS class used for a SimpleDialog
7216
 
    * @property YAHOO.widget.SimpleDialog.CSS_SIMPLEDIALOG
7217
 
    * @static
7218
 
    * @final
7219
 
    * @type String
7220
 
    */
7221
 
    SimpleDialog.CSS_SIMPLEDIALOG = "yui-simple-dialog";
7222
 
 
7223
 
    
7224
 
    YAHOO.extend(SimpleDialog, YAHOO.widget.Dialog, {
7225
 
    
7226
 
        /**
7227
 
        * Initializes the class's configurable properties which can be changed 
7228
 
        * using the SimpleDialog's Config object (cfg).
7229
 
        * @method initDefaultConfig
7230
 
        */
7231
 
        initDefaultConfig: function () {
7232
 
        
7233
 
            SimpleDialog.superclass.initDefaultConfig.call(this);
7234
 
        
7235
 
            // Add dialog config properties //
7236
 
        
7237
 
            /**
7238
 
            * Sets the informational icon for the SimpleDialog
7239
 
            * @config icon
7240
 
            * @type String
7241
 
            * @default "none"
7242
 
            */
7243
 
            this.cfg.addProperty(DEFAULT_CONFIG.ICON.key, {
7244
 
                handler: this.configIcon,
7245
 
                value: DEFAULT_CONFIG.ICON.value,
7246
 
                suppressEvent: DEFAULT_CONFIG.ICON.suppressEvent
7247
 
            });
7248
 
        
7249
 
            /**
7250
 
            * Sets the text for the SimpleDialog
7251
 
            * @config text
7252
 
            * @type String
7253
 
            * @default ""
7254
 
            */
7255
 
            this.cfg.addProperty(DEFAULT_CONFIG.TEXT.key, { 
7256
 
                handler: this.configText, 
7257
 
                value: DEFAULT_CONFIG.TEXT.value, 
7258
 
                suppressEvent: DEFAULT_CONFIG.TEXT.suppressEvent, 
7259
 
                supercedes: DEFAULT_CONFIG.TEXT.supercedes 
7260
 
            });
7261
 
        
7262
 
        },
7263
 
        
7264
 
        
7265
 
        /**
7266
 
        * The SimpleDialog initialization method, which is executed for 
7267
 
        * SimpleDialog and all of its subclasses. This method is automatically 
7268
 
        * called by the constructor, and  sets up all DOM references for 
7269
 
        * pre-existing markup, and creates required markup if it is not 
7270
 
        * already present.
7271
 
        * @method init
7272
 
        * @param {String} el The element ID representing the SimpleDialog 
7273
 
        * <em>OR</em>
7274
 
        * @param {HTMLElement} el The element representing the SimpleDialog
7275
 
        * @param {Object} userConfig The configuration object literal 
7276
 
        * containing the configuration that should be set for this 
7277
 
        * SimpleDialog. See configuration documentation for more details.
7278
 
        */
7279
 
        init: function (el, userConfig) {
7280
 
 
7281
 
            /*
7282
 
                Note that we don't pass the user config in here yet because we 
7283
 
                only want it executed once, at the lowest subclass level
7284
 
            */
7285
 
 
7286
 
            SimpleDialog.superclass.init.call(this, el/*, userConfig*/);
7287
 
        
7288
 
            this.beforeInitEvent.fire(SimpleDialog);
7289
 
        
7290
 
            Dom.addClass(this.element, SimpleDialog.CSS_SIMPLEDIALOG);
7291
 
        
7292
 
            this.cfg.queueProperty("postmethod", "manual");
7293
 
        
7294
 
            if (userConfig) {
7295
 
                this.cfg.applyConfig(userConfig, true);
7296
 
            }
7297
 
        
7298
 
            this.beforeRenderEvent.subscribe(function () {
7299
 
                if (! this.body) {
7300
 
                    this.setBody("");
7301
 
                }
7302
 
            }, this, true);
7303
 
        
7304
 
            this.initEvent.fire(SimpleDialog);
7305
 
        
7306
 
        },
7307
 
        
7308
 
        /**
7309
 
        * Prepares the SimpleDialog's internal FORM object, creating one if one 
7310
 
        * is not currently present, and adding the value hidden field.
7311
 
        * @method registerForm
7312
 
        */
7313
 
        registerForm: function () {
7314
 
 
7315
 
            SimpleDialog.superclass.registerForm.call(this);
7316
 
 
7317
 
            this.form.innerHTML += "<input type=\"hidden\" name=\"" + 
7318
 
                this.id + "\" value=\"\"/>";
7319
 
 
7320
 
        },
7321
 
        
7322
 
        // BEGIN BUILT-IN PROPERTY EVENT HANDLERS //
7323
 
        
7324
 
        /**
7325
 
        * Fired when the "icon" property is set.
7326
 
        * @method configIcon
7327
 
        * @param {String} type The CustomEvent type (usually the property name)
7328
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
7329
 
        * handlers, args[0] will equal the newly applied value for the property.
7330
 
        * @param {Object} obj The scope object. For configuration handlers, 
7331
 
        * this will usually equal the owner.
7332
 
        */
7333
 
        configIcon: function (type,args,obj) {
7334
 
        
7335
 
            var sIcon = args[0],
7336
 
                oBody = this.body,
7337
 
                sCSSClass = SimpleDialog.ICON_CSS_CLASSNAME,
7338
 
                oIcon,
7339
 
                oIconParent;
7340
 
        
7341
 
            if (sIcon && sIcon != "none") {
7342
 
 
7343
 
                oIcon = Dom.getElementsByClassName(sCSSClass, "*" , oBody);
7344
 
 
7345
 
                if (oIcon) {
7346
 
 
7347
 
                    oIconParent = oIcon.parentNode;
7348
 
                    
7349
 
                    if (oIconParent) {
7350
 
                    
7351
 
                        oIconParent.removeChild(oIcon);
7352
 
                        
7353
 
                        oIcon = null;
7354
 
                    
7355
 
                    }
7356
 
 
7357
 
                }
7358
 
 
7359
 
 
7360
 
                if (sIcon.indexOf(".") == -1) {
7361
 
 
7362
 
                    oIcon = document.createElement("span");
7363
 
                    oIcon.className = (sCSSClass + " " + sIcon);
7364
 
                    oIcon.innerHTML = "&#160;";
7365
 
 
7366
 
                } else {
7367
 
 
7368
 
                    oIcon = document.createElement("img");
7369
 
                    oIcon.src = (this.imageRoot + sIcon);
7370
 
                    oIcon.className = sCSSClass;
7371
 
 
7372
 
                }
7373
 
                
7374
 
 
7375
 
                if (oIcon) {
7376
 
                
7377
 
                    oBody.insertBefore(oIcon, oBody.firstChild);
7378
 
                
7379
 
                }
7380
 
 
7381
 
            }
7382
 
 
7383
 
        },
7384
 
        
7385
 
        /**
7386
 
        * Fired when the "text" property is set.
7387
 
        * @method configText
7388
 
        * @param {String} type The CustomEvent type (usually the property name)
7389
 
        * @param {Object[]} args The CustomEvent arguments. For configuration 
7390
 
        * handlers, args[0] will equal the newly applied value for the property.
7391
 
        * @param {Object} obj The scope object. For configuration handlers, 
7392
 
        * this will usually equal the owner.
7393
 
        */
7394
 
        configText: function (type,args,obj) {
7395
 
            var text = args[0];
7396
 
            if (text) {
7397
 
                this.setBody(text);
7398
 
                this.cfg.refireEvent("icon");
7399
 
            }
7400
 
        },
7401
 
        
7402
 
        // END BUILT-IN PROPERTY EVENT HANDLERS //
7403
 
        
7404
 
        /**
7405
 
        * Returns a string representation of the object.
7406
 
        * @method toString
7407
 
        * @return {String} The string representation of the SimpleDialog
7408
 
        */
7409
 
        toString: function () {
7410
 
            return "SimpleDialog " + this.id;
7411
 
        }
7412
 
    
7413
 
    });
7414
 
 
7415
 
}());
7416
 
 
7417
 
(function () {
7418
 
 
7419
 
    /**
7420
 
    * ContainerEffect encapsulates animation transitions that are executed when 
7421
 
    * an Overlay is shown or hidden.
7422
 
    * @namespace YAHOO.widget
7423
 
    * @class ContainerEffect
7424
 
    * @constructor
7425
 
    * @param {YAHOO.widget.Overlay} overlay The Overlay that the animation 
7426
 
    * should be associated with
7427
 
    * @param {Object} attrIn The object literal representing the animation 
7428
 
    * arguments to be used for the animate-in transition. The arguments for 
7429
 
    * this literal are: attributes(object, see YAHOO.util.Anim for description), 
7430
 
    * duration(Number), and method(i.e. Easing.easeIn).
7431
 
    * @param {Object} attrOut The object literal representing the animation 
7432
 
    * arguments to be used for the animate-out transition. The arguments for  
7433
 
    * this literal are: attributes(object, see YAHOO.util.Anim for description), 
7434
 
    * duration(Number), and method(i.e. Easing.easeIn).
7435
 
    * @param {HTMLElement} targetElement Optional. The target element that  
7436
 
    * should be animated during the transition. Defaults to overlay.element.
7437
 
    * @param {class} Optional. The animation class to instantiate. Defaults to 
7438
 
    * YAHOO.util.Anim. Other options include YAHOO.util.Motion.
7439
 
    */
7440
 
    YAHOO.widget.ContainerEffect = 
7441
 
    
7442
 
        function (overlay, attrIn, attrOut, targetElement, animClass) {
7443
 
    
7444
 
        if (!animClass) {
7445
 
            animClass = YAHOO.util.Anim;
7446
 
        }
7447
 
        
7448
 
        /**
7449
 
        * The overlay to animate
7450
 
        * @property overlay
7451
 
        * @type YAHOO.widget.Overlay
7452
 
        */
7453
 
        this.overlay = overlay;
7454
 
    
7455
 
        /**
7456
 
        * The animation attributes to use when transitioning into view
7457
 
        * @property attrIn
7458
 
        * @type Object
7459
 
        */
7460
 
        this.attrIn = attrIn;
7461
 
    
7462
 
        /**
7463
 
        * The animation attributes to use when transitioning out of view
7464
 
        * @property attrOut
7465
 
        * @type Object
7466
 
        */
7467
 
        this.attrOut = attrOut;
7468
 
    
7469
 
        /**
7470
 
        * The target element to be animated
7471
 
        * @property targetElement
7472
 
        * @type HTMLElement
7473
 
        */
7474
 
        this.targetElement = targetElement || overlay.element;
7475
 
    
7476
 
        /**
7477
 
        * The animation class to use for animating the overlay
7478
 
        * @property animClass
7479
 
        * @type class
7480
 
        */
7481
 
        this.animClass = animClass;
7482
 
    
7483
 
    };
7484
 
 
7485
 
 
7486
 
    var Dom = YAHOO.util.Dom,
7487
 
        CustomEvent = YAHOO.util.CustomEvent,
7488
 
        Easing = YAHOO.util.Easing,
7489
 
        ContainerEffect = YAHOO.widget.ContainerEffect;
7490
 
 
7491
 
 
7492
 
    /**
7493
 
    * A pre-configured ContainerEffect instance that can be used for fading 
7494
 
    * an overlay in and out.
7495
 
    * @method FADE
7496
 
    * @static
7497
 
    * @param {YAHOO.widget.Overlay} overlay The Overlay object to animate
7498
 
    * @param {Number} dur The duration of the animation
7499
 
    * @return {YAHOO.widget.ContainerEffect} The configured ContainerEffect object
7500
 
    */
7501
 
    ContainerEffect.FADE = function (overlay, dur) {
7502
 
 
7503
 
        var fin = {
7504
 
            attributes: {opacity:{from:0, to:1}},
7505
 
            duration: dur,
7506
 
            method: Easing.easeIn
7507
 
        };
7508
 
 
7509
 
        var fout = {
7510
 
            attributes: {opacity:{to:0}},
7511
 
            duration: dur,
7512
 
            method: Easing.easeOut
7513
 
        };
7514
 
 
7515
 
        var fade = new ContainerEffect(overlay, fin, fout, overlay.element);
7516
 
 
7517
 
        fade.handleUnderlayStart = function() {
7518
 
            var underlay = this.overlay.underlay;
7519
 
            if (underlay && YAHOO.env.ua.ie) {
7520
 
                var hasFilters = (underlay.filters && underlay.filters.length > 0);
7521
 
                if(hasFilters) {
7522
 
                    Dom.addClass(overlay.element, "yui-effect-fade");
7523
 
                }
7524
 
            }
7525
 
        };
7526
 
 
7527
 
        fade.handleUnderlayComplete = function() {
7528
 
            var underlay = this.overlay.underlay;
7529
 
            if (underlay && YAHOO.env.ua.ie) {
7530
 
                Dom.removeClass(overlay.element, "yui-effect-fade");
7531
 
            }
7532
 
        };
7533
 
 
7534
 
        fade.handleStartAnimateIn = function (type,args,obj) {
7535
 
            Dom.addClass(obj.overlay.element, "hide-select");
7536
 
 
7537
 
            if (!obj.overlay.underlay) {
7538
 
                obj.overlay.cfg.refireEvent("underlay");
7539
 
            }
7540
 
 
7541
 
            obj.handleUnderlayStart();
7542
 
 
7543
 
            Dom.setStyle(obj.overlay.element, "visibility", "visible");
7544
 
            Dom.setStyle(obj.overlay.element, "opacity", 0);
7545
 
        };
7546
 
 
7547
 
        fade.handleCompleteAnimateIn = function (type,args,obj) {
7548
 
            Dom.removeClass(obj.overlay.element, "hide-select");
7549
 
 
7550
 
            if (obj.overlay.element.style.filter) {
7551
 
                obj.overlay.element.style.filter = null;
7552
 
            }
7553
 
 
7554
 
            obj.handleUnderlayComplete();
7555
 
 
7556
 
            obj.overlay.cfg.refireEvent("iframe");
7557
 
            obj.animateInCompleteEvent.fire();
7558
 
        };
7559
 
 
7560
 
        fade.handleStartAnimateOut = function (type, args, obj) {
7561
 
            Dom.addClass(obj.overlay.element, "hide-select");
7562
 
            obj.handleUnderlayStart();
7563
 
        };
7564
 
 
7565
 
        fade.handleCompleteAnimateOut =  function (type, args, obj) {
7566
 
            Dom.removeClass(obj.overlay.element, "hide-select");
7567
 
            if (obj.overlay.element.style.filter) {
7568
 
                obj.overlay.element.style.filter = null;
7569
 
            }
7570
 
            Dom.setStyle(obj.overlay.element, "visibility", "hidden");
7571
 
            Dom.setStyle(obj.overlay.element, "opacity", 1);
7572
 
 
7573
 
            obj.handleUnderlayComplete();
7574
 
 
7575
 
            obj.overlay.cfg.refireEvent("iframe");
7576
 
            obj.animateOutCompleteEvent.fire();
7577
 
        };
7578
 
 
7579
 
        fade.init();
7580
 
        return fade;
7581
 
    };
7582
 
    
7583
 
    
7584
 
    /**
7585
 
    * A pre-configured ContainerEffect instance that can be used for sliding an 
7586
 
    * overlay in and out.
7587
 
    * @method SLIDE
7588
 
    * @static
7589
 
    * @param {YAHOO.widget.Overlay} overlay The Overlay object to animate
7590
 
    * @param {Number} dur The duration of the animation
7591
 
    * @return {YAHOO.widget.ContainerEffect} The configured ContainerEffect object
7592
 
    */
7593
 
    ContainerEffect.SLIDE = function (overlay, dur) {
7594
 
    
7595
 
        var x = overlay.cfg.getProperty("x") || Dom.getX(overlay.element),
7596
 
    
7597
 
            y = overlay.cfg.getProperty("y") || Dom.getY(overlay.element),
7598
 
    
7599
 
            clientWidth = Dom.getClientWidth(),
7600
 
    
7601
 
            offsetWidth = overlay.element.offsetWidth,
7602
 
    
7603
 
            slide = new ContainerEffect(overlay, 
7604
 
            
7605
 
            { attributes: { points: { to: [x, y] } },
7606
 
                duration: dur,
7607
 
                method: Easing.easeIn },
7608
 
    
7609
 
            { attributes: { points: { to: [(clientWidth + 25), y] } },
7610
 
                duration: dur,
7611
 
                method: Easing.easeOut },
7612
 
    
7613
 
            overlay.element, YAHOO.util.Motion);
7614
 
        
7615
 
        
7616
 
        slide.handleStartAnimateIn = function (type,args,obj) {
7617
 
            obj.overlay.element.style.left = ((-25) - offsetWidth) + "px";
7618
 
            obj.overlay.element.style.top  = y + "px";
7619
 
        };
7620
 
        
7621
 
        slide.handleTweenAnimateIn = function (type, args, obj) {
7622
 
        
7623
 
            var pos = Dom.getXY(obj.overlay.element),
7624
 
                currentX = pos[0],
7625
 
                currentY = pos[1];
7626
 
        
7627
 
            if (Dom.getStyle(obj.overlay.element, "visibility") == 
7628
 
                "hidden" && currentX < x) {
7629
 
 
7630
 
                Dom.setStyle(obj.overlay.element, "visibility", "visible");
7631
 
 
7632
 
            }
7633
 
        
7634
 
            obj.overlay.cfg.setProperty("xy", [currentX, currentY], true);
7635
 
            obj.overlay.cfg.refireEvent("iframe");
7636
 
        };
7637
 
        
7638
 
        slide.handleCompleteAnimateIn = function (type, args, obj) {
7639
 
            obj.overlay.cfg.setProperty("xy", [x, y], true);
7640
 
            obj.startX = x;
7641
 
            obj.startY = y;
7642
 
            obj.overlay.cfg.refireEvent("iframe");
7643
 
            obj.animateInCompleteEvent.fire();
7644
 
        };
7645
 
        
7646
 
        slide.handleStartAnimateOut = function (type, args, obj) {
7647
 
    
7648
 
            var vw = Dom.getViewportWidth(),
7649
 
                pos = Dom.getXY(obj.overlay.element),
7650
 
                yso = pos[1];
7651
 
    
7652
 
            obj.animOut.attributes.points.to = [(vw + 25), yso];
7653
 
        };
7654
 
        
7655
 
        slide.handleTweenAnimateOut = function (type, args, obj) {
7656
 
    
7657
 
            var pos = Dom.getXY(obj.overlay.element),
7658
 
                xto = pos[0],
7659
 
                yto = pos[1];
7660
 
        
7661
 
            obj.overlay.cfg.setProperty("xy", [xto, yto], true);
7662
 
            obj.overlay.cfg.refireEvent("iframe");
7663
 
        };
7664
 
        
7665
 
        slide.handleCompleteAnimateOut = function (type, args, obj) {
7666
 
            Dom.setStyle(obj.overlay.element, "visibility", "hidden");
7667
 
        
7668
 
            obj.overlay.cfg.setProperty("xy", [x, y]);
7669
 
            obj.animateOutCompleteEvent.fire();
7670
 
        };
7671
 
        
7672
 
        slide.init();
7673
 
        return slide;
7674
 
    };
7675
 
    
7676
 
    ContainerEffect.prototype = {
7677
 
    
7678
 
        /**
7679
 
        * Initializes the animation classes and events.
7680
 
        * @method init
7681
 
        */
7682
 
        init: function () {
7683
 
 
7684
 
            this.beforeAnimateInEvent = this.createEvent("beforeAnimateIn");
7685
 
            this.beforeAnimateInEvent.signature = CustomEvent.LIST;
7686
 
            
7687
 
            this.beforeAnimateOutEvent = this.createEvent("beforeAnimateOut");
7688
 
            this.beforeAnimateOutEvent.signature = CustomEvent.LIST;
7689
 
        
7690
 
            this.animateInCompleteEvent = this.createEvent("animateInComplete");
7691
 
            this.animateInCompleteEvent.signature = CustomEvent.LIST;
7692
 
        
7693
 
            this.animateOutCompleteEvent = 
7694
 
                this.createEvent("animateOutComplete");
7695
 
            this.animateOutCompleteEvent.signature = CustomEvent.LIST;
7696
 
        
7697
 
            this.animIn = new this.animClass(this.targetElement, 
7698
 
                this.attrIn.attributes, this.attrIn.duration, 
7699
 
                this.attrIn.method);
7700
 
 
7701
 
            this.animIn.onStart.subscribe(this.handleStartAnimateIn, this);
7702
 
            this.animIn.onTween.subscribe(this.handleTweenAnimateIn, this);
7703
 
 
7704
 
            this.animIn.onComplete.subscribe(this.handleCompleteAnimateIn, 
7705
 
                this);
7706
 
        
7707
 
            this.animOut = new this.animClass(this.targetElement, 
7708
 
                this.attrOut.attributes, this.attrOut.duration, 
7709
 
                this.attrOut.method);
7710
 
 
7711
 
            this.animOut.onStart.subscribe(this.handleStartAnimateOut, this);
7712
 
            this.animOut.onTween.subscribe(this.handleTweenAnimateOut, this);
7713
 
            this.animOut.onComplete.subscribe(this.handleCompleteAnimateOut, 
7714
 
                this);
7715
 
 
7716
 
        },
7717
 
        
7718
 
        /**
7719
 
        * Triggers the in-animation.
7720
 
        * @method animateIn
7721
 
        */
7722
 
        animateIn: function () {
7723
 
            this.beforeAnimateInEvent.fire();
7724
 
            this.animIn.animate();
7725
 
        },
7726
 
        
7727
 
        /**
7728
 
        * Triggers the out-animation.
7729
 
        * @method animateOut
7730
 
        */
7731
 
        animateOut: function () {
7732
 
            this.beforeAnimateOutEvent.fire();
7733
 
            this.animOut.animate();
7734
 
        },
7735
 
        
7736
 
        /**
7737
 
        * The default onStart handler for the in-animation.
7738
 
        * @method handleStartAnimateIn
7739
 
        * @param {String} type The CustomEvent type
7740
 
        * @param {Object[]} args The CustomEvent arguments
7741
 
        * @param {Object} obj The scope object
7742
 
        */
7743
 
        handleStartAnimateIn: function (type, args, obj) { },
7744
 
    
7745
 
        /**
7746
 
        * The default onTween handler for the in-animation.
7747
 
        * @method handleTweenAnimateIn
7748
 
        * @param {String} type The CustomEvent type
7749
 
        * @param {Object[]} args The CustomEvent arguments
7750
 
        * @param {Object} obj The scope object
7751
 
        */
7752
 
        handleTweenAnimateIn: function (type, args, obj) { },
7753
 
    
7754
 
        /**
7755
 
        * The default onComplete handler for the in-animation.
7756
 
        * @method handleCompleteAnimateIn
7757
 
        * @param {String} type The CustomEvent type
7758
 
        * @param {Object[]} args The CustomEvent arguments
7759
 
        * @param {Object} obj The scope object
7760
 
        */
7761
 
        handleCompleteAnimateIn: function (type, args, obj) { },
7762
 
        
7763
 
        /**
7764
 
        * The default onStart handler for the out-animation.
7765
 
        * @method handleStartAnimateOut
7766
 
        * @param {String} type The CustomEvent type
7767
 
        * @param {Object[]} args The CustomEvent arguments
7768
 
        * @param {Object} obj The scope object
7769
 
        */
7770
 
        handleStartAnimateOut: function (type, args, obj) { },
7771
 
    
7772
 
        /**
7773
 
        * The default onTween handler for the out-animation.
7774
 
        * @method handleTweenAnimateOut
7775
 
        * @param {String} type The CustomEvent type
7776
 
        * @param {Object[]} args The CustomEvent arguments
7777
 
        * @param {Object} obj The scope object
7778
 
        */
7779
 
        handleTweenAnimateOut: function (type, args, obj) { },
7780
 
    
7781
 
        /**
7782
 
        * The default onComplete handler for the out-animation.
7783
 
        * @method handleCompleteAnimateOut
7784
 
        * @param {String} type The CustomEvent type
7785
 
        * @param {Object[]} args The CustomEvent arguments
7786
 
        * @param {Object} obj The scope object
7787
 
        */
7788
 
        handleCompleteAnimateOut: function (type, args, obj) { },
7789
 
        
7790
 
        /**
7791
 
        * Returns a string representation of the object.
7792
 
        * @method toString
7793
 
        * @return {String} The string representation of the ContainerEffect
7794
 
        */
7795
 
        toString: function () {
7796
 
            var output = "ContainerEffect";
7797
 
            if (this.overlay) {
7798
 
                output += " [" + this.overlay.toString() + "]";
7799
 
            }
7800
 
            return output;
7801
 
        }
7802
 
    
7803
 
    };
7804
 
 
7805
 
    YAHOO.lang.augmentProto(ContainerEffect, YAHOO.util.EventProvider);
7806
 
 
7807
 
})();
7808
 
 
7809
 
YAHOO.register("container", YAHOO.widget.Module, {version: "2.5.0", build: "895"});