/loggerhead/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/loggerhead/trunk

« back to all changes in this revision

Viewing changes to loggerhead/static/javascript/yui/build/loader/loader.js

  • Committer: Martin Albisetti
  • Date: 2008-10-20 21:18:06 UTC
  • mfrom: (229.1.3 add-yui-3)
  • Revision ID: martin.albisetti@canonical.com-20081020211806-rzs0ya40gz9wcpoz
Added yui library to the tree. Welcome to the future. (Paul Hummer)

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: 3.0.0pr1
 
6
*/
 
7
/**
 
8
 * Loader dynamically loads script and css files.  It includes the dependency
 
9
 * info for the version of the library in use, and will automatically pull in
 
10
 * dependencies for the modules requested.  It supports rollup files and will
 
11
 * automatically use these when appropriate in order to minimize the number of
 
12
 * http connections required to load all of the dependencies.  It can load the
 
13
 * files from the Yahoo! CDN, and it can utilize the combo service provided on
 
14
 * this network to reduce the number of http connections required to download 
 
15
 * YUI files.
 
16
 *
 
17
 * @module yui
 
18
 * @submodule loader
 
19
 */
 
20
 
 
21
/**
 
22
 * Loader dynamically loads script and css files.  It includes the dependency
 
23
 * info for the version of the library in use, and will automatically pull in
 
24
 * dependencies for the modules requested.  It supports rollup files and will
 
25
 * automatically use these when appropriate in order to minimize the number of
 
26
 * http connections required to load all of the dependencies.  It can load the
 
27
 * files from the Yahoo! CDN, and it can utilize the combo service provided on
 
28
 * this network to reduce the number of http connections required to download 
 
29
 * YUI files.
 
30
 * @class Loader
 
31
 * @constructor
 
32
 * @param o an optional set of configuration options.  Valid options:
 
33
 * <ul>
 
34
 *  <li>base:
 
35
 *  The base dir</li>
 
36
 *  <li>secureBase:
 
37
 *  The secure base dir (not implemented)</li>
 
38
 *  <li>comboBase:
 
39
 *  The YUI combo service base dir. Ex: http://yui.yahooapis.com/combo?</li>
 
40
 *  <li>root:
 
41
 *  The root path to prepend to module names for the combo service. Ex: 2.5.2/build/</li>
 
42
 *  <li>filter:
 
43
 *  
 
44
 * A filter to apply to result urls.  This filter will modify the default
 
45
 * path for all modules.  The default path for the YUI library is the
 
46
 * minified version of the files (e.g., event-min.js).  The filter property
 
47
 * can be a predefined filter or a custom filter.  The valid predefined 
 
48
 * filters are:
 
49
 * <dl>
 
50
 *  <dt>DEBUG</dt>
 
51
 *  <dd>Selects the debug versions of the library (e.g., event-debug.js).
 
52
 *      This option will automatically include the logger widget</dd>
 
53
 *  <dt>RAW</dt>
 
54
 *  <dd>Selects the non-minified version of the library (e.g., event.js).</dd>
 
55
 * </dl>
 
56
 * You can also define a custom filter, which must be an object literal 
 
57
 * containing a search expression and a replace string:
 
58
 * <pre>
 
59
 *  myFilter: &#123; 
 
60
 *      'searchExp': "-min\\.js", 
 
61
 *      'replaceStr': "-debug.js"
 
62
 *  &#125;
 
63
 * </pre>
 
64
 *
 
65
 *  </li>
 
66
 *  <li>combine:
 
67
 *  Use the YUI combo service to reduce the number of http connections required to load your dependencies</li>
 
68
 *  <li>ignore:
 
69
 *  A list of modules that should never be dynamically loaded</li>
 
70
 *  <li>force:
 
71
 *  A list of modules that should always be loaded when required, even if already present on the page</li>
 
72
 *  <li>insertBefore:
 
73
 *  Node or id for a node that should be used as the insertion point for new nodes</li>
 
74
 *  <li>charset:
 
75
 *  charset for dynamic nodes</li>
 
76
 *  <li>timeout:
 
77
 *  number of milliseconds before a timeout occurs when dynamically loading nodes.  in not set, there is no timeout</li>
 
78
 *  <li>context:
 
79
 *  execution context for all callbacks</li>
 
80
 *  <li>onSuccess:
 
81
 *  callback for the 'success' event</li>
 
82
 *  <li>onFailure:
 
83
 *  callback for the 'failure' event</li>
 
84
 *  <li>onTimeout:
 
85
 *  callback for the 'timeout' event</li>
 
86
 *  <li>onProgress:
 
87
 *  callback executed each time a script or css file is loaded</li>
 
88
 *  <li>modules:
 
89
 *  A list of module definitions.  See Loader.addModule for the supported module metadata</li>
 
90
 * </ul>
 
91
 */
 
92
 
 
93
// @TODO backed out the custom event changes so that the event system
 
94
// isn't required in the seed build.  If needed, we may want to 
 
95
// add them back if the event system is detected.
 
96
 
 
97
/*
 
98
 * Executed when the loader successfully completes an insert operation
 
99
 * This can be subscribed to normally, or a listener can be passed
 
100
 * as an onSuccess config option.
 
101
 * @event success
 
102
 */
 
103
 
 
104
/*
 
105
 * Executed when the loader fails to complete an insert operation.
 
106
 * This can be subscribed to normally, or a listener can be passed
 
107
 * as an onFailure config option.
 
108
 *
 
109
 * @event failure
 
110
 */
 
111
 
 
112
/*
 
113
 * Executed when a Get operation times out.
 
114
 * This can be subscribed to normally, or a listener can be passed
 
115
 * as an onTimeout config option.
 
116
 *
 
117
 * @event timeout
 
118
 */
 
119
 
 
120
// http://yui.yahooapis.com/combo?2.5.2/build/yahoo/yahoo-min.js&2.5.2/build/dom/dom-min.js&2.5.2/build/event/event-min.js&2.5.2/build/autocomplete/autocomplete-min.js"
 
121
 
 
122
YUI.add("loader", function(Y) {
 
123
 
 
124
var BASE = 'base', 
 
125
    CSS = 'css',
 
126
    JS = 'js',
 
127
    CSSRESET = 'cssreset',
 
128
    CSSFONTS = 'cssfonts',
 
129
    CSSGRIDS = 'cssgrids',
 
130
    CSSBASE = 'cssbase',
 
131
    CSS_AFTER = [CSSRESET, CSSFONTS, CSSGRIDS, 'cssreset-context', 'cssfonts-context', 'cssgrids-context'],
 
132
    YUI_CSS = ['reset', 'fonts', 'grids', 'base'],
 
133
    VERSION = '3.0.0pr1',
 
134
    ROOT = VERSION + '/build/',
 
135
    CONTEXT = '-context',
 
136
    META = {
 
137
 
 
138
    version: VERSION,
 
139
 
 
140
    root: ROOT,
 
141
 
 
142
    base: 'http://yui.yahooapis.com/' + ROOT,
 
143
 
 
144
    comboBase: 'http://yui.yahooapis.com/combo?',
 
145
 
 
146
    modules: {
 
147
 
 
148
       dom: {
 
149
            requires: ['event'],
 
150
            submodules: {
 
151
                'dom-base': {
 
152
                    requires: ['event']
 
153
                },
 
154
                'dom-style': {
 
155
                    requires: ['dom-base']
 
156
 
 
157
                },
 
158
                'dom-screen': {
 
159
                    requires: ['dom-base', 'dom-style']
 
160
                },
 
161
                selector: {
 
162
                    requires: ['dom-base']
 
163
                }
 
164
            }
 
165
        },
 
166
 
 
167
        node: {
 
168
            requires: ['dom'],
 
169
            submodules: {
 
170
                'node-base': {
 
171
                    requires: ['dom-base', 'selector']
 
172
                },
 
173
                'node-style': {
 
174
                    requires: ['dom-style', 'node-base']
 
175
                },
 
176
                'node-screen': {
 
177
                    requires: ['dom-screen', 'node-base']
 
178
                }
 
179
            }
 
180
        },
 
181
 
 
182
        anim: {
 
183
            requires: [BASE, 'node'],
 
184
            submodules: {
 
185
                'anim-base': {
 
186
                    requires: ['base', 'node-style']
 
187
                },
 
188
                'anim-color': {
 
189
                    requires: ['anim-base']
 
190
                },
 
191
                'anim-curve': {
 
192
                    requires: ['anim-xy']
 
193
                },
 
194
                'anim-easing': {
 
195
                },
 
196
                'anim-scroll': {
 
197
                    requires: ['anim-base']
 
198
                },
 
199
                'anim-xy': {
 
200
                    requires: ['anim-base', 'node-screen']
 
201
                },
 
202
                'anim-node-plugin': {
 
203
                     requires: ['node', 'anim-base']
 
204
                }
 
205
            }
 
206
        },
 
207
 
 
208
        attribute: { 
 
209
            requires: ['event']
 
210
        },
 
211
 
 
212
        base: {
 
213
            requires: ['attribute']
 
214
        },
 
215
        
 
216
        compat: { 
 
217
            requires: ['node']
 
218
        },
 
219
        
 
220
        cookie: { },
 
221
 
 
222
        // Note: CSS attributes are modified programmatically to reduce metadata size
 
223
        // cssbase: {
 
224
        //     after: CSS_AFTER
 
225
        // },
 
226
 
 
227
        // cssgrids: {
 
228
        //     requires: [CSSFONTS],
 
229
        //     optional: [CSSRESET]
 
230
        // },
 
231
 
 
232
        'dd':{
 
233
            submodules: {
 
234
                'dd-ddm-base': {
 
235
                    requires: ['node', BASE]
 
236
                }, 
 
237
                'dd-ddm':{
 
238
                    requires: ['dd-ddm-base']
 
239
                }, 
 
240
                'dd-ddm-drop':{
 
241
                    requires: ['dd-ddm']
 
242
                }, 
 
243
                'dd-drag':{
 
244
                    requires: ['dd-ddm-base']
 
245
                }, 
 
246
                'dd-drop':{
 
247
                    requires: ['dd-ddm-drop']
 
248
                }, 
 
249
                'dd-proxy':{
 
250
                    requires: ['dd-drag']
 
251
                }, 
 
252
                'dd-constrain':{
 
253
                    requires: ['dd-drag', 'dd-proxy']
 
254
                }, 
 
255
                'dd-plugin':{
 
256
                    requires: ['dd-drag'],
 
257
                    optional: ['dd-constrain', 'dd-proxy']
 
258
                },
 
259
                'dd-drop-plugin':{
 
260
                    requires: ['dd-drop']
 
261
                }
 
262
            }
 
263
        },
 
264
 
 
265
        dump: { },
 
266
 
 
267
        event: { 
 
268
            requires: ['oop']
 
269
        },
 
270
 
 
271
        get: { },
 
272
        
 
273
        io: { 
 
274
            requires: ['node']
 
275
        },
 
276
 
 
277
        json: {
 
278
            submodules: {
 
279
                'json-parse': {
 
280
                },
 
281
 
 
282
                'json-stringify': {
 
283
                }
 
284
            }
 
285
        },
 
286
 
 
287
        loader: { },
 
288
        
 
289
        oop: { 
 
290
            requires: ['yui-base']
 
291
        },
 
292
 
 
293
        queue: { },
 
294
 
 
295
        substitute: {
 
296
            optional: ['dump']
 
297
        },
 
298
 
 
299
        // Since YUI is required for everything else, it should not be specified as
 
300
        // a dependency.
 
301
        yui: {
 
302
            supersedes: ['yui-base', 'get', 'loader']
 
303
        },
 
304
 
 
305
        'yui-base': { }
 
306
    }
 
307
};
 
308
 
 
309
var _path = function(dir, file, type) {
 
310
    return dir + '/' + file + '-min.' + (type || CSS);
 
311
};
 
312
 
 
313
var _cssmeta = function() {
 
314
    var mods = META.modules;
 
315
    // modify the meta info for YUI CSS
 
316
    for (var i=0; i<YUI_CSS.length; i=i+1) {
 
317
        var bname = YUI_CSS[i],
 
318
            mname = CSS + bname;
 
319
 
 
320
        mods[mname] = {
 
321
            type: CSS,
 
322
            path: _path(mname, bname)
 
323
        };
 
324
 
 
325
        // define -context module
 
326
        var contextname = mname + CONTEXT;
 
327
        bname = bname + CONTEXT;
 
328
 
 
329
        mods[contextname] = {
 
330
            type: CSS,
 
331
            path: _path(mname, bname)
 
332
        };
 
333
 
 
334
        if (mname == CSSGRIDS) {
 
335
            mods[mname].requires = [CSSFONTS];
 
336
            mods[mname].optional = [CSSRESET];
 
337
            mods[contextname].requires = [CSSFONTS + CONTEXT];
 
338
            mods[contextname].optional = [CSSRESET + CONTEXT];
 
339
        } else if (mname == CSSBASE) {
 
340
            mods[mname].after = CSS_AFTER;
 
341
            mods[contextname].after = CSS_AFTER;
 
342
        }
 
343
    }
 
344
}();
 
345
 
 
346
Y.Env.meta = META;
 
347
 
 
348
 
 
349
    var L=Y.Lang, env=Y.Env,
 
350
        PROV = "_provides", SUPER = "_supersedes",
 
351
        REQ = "expanded";
 
352
 
 
353
    Y.Loader = function(o) {
 
354
 
 
355
        /**
 
356
         * Internal callback to handle multiple internal insert() calls
 
357
         * so that css is inserted prior to js
 
358
         * @property _internalCallback
 
359
         * @private
 
360
         */
 
361
        this._internalCallback = null;
 
362
 
 
363
        /**
 
364
         * Use the YUI environment listener to detect script load.  This
 
365
         * is only switched on for Safari 2.x and below.
 
366
         * @property _useYahooListener
 
367
         * @private
 
368
         */
 
369
        this._useYahooListener = false;
 
370
 
 
371
        /**
 
372
         * Callback that will be executed when the loader is finished
 
373
         * with an insert
 
374
         * @method onSuccess
 
375
         * @type function
 
376
         */
 
377
        this.onSuccess = null;
 
378
 
 
379
        /**
 
380
         * Callback that will be executed if there is a failure
 
381
         * @method onFailure
 
382
         * @type function
 
383
         */
 
384
        this.onFailure = null;
 
385
 
 
386
        /**
 
387
         * Callback executed each time a script or css file is loaded
 
388
         * @method onProgress
 
389
         * @type function
 
390
         */
 
391
        this.onProgress = null;
 
392
 
 
393
        /**
 
394
         * Callback that will be executed if a timeout occurs
 
395
         * @method onTimeout
 
396
         * @type function
 
397
         */
 
398
        this.onTimeout = null;
 
399
 
 
400
        /**
 
401
         * The execution context for all callbacks
 
402
         * @property context
 
403
         * @default {YUI} the YUI instance
 
404
         */
 
405
        this.context = Y;
 
406
 
 
407
        /**
 
408
         * Data that is passed to all callbacks
 
409
         * @property data
 
410
         */
 
411
        this.data = null;
 
412
 
 
413
        /**
 
414
         * Node reference or id where new nodes should be inserted before
 
415
         * @property insertBefore
 
416
         * @type string|HTMLElement
 
417
         */
 
418
        this.insertBefore = null;
 
419
 
 
420
        /**
 
421
         * The charset attribute for inserted nodes
 
422
         * @property charset
 
423
         * @type string
 
424
         * @default utf-8
 
425
         */
 
426
        this.charset = null;
 
427
 
 
428
        /**
 
429
         * The base directory.
 
430
         * @property base
 
431
         * @type string
 
432
         * @default http://yui.yahooapis.com/[YUI VERSION]/build/
 
433
         */
 
434
        this.base = Y.Env.meta.base;
 
435
 
 
436
        /**
 
437
         * Base path for the combo service
 
438
         * @property comboBase
 
439
         * @type string
 
440
         * @default http://yui.yahooapis.com/combo?
 
441
         */
 
442
        this.comboBase = Y.Env.meta.comboBase;
 
443
 
 
444
        /**
 
445
         * If configured, YUI JS resources will use the combo
 
446
         * handler
 
447
         * @property combine
 
448
         * @type boolean
 
449
         * @default true if a base dir isn't in the config
 
450
         */
 
451
        this.combine = (!(BASE in o));
 
452
 
 
453
        /**
 
454
         * Ignore modules registered on the YUI global
 
455
         * @property ignoreRegistered
 
456
         * @default false
 
457
         */
 
458
        this.ignoreRegistered = false;
 
459
 
 
460
        /**
 
461
         * Root path to prepend to module path for the combo
 
462
         * service
 
463
         * @property root
 
464
         * @type string
 
465
         * @default [YUI VERSION]/build/
 
466
         */
 
467
        this.root = Y.Env.meta.root;
 
468
 
 
469
        /**
 
470
         * Timeout value in milliseconds.  If set, this value will be used by
 
471
         * the get utility.  the timeout event will fire if
 
472
         * a timeout occurs.
 
473
         * @property timeout
 
474
         * @type int
 
475
         */
 
476
        this.timeout = 0;
 
477
 
 
478
        /**
 
479
         * A list of modules that should not be loaded, even if
 
480
         * they turn up in the dependency tree
 
481
         * @property ignore
 
482
         * @type string[]
 
483
         */
 
484
        this.ignore = null;
 
485
 
 
486
        /**
 
487
         * A list of modules that should always be loaded, even
 
488
         * if they have already been inserted into the page.
 
489
         * @property force
 
490
         * @type string[]
 
491
         */
 
492
        this.force = null;
 
493
 
 
494
        /**
 
495
         * Should we allow rollups
 
496
         * @property allowRollup
 
497
         * @type boolean
 
498
         * @default true
 
499
         */
 
500
        this.allowRollup = true;
 
501
 
 
502
        /**
 
503
         * A filter to apply to result urls.  This filter will modify the default
 
504
         * path for all modules.  The default path for the YUI library is the
 
505
         * minified version of the files (e.g., event-min.js).  The filter property
 
506
         * can be a predefined filter or a custom filter.  The valid predefined 
 
507
         * filters are:
 
508
         * <dl>
 
509
         *  <dt>DEBUG</dt>
 
510
         *  <dd>Selects the debug versions of the library (e.g., event-debug.js).
 
511
         *      This option will automatically include the logger widget</dd>
 
512
         *  <dt>RAW</dt>
 
513
         *  <dd>Selects the non-minified version of the library (e.g., event.js).</dd>
 
514
         * </dl>
 
515
         * You can also define a custom filter, which must be an object literal 
 
516
         * containing a search expression and a replace string:
 
517
         * <pre>
 
518
         *  myFilter: &#123; 
 
519
         *      'searchExp': "-min\\.js", 
 
520
         *      'replaceStr': "-debug.js"
 
521
         *  &#125;
 
522
         * </pre>
 
523
         * @property filter
 
524
         * @type string|{searchExp: string, replaceStr: string}
 
525
         */
 
526
        this.filter = null;
 
527
 
 
528
        /**
 
529
         * The list of requested modules
 
530
         * @property required
 
531
         * @type {string: boolean}
 
532
         */
 
533
        this.required = {};
 
534
 
 
535
        /**
 
536
         * The library metadata
 
537
         * @property moduleInfo
 
538
         */
 
539
        // this.moduleInfo = Y.merge(Y.Env.meta.moduleInfo);
 
540
        this.moduleInfo = {};
 
541
        
 
542
        var defaults = Y.Env.meta.modules;
 
543
 
 
544
        for (var i in defaults) {
 
545
            if (defaults.hasOwnProperty(i)) {
 
546
                this._internal = true;
 
547
                this.addModule(defaults[i], i);
 
548
                this._internal = false;
 
549
            }
 
550
        }
 
551
 
 
552
        /**
 
553
         * List of rollup files found in the library metadata
 
554
         * @property rollups
 
555
         */
 
556
        this.rollups = null;
 
557
 
 
558
        /**
 
559
         * Whether or not to load optional dependencies for 
 
560
         * the requested modules
 
561
         * @property loadOptional
 
562
         * @type boolean
 
563
         * @default false
 
564
         */
 
565
        this.loadOptional = false;
 
566
 
 
567
        /**
 
568
         * All of the derived dependencies in sorted order, which
 
569
         * will be populated when either calculate() or insert()
 
570
         * is called
 
571
         * @property sorted
 
572
         * @type string[]
 
573
         */
 
574
        this.sorted = [];
 
575
 
 
576
        /**
 
577
         * Set when beginning to compute the dependency tree. 
 
578
         * Composed of what YUI reports to be loaded combined
 
579
         * with what has been loaded by the tool
 
580
         * @propery loaded
 
581
         * @type {string: boolean}
 
582
         */
 
583
        this.loaded = {};
 
584
 
 
585
        /**
 
586
         * A list of modules to attach to the YUI instance when complete.
 
587
         * If not supplied, the sorted list of dependencies are applied.
 
588
         * @property attaching
 
589
         */
 
590
        this.attaching = null;
 
591
 
 
592
        /**
 
593
         * Flag to indicate the dependency tree needs to be recomputed
 
594
         * if insert is called again.
 
595
         * @property dirty
 
596
         * @type boolean
 
597
         * @default true
 
598
         */
 
599
        this.dirty = true;
 
600
 
 
601
        /**
 
602
         * List of modules inserted by the utility
 
603
         * @property inserted
 
604
         * @type {string: boolean}
 
605
         */
 
606
        this.inserted = {};
 
607
 
 
608
        this.skipped = {};
 
609
 
 
610
        // Y.on('yui:load', this.loadNext, this);
 
611
 
 
612
        this._config(o);
 
613
 
 
614
    };
 
615
 
 
616
    Y.Loader.prototype = {
 
617
 
 
618
        FILTERS: {
 
619
            RAW: { 
 
620
                'searchExp': "-min\\.js", 
 
621
                'replaceStr': ".js"
 
622
            },
 
623
            DEBUG: { 
 
624
                'searchExp': "-min\\.js", 
 
625
                'replaceStr': "-debug.js"
 
626
            }
 
627
        },
 
628
 
 
629
        _config: function(o) {
 
630
 
 
631
            // apply config values
 
632
            if (o) {
 
633
                for (var i in o) {
 
634
                    var val = o[i];
 
635
                    if (o.hasOwnProperty(i)) {
 
636
                        if (i == 'require') {
 
637
                            this.require(val);
 
638
                        // support the old callback syntax
 
639
                        // } else if (i.indexOf('on') === 0) {
 
640
                            // this.subscribe(i.substr(2).toLowerCase(), o[i], o.context || this);
 
641
                        } else if (i == 'modules') {
 
642
                            // add a hash of module definitions
 
643
                            for (var j in val) {
 
644
                                this.addModule(val[j], j);
 
645
                            }
 
646
                        } else {
 
647
                            this[i] = val;
 
648
                        }
 
649
                    }
 
650
                }
 
651
            }
 
652
 
 
653
            // fix filter
 
654
            var f = this.filter;
 
655
 
 
656
            if (L.isString(f)) {
 
657
 
 
658
                f = f.toUpperCase();
 
659
 
 
660
                this.filterName = f;
 
661
 
 
662
                // the logger must be available in order to use the debug
 
663
                // versions of the library
 
664
                // @TODO review when logreader is available
 
665
                // if (f === "DEBUG") {
 
666
                //     this.require("log");
 
667
                // }
 
668
 
 
669
                this.filter = this.FILTERS[f];
 
670
            }
 
671
 
 
672
        },
 
673
 
 
674
        /** Add a new module to the component metadata.         
 
675
         * <dl>
 
676
         *     <dt>name:</dt>       <dd>required, the component name</dd>
 
677
         *     <dt>type:</dt>       <dd>required, the component type (js or css)</dd>
 
678
         *     <dt>path:</dt>       <dd>required, the path to the script from "base"</dd>
 
679
         *     <dt>requires:</dt>   <dd>array of modules required by this component</dd>
 
680
         *     <dt>optional:</dt>   <dd>array of optional modules for this component</dd>
 
681
         *     <dt>supersedes:</dt> <dd>array of the modules this component replaces</dd>
 
682
         *     <dt>after:</dt>      <dd>array of modules the components which, if present, should be sorted above this one</dd>
 
683
         *     <dt>rollup:</dt>     <dd>the number of superseded modules required for automatic rollup</dd>
 
684
         *     <dt>fullpath:</dt>   <dd>If fullpath is specified, this is used instead of the configured base + path</dd>
 
685
         *     <dt>skinnable:</dt>  <dd>flag to determine if skin assets should automatically be pulled in</dd>
 
686
         *     <dt>submodules:</dt> <dd>a has of submodules</dd>
 
687
         * </dl>
 
688
         * @method addModule
 
689
         * @param o An object containing the module data
 
690
         * @param name the module name (optional), required if not in the module data
 
691
         * @return {boolean} true if the module was added, false if 
 
692
         * the object passed in did not provide all required attributes
 
693
         */
 
694
        addModule: function(o, name) {
 
695
 
 
696
            name = name || o.name;
 
697
            o.name = name;
 
698
 
 
699
            if (!o || !o.name) {
 
700
                return false;
 
701
            }
 
702
 
 
703
            if (!o.type) {
 
704
                o.type = JS;
 
705
            }
 
706
 
 
707
            if (!o.path && !o.fullpath) {
 
708
                // o.path = name + "/" + name + "-min." + o.type;
 
709
                o.path = _path(name, name, o.type);
 
710
            }
 
711
 
 
712
            o.ext = ('ext' in o) ? o.ext : (this._internal) ? false : true;
 
713
            o.requires = o.requires || [];
 
714
 
 
715
 
 
716
            // Handle submodule logic
 
717
            var subs = o.submodules;
 
718
            if (subs) {
 
719
                var sup = [], l=0;
 
720
 
 
721
                for (var i in subs) {
 
722
                    var s = subs[i];
 
723
                    s.path = _path(name, i, o.type);
 
724
                    this.addModule(s, i);
 
725
                    sup.push(i);
 
726
                    l++;
 
727
                }
 
728
 
 
729
                o.supersedes = sup;
 
730
                o.rollup = Math.min(l-1, 4);
 
731
            }
 
732
 
 
733
            this.moduleInfo[name] = o;
 
734
            this.dirty = true;
 
735
 
 
736
            return o;
 
737
        },
 
738
 
 
739
        /**
 
740
         * Add a requirement for one or more module
 
741
         * @method require
 
742
         * @param what {string[] | string*} the modules to load
 
743
         */
 
744
        require: function(what) {
 
745
            var a = (typeof what === "string") ? arguments : what;
 
746
            this.dirty = true;
 
747
            Y.mix(this.required, Y.Array.hash(a));
 
748
        },
 
749
 
 
750
        /**
 
751
         * Returns an object containing properties for all modules required
 
752
         * in order to load the requested module
 
753
         * @method getRequires
 
754
         * @param mod The module definition from moduleInfo
 
755
         */
 
756
        getRequires: function(mod) {
 
757
 
 
758
            if (!mod) {
 
759
                return [];
 
760
            }
 
761
 
 
762
            if (!this.dirty && mod.expanded) {
 
763
                return mod.expanded;
 
764
            }
 
765
 
 
766
            var i, d=[], r=mod.requires, o=mod.optional, 
 
767
                info=this.moduleInfo, m, j, add;
 
768
 
 
769
            for (i=0; i<r.length; i=i+1) {
 
770
                d.push(r[i]);
 
771
                m = this.getModule(r[i]);
 
772
                add = this.getRequires(m);
 
773
                for (j=0;j<add.length;j=j+1) {
 
774
                    d.push(add[j]);
 
775
                }
 
776
            }
 
777
 
 
778
            // get the requirements from superseded modules, if any
 
779
            r=mod.supersedes;
 
780
            if (r) {
 
781
                for (i=0; i<r.length; i=i+1) {
 
782
                    d.push(r[i]);
 
783
                    m = this.getModule(r[i]);
 
784
                    add = this.getRequires(m);
 
785
                    for (j=0;j<add.length;j=j+1) {
 
786
                        d.push(add[j]);
 
787
                    }
 
788
                }
 
789
            }
 
790
 
 
791
            if (o && this.loadOptional) {
 
792
                for (i=0; i<o.length; i=i+1) {
 
793
                    d.push(o[i]);
 
794
                    add = this.getRequires(info[o[i]]);
 
795
                    for (j=0;j<add.length;j=j+1) {
 
796
                        d.push(add[j]);
 
797
                    }
 
798
                }
 
799
            }
 
800
 
 
801
            mod.expanded = Y.Object.keys(Y.Array.hash(d));
 
802
 
 
803
 
 
804
            return mod.expanded;
 
805
        },
 
806
 
 
807
 
 
808
        /**
 
809
         * Returns an object literal of the modules the supplied module satisfies
 
810
         * @method getProvides
 
811
         * @param name{string} The name of the module
 
812
         * @param notMe {string} don't add this module name, only include superseded modules
 
813
         * @return what this module provides
 
814
         */
 
815
        getProvides: function(name, notMe) {
 
816
            var addMe = !(notMe), ckey = (addMe) ? PROV : SUPER,
 
817
                m = this.getModule(name), o = {};
 
818
 
 
819
            if (!m) {
 
820
                return o;
 
821
            }
 
822
 
 
823
            if (m[ckey]) {
 
824
                return m[ckey];
 
825
            }
 
826
 
 
827
            var s = m.supersedes, done={}, me = this;
 
828
 
 
829
            // use worker to break cycles
 
830
            var add = function(mm) {
 
831
                if (!done[mm]) {
 
832
                    done[mm] = true;
 
833
                    // we always want the return value normal behavior 
 
834
                    // (provides) for superseded modules.
 
835
                    Y.mix(o, me.getProvides(mm));
 
836
                } 
 
837
                
 
838
                // else {
 
839
                // }
 
840
            };
 
841
 
 
842
            // calculate superseded modules
 
843
            if (s) {
 
844
                for (var i=0; i<s.length; i=i+1) {
 
845
                    add(s[i]);
 
846
                }
 
847
            }
 
848
 
 
849
            // supersedes cache
 
850
            m[SUPER] = o;
 
851
            // provides cache
 
852
            m[PROV] = Y.merge(o);
 
853
            m[PROV][name] = true;
 
854
 
 
855
 
 
856
            return m[ckey];
 
857
        },
 
858
 
 
859
 
 
860
        /**
 
861
         * Calculates the dependency tree, the result is stored in the sorted 
 
862
         * property
 
863
         * @method calculate
 
864
         * @param o optional options object
 
865
         */
 
866
        calculate: function(o) {
 
867
            if (o || this.dirty) {
 
868
                this._config(o);
 
869
                this._setup();
 
870
                this._explode();
 
871
                if (this.allowRollup) {
 
872
                    this._rollup();
 
873
                }
 
874
                this._reduce();
 
875
                this._sort();
 
876
 
 
877
 
 
878
                this.dirty = false;
 
879
            }
 
880
        },
 
881
 
 
882
        /**
 
883
         * Investigates the current YUI configuration on the page.  By default,
 
884
         * modules already detected will not be loaded again unless a force
 
885
         * option is encountered.  Called by calculate()
 
886
         * @method _setup
 
887
         * @private
 
888
         */
 
889
        _setup: function() {
 
890
 
 
891
            var info = this.moduleInfo, name, i, j;
 
892
 
 
893
            var l = Y.merge(this.inserted); // shallow clone
 
894
 
 
895
            // available modules
 
896
            if (!this.ignoreRegistered) {
 
897
                Y.mix(l, YUI.Env.mods);
 
898
            }
 
899
            
 
900
 
 
901
            // add the ignore list to the list of loaded packages
 
902
            if (this.ignore) {
 
903
                // OU.appendArray(l, this.ignore);
 
904
                Y.mix(l, Y.Array.hash(this.ignore));
 
905
            }
 
906
 
 
907
            // expand the list to include superseded modules
 
908
            for (j in l) {
 
909
                if (l.hasOwnProperty(j)) {
 
910
                    Y.mix(l, this.getProvides(j));
 
911
                }
 
912
            }
 
913
 
 
914
            // remove modules on the force list from the loaded list
 
915
            if (this.force) {
 
916
                for (i=0; i<this.force.length; i=i+1) {
 
917
                    if (this.force[i] in l) {
 
918
                        delete l[this.force[i]];
 
919
                    }
 
920
                }
 
921
            }
 
922
 
 
923
 
 
924
            this.loaded = l;
 
925
 
 
926
        },
 
927
        
 
928
 
 
929
        /**
 
930
         * Inspects the required modules list looking for additional 
 
931
         * dependencies.  Expands the required list to include all 
 
932
         * required modules.  Called by calculate()
 
933
         * @method _explode
 
934
         * @private
 
935
         */
 
936
        _explode: function() {
 
937
 
 
938
            var r=this.required, i, mod;
 
939
 
 
940
            for (i in r) {
 
941
                if (r.hasOwnProperty(i)) {
 
942
                    mod = this.getModule(i);
 
943
 
 
944
                    var req = this.getRequires(mod);
 
945
 
 
946
                    if (req) {
 
947
                        Y.mix(r, Y.Array.hash(req));
 
948
                    }
 
949
                }
 
950
            }
 
951
        },
 
952
 
 
953
        getModule: function(name) {
 
954
 
 
955
            var m = this.moduleInfo[name];
 
956
 
 
957
            // create the default module
 
958
            // if (!m) {
 
959
                // m = this.addModule({ext: false}, name);
 
960
            // }
 
961
 
 
962
            return m;
 
963
        },
 
964
 
 
965
        /**
 
966
         * Look for rollup packages to determine if all of the modules a
 
967
         * rollup supersedes are required.  If so, include the rollup to
 
968
         * help reduce the total number of connections required.  Called
 
969
         * by calculate()
 
970
         * @method _rollup
 
971
         * @private
 
972
         */
 
973
        _rollup: function() {
 
974
            var i, j, m, s, rollups={}, r=this.required, roll,
 
975
                info = this.moduleInfo;
 
976
 
 
977
            // find and cache rollup modules
 
978
            if (this.dirty || !this.rollups) {
 
979
                for (i in info) {
 
980
                    if (info.hasOwnProperty(i)) {
 
981
                        m = this.getModule(i);
 
982
                        // if (m && m.rollup && m.supersedes) {
 
983
                        if (m && m.rollup) {
 
984
                            rollups[i] = m;
 
985
                        }
 
986
                    }
 
987
                }
 
988
 
 
989
                this.rollups = rollups;
 
990
            }
 
991
 
 
992
            // make as many passes as needed to pick up rollup rollups
 
993
            for (;;) {
 
994
                var rolled = false;
 
995
 
 
996
                // go through the rollup candidates
 
997
                for (i in rollups) { 
 
998
 
 
999
                    // there can be only one
 
1000
                    if (!r[i] && !this.loaded[i]) {
 
1001
                        m =this.getModule(i); s = m.supersedes ||[]; roll=false;
 
1002
 
 
1003
                        if (!m.rollup) {
 
1004
                            continue;
 
1005
                        }
 
1006
 
 
1007
                        var c=0;
 
1008
 
 
1009
                        // check the threshold
 
1010
                        for (j=0;j<s.length;j=j+1) {
 
1011
 
 
1012
                            // if the superseded module is loaded, we can't load the rollup
 
1013
                            // if (this.loaded[s[j]] && (!_Y.dupsAllowed[s[j]])) {
 
1014
                            if (this.loaded[s[j]]) {
 
1015
                                roll = false;
 
1016
                                break;
 
1017
                            // increment the counter if this module is required.  if we are
 
1018
                            // beyond the rollup threshold, we will use the rollup module
 
1019
                            } else if (r[s[j]]) {
 
1020
                                c++;
 
1021
                                roll = (c >= m.rollup);
 
1022
                                if (roll) {
 
1023
                                    break;
 
1024
                                }
 
1025
                            }
 
1026
                        }
 
1027
 
 
1028
                        if (roll) {
 
1029
                            // add the rollup
 
1030
                            r[i] = true;
 
1031
                            rolled = true;
 
1032
 
 
1033
                            // expand the rollup's dependencies
 
1034
                            this.getRequires(m);
 
1035
                        }
 
1036
                    }
 
1037
                }
 
1038
 
 
1039
                // if we made it here w/o rolling up something, we are done
 
1040
                if (!rolled) {
 
1041
                    break;
 
1042
                }
 
1043
            }
 
1044
        },
 
1045
 
 
1046
        /**
 
1047
         * Remove superceded modules and loaded modules.  Called by
 
1048
         * calculate() after we have the mega list of all dependencies
 
1049
         * @method _reduce
 
1050
         * @private
 
1051
         */
 
1052
        _reduce: function() {
 
1053
 
 
1054
            var i, j, s, m, r=this.required;
 
1055
            for (i in r) {
 
1056
 
 
1057
                // remove if already loaded
 
1058
                if (i in this.loaded) { 
 
1059
                    delete r[i];
 
1060
 
 
1061
                // remove anything this module supersedes
 
1062
                } else {
 
1063
 
 
1064
                     m = this.getModule(i);
 
1065
                     s = m && m.supersedes;
 
1066
                     if (s) {
 
1067
                         for (j=0; j<s.length; j=j+1) {
 
1068
                             if (s[j] in r) {
 
1069
                                 delete r[s[j]];
 
1070
                             }
 
1071
                         }
 
1072
                     }
 
1073
                }
 
1074
            }
 
1075
        },
 
1076
 
 
1077
        _attach: function() {
 
1078
 
 
1079
            // this is the full list of items the YUI needs attached,
 
1080
            // which is needed if some dependencies are already on
 
1081
            // the page without their dependencies.
 
1082
            if (this.attaching) {
 
1083
                Y._attach(this.attaching);
 
1084
            } else {
 
1085
                Y._attach(this.sorted);
 
1086
            }
 
1087
 
 
1088
            this._pushEvents();
 
1089
 
 
1090
        },
 
1091
 
 
1092
        _onSuccess: function() {
 
1093
 
 
1094
            this._attach();
 
1095
 
 
1096
            for (var i in this.skipped) {
 
1097
                delete this.inserted[i];
 
1098
            }
 
1099
 
 
1100
            this.skipped = {};
 
1101
 
 
1102
            // this.fire('success', {
 
1103
            //     data: this.data
 
1104
            // });
 
1105
 
 
1106
            var f = this.onSuccess;
 
1107
            if (f) {
 
1108
                f.call(this.context, {
 
1109
                    msg: 'success',
 
1110
                    data: this.data,
 
1111
                    success: true
 
1112
                });
 
1113
            }
 
1114
 
 
1115
        },
 
1116
 
 
1117
        _onFailure: function(msg) {
 
1118
            this._attach();
 
1119
            // this.fire('failure', {
 
1120
            //     msg: 'operation failed: ' + msg,
 
1121
            //     data: this.data
 
1122
            // });
 
1123
 
 
1124
            var f = this.onFailure;
 
1125
            if (f) {
 
1126
                f.call(this.context, {
 
1127
                    msg: 'failure: ' + msg,
 
1128
                    data: this.data,
 
1129
                    success: false
 
1130
                });
 
1131
            }
 
1132
        },
 
1133
 
 
1134
        _onTimeout: function() {
 
1135
            this._attach();
 
1136
 
 
1137
            // this.fire('timeout', {
 
1138
            //     data: this.data
 
1139
            // });
 
1140
 
 
1141
            var f = this.onTimeout;
 
1142
            if (f) {
 
1143
                f.call(this.context, {
 
1144
                    msg: 'timeout',
 
1145
                    data: this.data,
 
1146
                    success: false
 
1147
                });
 
1148
            }
 
1149
        },
 
1150
        
 
1151
        /**
 
1152
         * Sorts the dependency tree.  The last step of calculate()
 
1153
         * @method _sort
 
1154
         * @private
 
1155
         */
 
1156
        _sort: function() {
 
1157
            // create an indexed list
 
1158
            var s=Y.Object.keys(this.required), info=this.moduleInfo, loaded=this.loaded,
 
1159
                me = this;
 
1160
 
 
1161
            // returns true if b is not loaded, and is required
 
1162
            // directly or by means of modules it supersedes.
 
1163
            var requires = function(aa, bb) {
 
1164
 
 
1165
                var mm=info[aa];
 
1166
 
 
1167
                if (loaded[bb] || !mm) {
 
1168
                    return false;
 
1169
                }
 
1170
 
 
1171
                var ii, rr = mm.expanded, 
 
1172
                    after = mm.after, other=info[bb];
 
1173
 
 
1174
                // check if this module requires the other directly
 
1175
                if (rr && Y.Array.indexOf(rr, bb) > -1) {
 
1176
                    return true;
 
1177
                }
 
1178
 
 
1179
                // check if this module should be sorted after the other
 
1180
                if (after && Y.Array.indexOf(after, bb) > -1) {
 
1181
                    return true;
 
1182
                }
 
1183
 
 
1184
                // check if this module requires one the other supersedes
 
1185
                var ss=info[bb] && info[bb].supersedes;
 
1186
                if (ss) {
 
1187
                    for (ii=0; ii<ss.length; ii=ii+1) {
 
1188
                        if (requires(aa, ss[ii])) {
 
1189
                            return true;
 
1190
                        }
 
1191
                    }
 
1192
                }
 
1193
 
 
1194
                // external css files should be sorted below yui css
 
1195
                if (mm.ext && mm.type == CSS && (!other.ext)) {
 
1196
                    return true;
 
1197
                }
 
1198
 
 
1199
                return false;
 
1200
            };
 
1201
 
 
1202
            // pointer to the first unsorted item
 
1203
            var p=0; 
 
1204
 
 
1205
            // keep going until we make a pass without moving anything
 
1206
            for (;;) {
 
1207
               
 
1208
                var l=s.length, a, b, j, k, moved=false;
 
1209
 
 
1210
                // start the loop after items that are already sorted
 
1211
                for (j=p; j<l; j=j+1) {
 
1212
 
 
1213
                    // check the next module on the list to see if its
 
1214
                    // dependencies have been met
 
1215
                    a = s[j];
 
1216
 
 
1217
                    // check everything below current item and move if we
 
1218
                    // find a requirement for the current item
 
1219
                    for (k=j+1; k<l; k=k+1) {
 
1220
                        if (requires(a, s[k])) {
 
1221
 
 
1222
                            // extract the dependency so we can move it up
 
1223
                            b = s.splice(k, 1);
 
1224
 
 
1225
                            // insert the dependency above the item that 
 
1226
                            // requires it
 
1227
                            s.splice(j, 0, b[0]);
 
1228
 
 
1229
                            moved = true;
 
1230
                            break;
 
1231
                        }
 
1232
                    }
 
1233
 
 
1234
                    // jump out of loop if we moved something
 
1235
                    if (moved) {
 
1236
                        break;
 
1237
                    // this item is sorted, move our pointer and keep going
 
1238
                    } else {
 
1239
                        p = p + 1;
 
1240
                    }
 
1241
                }
 
1242
 
 
1243
                // when we make it here and moved is false, we are 
 
1244
                // finished sorting
 
1245
                if (!moved) {
 
1246
                    break;
 
1247
                }
 
1248
 
 
1249
            }
 
1250
 
 
1251
            this.sorted = s;
 
1252
        },
 
1253
 
 
1254
        /**
 
1255
         * inserts the requested modules and their dependencies.  
 
1256
         * <code>type</code> can be "js" or "css".  Both script and 
 
1257
         * css are inserted if type is not provided.
 
1258
         * @method insert
 
1259
         * @param o optional options object
 
1260
         * @param type {string} the type of dependency to insert
 
1261
         */
 
1262
        insert: function(o, type) {
 
1263
 
 
1264
 
 
1265
            // build the dependency list
 
1266
            this.calculate(o);
 
1267
 
 
1268
            if (!type) {
 
1269
                var self = this;
 
1270
                this._internalCallback = function() {
 
1271
                            self._internalCallback = null;
 
1272
                            self.insert(null, JS);
 
1273
                        };
 
1274
                this.insert(null, CSS);
 
1275
                return;
 
1276
            }
 
1277
 
 
1278
            // set a flag to indicate the load has started
 
1279
            this._loading = true;
 
1280
 
 
1281
            // flag to indicate we are done with the combo service
 
1282
            // and any additional files will need to be loaded
 
1283
            // individually
 
1284
            this._combineComplete = false;
 
1285
 
 
1286
            // keep the loadType (js, css or undefined) cached
 
1287
            this.loadType = type;
 
1288
 
 
1289
            // start the load
 
1290
            this.loadNext();
 
1291
 
 
1292
        },
 
1293
 
 
1294
        /**
 
1295
         * Executed every time a module is loaded, and if we are in a load
 
1296
         * cycle, we attempt to load the next script.  Public so that it
 
1297
         * is possible to call this if using a method other than
 
1298
         * Y.register to determine when scripts are fully loaded
 
1299
         * @method loadNext
 
1300
         * @param mname {string} optional the name of the module that has
 
1301
         * been loaded (which is usually why it is time to load the next
 
1302
         * one)
 
1303
         */
 
1304
        loadNext: function(mname) {
 
1305
 
 
1306
            // It is possible that this function is executed due to something
 
1307
            // else one the page loading a YUI module.  Only react when we
 
1308
            // are actively loading something
 
1309
            if (!this._loading) {
 
1310
                return;
 
1311
            }
 
1312
 
 
1313
            var s, len, i, m, url, self=this;
 
1314
 
 
1315
            // @TODO this will need to handle the two phase insert when
 
1316
            // CSS support is added
 
1317
            if (this.loadType !== CSS && this.combine && (!this._combineComplete)) {
 
1318
 
 
1319
                this._combining = []; 
 
1320
                s=this.sorted;
 
1321
                len=s.length;
 
1322
                url=this.comboBase;
 
1323
 
 
1324
                for (i=0; i<len; i=i+1) {
 
1325
                    m = this.getModule(s[i]);
 
1326
// @TODO we can't combine CSS yet until we deliver files with absolute paths to the assets
 
1327
                    // Do not try to combine non-yui JS
 
1328
                    if (m.type == JS && !m.ext) {
 
1329
                        url += this.root + m.path;
 
1330
                        if (i < len-1) {
 
1331
                            url += '&';
 
1332
                        }
 
1333
 
 
1334
                        this._combining.push(s[i]);
 
1335
                    }
 
1336
                }
 
1337
 
 
1338
                if (this._combining.length) {
 
1339
 
 
1340
 
 
1341
                    var callback=function(o) {
 
1342
                        this._combineComplete = true;
 
1343
 
 
1344
 
 
1345
                        var c=this._combining, len=c.length, i, m;
 
1346
                        for (i=0; i<len; i=i+1) {
 
1347
                            this.inserted[c[i]] = true;
 
1348
                        }
 
1349
 
 
1350
                        this.loadNext(o.data);
 
1351
                    };
 
1352
 
 
1353
                    // @TODO get rid of the redundant Get code
 
1354
                    Y.Get.script(url, {
 
1355
                        data: this._loading,
 
1356
                        onSuccess: callback,
 
1357
                        onFailure: this._onFailure,
 
1358
                        onTimeout: this._onTimeout,
 
1359
                        insertBefore: this.insertBefore,
 
1360
                        charset: this.charset,
 
1361
                        timeout: this.timeout,
 
1362
                        context: self 
 
1363
                    });
 
1364
 
 
1365
                    return;
 
1366
 
 
1367
                } else {
 
1368
                    this._combineComplete = true;
 
1369
                }
 
1370
            }
 
1371
 
 
1372
            if (mname) {
 
1373
 
 
1374
                // if the module that was just loaded isn't what we were expecting,
 
1375
                // continue to wait
 
1376
                if (mname !== this._loading) {
 
1377
                    return;
 
1378
                }
 
1379
 
 
1380
 
 
1381
                // The global handler that is called when each module is loaded
 
1382
                // will pass that module name to this function.  Storing this
 
1383
                // data to avoid loading the same module multiple times
 
1384
                this.inserted[mname] = true;
 
1385
 
 
1386
                // this.fire('progress', {
 
1387
                //     name: mname,
 
1388
                //     data: this.data
 
1389
                // });
 
1390
                if (this.onProgress) {
 
1391
                    this.onProgress.call(this.context, {
 
1392
                            name: mname,
 
1393
                            data: this.data
 
1394
                        });
 
1395
                }
 
1396
 
 
1397
 
 
1398
            }
 
1399
 
 
1400
            s=this.sorted;
 
1401
            len=s.length;
 
1402
 
 
1403
            for (i=0; i<len; i=i+1) {
 
1404
 
 
1405
                // this.inserted keeps track of what the loader has loaded.
 
1406
                // move on if this item is done.
 
1407
                if (s[i] in this.inserted) {
 
1408
                    continue;
 
1409
                }
 
1410
 
 
1411
                // Because rollups will cause multiple load notifications
 
1412
                // from Y, loadNext may be called multiple times for
 
1413
                // the same module when loading a rollup.  We can safely
 
1414
                // skip the subsequent requests
 
1415
                if (s[i] === this._loading) {
 
1416
                    return;
 
1417
                }
 
1418
 
 
1419
                // log("inserting " + s[i]);
 
1420
                m = this.getModule(s[i]);
 
1421
 
 
1422
                if (!m) {
 
1423
 
 
1424
                    var msg = "Undefined module " + s[i] + " skipped";
 
1425
                    this.inserted[s[i]] = true;
 
1426
                    this.skipped[s[i]] = true;
 
1427
                    continue;
 
1428
 
 
1429
                    // this.fire('failure', {
 
1430
                        // msg: msg,
 
1431
                        // data: this.data
 
1432
                    // });
 
1433
                }
 
1434
 
 
1435
 
 
1436
                // The load type is stored to offer the possibility to load
 
1437
                // the css separately from the script.
 
1438
                if (!this.loadType || this.loadType === m.type) {
 
1439
                    this._loading = s[i];
 
1440
 
 
1441
                    var fn=(m.type === CSS) ? Y.Get.css : Y.Get.script,
 
1442
                        onsuccess=function(o) {
 
1443
                            self.loadNext(o.data);
 
1444
                        };
 
1445
                        
 
1446
                    url=m.fullpath || this._url(m.path, s[i]);
 
1447
                    self=this; 
 
1448
 
 
1449
                    fn(url, {
 
1450
                        data: s[i],
 
1451
                        onSuccess: onsuccess,
 
1452
                        insertBefore: this.insertBefore,
 
1453
                        charset: this.charset,
 
1454
                        onFailure: this._onFailure,
 
1455
                        onTimeout: this._onTimeout,
 
1456
                        timeout: this.timeout,
 
1457
                        context: self 
 
1458
                    });
 
1459
 
 
1460
                    return;
 
1461
                }
 
1462
            }
 
1463
 
 
1464
            // we are finished
 
1465
            this._loading = null;
 
1466
 
 
1467
            // internal callback for loading css first
 
1468
            if (this._internalCallback) {
 
1469
 
 
1470
                var f = this._internalCallback;
 
1471
                this._internalCallback = null;
 
1472
                f.call(this);
 
1473
 
 
1474
            // } else if (this.onSuccess) {
 
1475
            } else {
 
1476
 
 
1477
                // call Y.use passing this instance. Y will use the sorted
 
1478
                // dependency list.
 
1479
 
 
1480
                this._onSuccess();
 
1481
 
 
1482
            }
 
1483
 
 
1484
        },
 
1485
 
 
1486
        /**
 
1487
         * In IE, the onAvailable/onDOMReady events need help when Event is
 
1488
         * loaded dynamically
 
1489
         * @method _pushEvents
 
1490
         * @param {Function} optional function reference
 
1491
         * @private
 
1492
         */
 
1493
        _pushEvents: function() {
 
1494
            if (Y.Event) {
 
1495
                Y.Event._load();
 
1496
            }
 
1497
        },
 
1498
 
 
1499
        /**
 
1500
         * Generates the full url for a module
 
1501
         * method _url
 
1502
         * @param path {string} the path fragment
 
1503
         * @return {string} the full url
 
1504
         * @private
 
1505
         */
 
1506
        _url: function(path, name) {
 
1507
            
 
1508
            var u = (this.base || "") + path, 
 
1509
                f = this.filter;
 
1510
 
 
1511
            if (f) {
 
1512
                var useFilter = true;
 
1513
 
 
1514
                if (this.filterName == "DEBUG") {
 
1515
                
 
1516
                    var self = this, 
 
1517
                        exc = self.logExclude,
 
1518
                        inc = self.logInclude;
 
1519
                    if (inc && !(name in inc)) {
 
1520
                        useFilter = false;
 
1521
                    } else if (exc && (name in exc)) {
 
1522
                        useFilter = false;
 
1523
                    }
 
1524
 
 
1525
                }
 
1526
                
 
1527
                if (useFilter) {
 
1528
                    u = u.replace(new RegExp(f.searchExp), f.replaceStr);
 
1529
                }
 
1530
            }
 
1531
 
 
1532
 
 
1533
            return u;
 
1534
        }
 
1535
 
 
1536
    };
 
1537
 
 
1538
    // Y.augment(Y.Loader, Y.Event.Target);
 
1539
 
 
1540
}, "3.0.0pr1");