~launchpad-pqm/lazr-js/toolchain

« back to all changes in this revision

Viewing changes to src-js/lazrjs/yui/loader/loader-base-debug.js

  • Committer: Sidnei da Silva
  • Date: 2009-11-16 00:51:29 UTC
  • mto: This revision was merged to the branch mainline in revision 154.
  • Revision ID: sidnei.da.silva@canonical.com-20091116005129-8ibwjlboa38glaw5
- Improved generation of skin modules and revamped combo service to make it more twisty.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3
 
Code licensed under the BSD License:
4
 
http://developer.yahoo.com/yui/license.html
5
 
version: 3.2.0
6
 
build: 2676
7
 
*/
8
 
YUI.add('loader-base', function(Y) {
9
 
 
10
 
/**
11
 
 * The YUI loader core
12
 
 * @module loader
13
 
 * @submodule loader-base
14
 
 */
15
 
 
16
 
if (!YUI.Env[Y.version]) {
17
 
 
18
 
    (function() {
19
 
        var VERSION         = Y.version,
20
 
            // CONFIG          = Y.config,
21
 
            BUILD           = '/build/',
22
 
            ROOT            = VERSION + BUILD,
23
 
            CDN_BASE        = Y.Env.base,
24
 
            GALLERY_VERSION = 'gallery-2010.09.01-19-12',
25
 
            // GALLERY_ROOT    = GALLERY_VERSION + BUILD,
26
 
            TNT             = '2in3',
27
 
            TNT_VERSION     = '3',
28
 
            YUI2_VERSION    = '2.8.1',
29
 
            // YUI2_ROOT       = TNT + '.' + TNT_VERSION + '/' + YUI2_VERSION + BUILD,
30
 
            COMBO_BASE      = CDN_BASE + 'combo?',
31
 
            META =          { version:   VERSION,
32
 
                              root:      ROOT,
33
 
                              base:      Y.Env.base,
34
 
                              comboBase: COMBO_BASE,
35
 
                              skin:      { defaultSkin: 'sam',
36
 
                                           base:        'assets/skins/',
37
 
                                           path:        'skin.css',
38
 
                                           after:       [ 'cssreset', 
39
 
                                                          'cssfonts', 
40
 
                                                          'cssgrids', 
41
 
                                                          'cssbase', 
42
 
                                                          'cssreset-context', 
43
 
                                                          'cssfonts-context' ] },
44
 
                              groups:    {},
45
 
                              // modules:   { / METAGEN / },
46
 
                              patterns:  {}                                     },
47
 
            groups =          META.groups,
48
 
            yui2Update =      function(tnt, yui2) {
49
 
                                  var root = TNT + '.' + 
50
 
                                            (tnt || TNT_VERSION) + '/' + (yui2 || YUI2_VERSION) + BUILD;
51
 
                                  groups.yui2.base = CDN_BASE + root;
52
 
                                  groups.yui2.root = root;
53
 
                              },
54
 
            galleryUpdate =   function(tag) {
55
 
                                  var root = (tag || GALLERY_VERSION) + BUILD;
56
 
                                  groups.gallery.base = CDN_BASE + root;
57
 
                                  groups.gallery.root = root;
58
 
                              };
59
 
 
60
 
        groups[VERSION] = {};
61
 
 
62
 
        groups.gallery = {
63
 
            // base:      CDN_BASE + GALLERY_ROOT,
64
 
            ext:       false,
65
 
            combine:   true,
66
 
            // root:      GALLERY_ROOT,
67
 
            comboBase: COMBO_BASE,
68
 
            update:    galleryUpdate,
69
 
            patterns:  { 'gallery-':    { },
70
 
                         'gallerycss-': { type: 'css' } }
71
 
        };
72
 
 
73
 
        groups.yui2 = {
74
 
            // base:      CDN_BASE + YUI2_ROOT,
75
 
            combine:   true,
76
 
            ext:       false,
77
 
            // root:      YUI2_ROOT,
78
 
            comboBase: COMBO_BASE,
79
 
            update:    yui2Update,
80
 
            patterns:  { 
81
 
                'yui2-': {
82
 
                    configFn: function(me) {
83
 
                        if(/-skin|reset|fonts|grids|base/.test(me.name)) {
84
 
                            me.type = 'css';
85
 
                            me.path = me.path.replace(/\.js/, '.css');
86
 
                            // this makes skins in builds earlier than 2.6.0 work as long as combine is false
87
 
                            me.path = me.path.replace(/\/yui2-skin/, '/assets/skins/sam/yui2-skin');
88
 
                        }
89
 
                    }
90
 
                } 
91
 
            }
92
 
        };
93
 
 
94
 
        galleryUpdate();
95
 
        yui2Update();
96
 
 
97
 
        YUI.Env[VERSION] = META;
98
 
    }());
99
 
}
100
 
 
101
 
 
102
 
/**
103
 
 * Loader dynamically loads script and css files.  It includes the dependency
104
 
 * info for the version of the library in use, and will automatically pull in
105
 
 * dependencies for the modules requested.  It supports rollup files and will
106
 
 * automatically use these when appropriate in order to minimize the number of
107
 
 * http connections required to load all of the dependencies.  It can load the
108
 
 * files from the Yahoo! CDN, and it can utilize the combo service provided on
109
 
 * this network to reduce the number of http connections required to download 
110
 
 * YUI files.
111
 
 *
112
 
 * @module loader
113
 
 * @submodule loader-base
114
 
 */
115
 
 
116
 
/**
117
 
 * Loader dynamically loads script and css files.  It includes the dependency
118
 
 * info for the version of the library in use, and will automatically pull in
119
 
 * dependencies for the modules requested.  It supports rollup files and will
120
 
 * automatically use these when appropriate in order to minimize the number of
121
 
 * http connections required to load all of the dependencies.  It can load the
122
 
 * files from the Yahoo! CDN, and it can utilize the combo service provided on
123
 
 * this network to reduce the number of http connections required to download 
124
 
 * YUI files.
125
 
 *
126
 
 * While the loader can be instantiated by the end user, it normally is not.
127
 
 * @see YUI.use for the normal use case.  The use function automatically will
128
 
 * pull in missing dependencies.
129
 
 *
130
 
 * @class Loader
131
 
 * @constructor
132
 
 * @param o an optional set of configuration options.  Valid options:
133
 
 * <ul>
134
 
 *  <li>base:
135
 
 *  The base dir</li>
136
 
 *  <li>comboBase:
137
 
 *  The YUI combo service base dir. Ex: http://yui.yahooapis.com/combo?</li>
138
 
 *  <li>root:
139
 
 *  The root path to prepend to module names for the combo service. Ex: 2.5.2/build/</li>
140
 
 *  <li>filter:
141
 
 *  
142
 
 * A filter to apply to result urls.  This filter will modify the default
143
 
 * path for all modules.  The default path for the YUI library is the
144
 
 * minified version of the files (e.g., event-min.js).  The filter property
145
 
 * can be a predefined filter or a custom filter.  The valid predefined 
146
 
 * filters are:
147
 
 * <dl>
148
 
 *  <dt>DEBUG</dt>
149
 
 *  <dd>Selects the debug versions of the library (e.g., event-debug.js).
150
 
 *      This option will automatically include the Logger widget</dd>
151
 
 *  <dt>RAW</dt>
152
 
 *  <dd>Selects the non-minified version of the library (e.g., event.js).</dd>
153
 
 * </dl>
154
 
 * You can also define a custom filter, which must be an object literal 
155
 
 * containing a search expression and a replace string:
156
 
 * <pre>
157
 
 *  myFilter: &#123; 
158
 
 *      'searchExp': "-min\\.js", 
159
 
 *      'replaceStr': "-debug.js"
160
 
 *  &#125;
161
 
 * </pre>
162
 
 *
163
 
 *  </li>
164
 
 *  <li>filters: per-component filter specification.  If specified for a given component, this overrides the filter config</li>
165
 
 *  <li>combine:
166
 
 *  Use the YUI combo service to reduce the number of http connections required to load your dependencies</li>
167
 
 *  <li>ignore:
168
 
 *  A list of modules that should never be dynamically loaded</li>
169
 
 *  <li>force:
170
 
 *  A list of modules that should always be loaded when required, even if already present on the page</li>
171
 
 *  <li>insertBefore:
172
 
 *  Node or id for a node that should be used as the insertion point for new nodes</li>
173
 
 *  <li>charset:
174
 
 *  charset for dynamic nodes (deprecated, use jsAttributes or cssAttributes)</li>
175
 
 *  <li>jsAttributes: object literal containing attributes to add to script nodes</li>
176
 
 *  <li>cssAttributes: object literal containing attributes to add to link nodes</li>
177
 
 *  <li>timeout:
178
 
 *  The number of milliseconds before a timeout occurs when dynamically loading nodes.  If
179
 
 *  not set, there is no timeout</li>
180
 
 *  <li>context:
181
 
 *  execution context for all callbacks</li>
182
 
 *  <li>onSuccess:
183
 
 *  callback for the 'success' event</li>
184
 
 *  <li>onFailure: callback for the 'failure' event</li>
185
 
 *  <li>onCSS: callback for the 'CSSComplete' event.  When loading YUI components with CSS
186
 
 *  the CSS is loaded first, then the script.  This provides a moment you can tie into to improve
187
 
 *  the presentation of the page while the script is loading.</li>
188
 
 *  <li>onTimeout:
189
 
 *  callback for the 'timeout' event</li>
190
 
 *  <li>onProgress:
191
 
 *  callback executed each time a script or css file is loaded</li>
192
 
 *  <li>modules:
193
 
 *  A list of module definitions.  See Loader.addModule for the supported module metadata</li>
194
 
 *  <li>groups:
195
 
 *  A list of group definitions.  Each group can contain specific definitions for base, comboBase,
196
 
 *  combine, and accepts a list of modules.  See above for the description of these properties.</li>
197
 
 *  <li>2in3: the version of the YUI 2 in 3 wrapper to use.  The intrinsic support for YUI 2 modules
198
 
 *  in YUI 3 relies on versions of the YUI 2 components inside YUI 3 module wrappers.  These wrappers
199
 
 *  change over time to accomodate the issues that arise from running YUI 2 in a YUI 3 sandbox.</li>
200
 
 *  <li>yui2: when using the 2in3 project, you can select the version of YUI 2 to use.  Valid values
201
 
 *  are 2.2.2, 2.3.1, 2.4.1, 2.5.2, 2.6.0, 2.7.0, 2.8.0, and 2.8.1 [default] -- plus all versions
202
 
 *  of YUI 2 going forward.</li>
203
 
 * </ul>
204
 
 */
205
 
 
206
 
var NOT_FOUND       = {},
207
 
    NO_REQUIREMENTS = [],
208
 
    MAX_URL_LENGTH  = (Y.UA.ie) ? 2048 : 8192,
209
 
    GLOBAL_ENV      = YUI.Env,
210
 
    GLOBAL_LOADED   = GLOBAL_ENV._loaded,
211
 
    CSS             = 'css',
212
 
    JS              = 'js',
213
 
    INTL            = 'intl',
214
 
    VERSION         = Y.version,
215
 
    ROOT_LANG       = "",
216
 
    YObject         = Y.Object,
217
 
    oeach           = YObject.each,
218
 
    YArray          = Y.Array,
219
 
    _queue          = GLOBAL_ENV._loaderQueue,
220
 
    META            = GLOBAL_ENV[VERSION],
221
 
    SKIN_PREFIX     = "skin-",
222
 
    L               = Y.Lang,
223
 
    ON_PAGE         = GLOBAL_ENV.mods,
224
 
    modulekey,
225
 
    cache,
226
 
    _path           = function(dir, file, type, nomin) {
227
 
                        var path = dir + '/' + file;
228
 
                        if (!nomin) {
229
 
                            path += '-min';
230
 
                        }
231
 
                        path += '.' + (type || CSS);
232
 
 
233
 
                        return path;
234
 
                    };
235
 
 
236
 
Y.Env.meta = META;
237
 
 
238
 
Y.Loader = function(o) {
239
 
 
240
 
    var defaults = META.modules, 
241
 
        self     = this;
242
 
 
243
 
    modulekey       = META.md5;
244
 
 
245
 
    /**
246
 
     * Internal callback to handle multiple internal insert() calls
247
 
     * so that css is inserted prior to js
248
 
     * @property _internalCallback
249
 
     * @private
250
 
     */
251
 
    // self._internalCallback = null;
252
 
 
253
 
    /**
254
 
     * Callback that will be executed when the loader is finished
255
 
     * with an insert
256
 
     * @method onSuccess
257
 
     * @type function
258
 
     */
259
 
    // self.onSuccess = null;
260
 
 
261
 
    /**
262
 
     * Callback that will be executed if there is a failure
263
 
     * @method onFailure
264
 
     * @type function
265
 
     */
266
 
    // self.onFailure = null;
267
 
 
268
 
    /**
269
 
     * Callback for the 'CSSComplete' event.  When loading YUI components with CSS
270
 
     * the CSS is loaded first, then the script.  This provides a moment you can tie into to improve
271
 
     * the presentation of the page while the script is loading.
272
 
     * @method onCSS
273
 
     * @type function
274
 
     */
275
 
    // self.onCSS = null;
276
 
 
277
 
    /**
278
 
     * Callback executed each time a script or css file is loaded
279
 
     * @method onProgress
280
 
     * @type function
281
 
     */
282
 
    // self.onProgress = null;
283
 
 
284
 
    /**
285
 
     * Callback that will be executed if a timeout occurs
286
 
     * @method onTimeout
287
 
     * @type function
288
 
     */
289
 
    // self.onTimeout = null;
290
 
 
291
 
    /**
292
 
     * The execution context for all callbacks
293
 
     * @property context
294
 
     * @default {YUI} the YUI instance
295
 
     */
296
 
    self.context = Y;
297
 
 
298
 
    /**
299
 
     * Data that is passed to all callbacks
300
 
     * @property data
301
 
     */
302
 
    // self.data = null;
303
 
 
304
 
    /**
305
 
     * Node reference or id where new nodes should be inserted before
306
 
     * @property insertBefore
307
 
     * @type string|HTMLElement
308
 
     */
309
 
    // self.insertBefore = null;
310
 
 
311
 
    /**
312
 
     * The charset attribute for inserted nodes
313
 
     * @property charset
314
 
     * @type string
315
 
     * @deprecated, use cssAttributes or jsAttributes
316
 
     */
317
 
    // self.charset = null;
318
 
 
319
 
    /**
320
 
     * An object literal containing attributes to add to link nodes
321
 
     * @property cssAttributes
322
 
     * @type object
323
 
     */
324
 
    // self.cssAttributes = null;
325
 
 
326
 
    /**
327
 
     * An object literal containing attributes to add to script nodes
328
 
     * @property jsAttributes
329
 
     * @type object
330
 
     */
331
 
    // self.jsAttributes = null;
332
 
 
333
 
    /**
334
 
     * The base directory.
335
 
     * @property base
336
 
     * @type string
337
 
     * @default http://yui.yahooapis.com/[YUI VERSION]/build/
338
 
     */
339
 
    self.base = Y.Env.meta.base;
340
 
 
341
 
    /**
342
 
     * Base path for the combo service
343
 
     * @property comboBase
344
 
     * @type string
345
 
     * @default http://yui.yahooapis.com/combo?
346
 
     */
347
 
    self.comboBase = Y.Env.meta.comboBase;
348
 
 
349
 
    /*
350
 
     * Base path for language packs.
351
 
     */
352
 
    // self.langBase = Y.Env.meta.langBase;
353
 
    // self.lang = "";
354
 
 
355
 
    /**
356
 
     * If configured, the loader will attempt to use the combo
357
 
     * service for YUI resources and configured external resources.
358
 
     * @property combine
359
 
     * @type boolean
360
 
     * @default true if a base dir isn't in the config
361
 
     */
362
 
    self.combine = o.base && (o.base.indexOf( self.comboBase.substr(0, 20)) > -1);
363
 
 
364
 
    /**
365
 
     * Max url length for combo urls.  The default is 2048 for
366
 
     * internet explorer, and 8192 otherwise.  This is the URL
367
 
     * limit for the Yahoo! hosted combo servers.  If consuming
368
 
     * a different combo service that has a different URL limit
369
 
     * it is possible to override this default by supplying 
370
 
     * the maxURLLength config option.  The config option will
371
 
     * only take effect if lower than the default.
372
 
     *
373
 
     * Browsers:
374
 
     *    IE: 2048
375
 
     *    Other A-Grade Browsers: Higher that what is typically supported 
376
 
     *    'capable' mobile browsers: @TODO
377
 
     *
378
 
     * Servers:
379
 
     *    Apache: 8192
380
 
     *
381
 
     * @property maxURLLength
382
 
     * @type int
383
 
     */
384
 
    self.maxURLLength = MAX_URL_LENGTH;
385
 
 
386
 
    /**
387
 
     * Ignore modules registered on the YUI global
388
 
     * @property ignoreRegistered
389
 
     * @default false
390
 
     */
391
 
    // self.ignoreRegistered = false;
392
 
 
393
 
    /**
394
 
     * Root path to prepend to module path for the combo
395
 
     * service
396
 
     * @property root
397
 
     * @type string
398
 
     * @default [YUI VERSION]/build/
399
 
     */
400
 
    self.root = Y.Env.meta.root;
401
 
 
402
 
    /**
403
 
     * Timeout value in milliseconds.  If set, self value will be used by
404
 
     * the get utility.  the timeout event will fire if
405
 
     * a timeout occurs.
406
 
     * @property timeout
407
 
     * @type int
408
 
     */
409
 
    self.timeout = 0;
410
 
 
411
 
    /**
412
 
     * A list of modules that should not be loaded, even if
413
 
     * they turn up in the dependency tree
414
 
     * @property ignore
415
 
     * @type string[]
416
 
     */
417
 
    // self.ignore = null;
418
 
 
419
 
    /**
420
 
     * A list of modules that should always be loaded, even
421
 
     * if they have already been inserted into the page.
422
 
     * @property force
423
 
     * @type string[]
424
 
     */
425
 
    // self.force = null;
426
 
 
427
 
    self.forceMap = {};
428
 
 
429
 
    /**
430
 
     * Should we allow rollups
431
 
     * @property allowRollup
432
 
     * @type boolean
433
 
     * @default true
434
 
     */
435
 
    self.allowRollup = true;
436
 
 
437
 
    /**
438
 
     * A filter to apply to result urls.  This filter will modify the default
439
 
     * path for all modules.  The default path for the YUI library is the
440
 
     * minified version of the files (e.g., event-min.js).  The filter property
441
 
     * can be a predefined filter or a custom filter.  The valid predefined 
442
 
     * filters are:
443
 
     * <dl>
444
 
     *  <dt>DEBUG</dt>
445
 
     *  <dd>Selects the debug versions of the library (e.g., event-debug.js).
446
 
     *      This option will automatically include the Logger widget</dd>
447
 
     *  <dt>RAW</dt>
448
 
     *  <dd>Selects the non-minified version of the library (e.g., event.js).</dd>
449
 
     * </dl>
450
 
     * You can also define a custom filter, which must be an object literal 
451
 
     * containing a search expression and a replace string:
452
 
     * <pre>
453
 
     *  myFilter: &#123; 
454
 
     *      'searchExp': "-min\\.js", 
455
 
     *      'replaceStr': "-debug.js"
456
 
     *  &#125;
457
 
     * </pre>
458
 
     * @property filter
459
 
     * @type string|{searchExp: string, replaceStr: string}
460
 
     */
461
 
    // self.filter = null;
462
 
 
463
 
    /**
464
 
     * per-component filter specification.  If specified for a given component, this 
465
 
     * overrides the filter config.
466
 
     * @property filters
467
 
     * @type object
468
 
     */
469
 
    self.filters = {};
470
 
 
471
 
    /**
472
 
     * The list of requested modules
473
 
     * @property required
474
 
     * @type {string: boolean}
475
 
     */
476
 
    self.required = {};
477
 
 
478
 
    /**
479
 
     * If a module name is predefined when requested, it is checked againsts
480
 
     * the patterns provided in this property.  If there is a match, the
481
 
     * module is added with the default configuration.
482
 
     *
483
 
     * At the moment only supporting module prefixes, but anticipate supporting
484
 
     * at least regular expressions.
485
 
     * @property patterns
486
 
     * @type Object
487
 
     */
488
 
    // self.patterns = Y.merge(Y.Env.meta.patterns);
489
 
    self.patterns = {};
490
 
 
491
 
    /**
492
 
     * The library metadata
493
 
     * @property moduleInfo
494
 
     */
495
 
    // self.moduleInfo = Y.merge(Y.Env.meta.moduleInfo);
496
 
    self.moduleInfo = {};
497
 
 
498
 
    self.groups = Y.merge(Y.Env.meta.groups);
499
 
 
500
 
    /**
501
 
     * Provides the information used to skin the skinnable components.
502
 
     * The following skin definition would result in 'skin1' and 'skin2'
503
 
     * being loaded for calendar (if calendar was requested), and
504
 
     * 'sam' for all other skinnable components:
505
 
     *
506
 
     *   <code>
507
 
     *   skin: {
508
 
     *
509
 
     *      // The default skin, which is automatically applied if not
510
 
     *      // overriden by a component-specific skin definition.
511
 
     *      // Change this in to apply a different skin globally
512
 
     *      defaultSkin: 'sam', 
513
 
     *
514
 
     *      // This is combined with the loader base property to get
515
 
     *      // the default root directory for a skin. ex:
516
 
     *      // http://yui.yahooapis.com/2.3.0/build/assets/skins/sam/
517
 
     *      base: 'assets/skins/',
518
 
     *
519
 
     *      // Any component-specific overrides can be specified here,
520
 
     *      // making it possible to load different skins for different
521
 
     *      // components.  It is possible to load more than one skin
522
 
     *      // for a given component as well.
523
 
     *      overrides: {
524
 
     *          calendar: ['skin1', 'skin2']
525
 
     *      }
526
 
     *   }
527
 
     *   </code>
528
 
     *   @property skin
529
 
     */
530
 
    self.skin = Y.merge(Y.Env.meta.skin);
531
 
 
532
 
    /*
533
 
     * Map of conditional modules
534
 
     * @since 3.2.0
535
 
     */
536
 
    self.conditions = {};
537
 
 
538
 
    // map of modules with a hash of modules that meet the requirement
539
 
    // self.provides = {};
540
 
 
541
 
    self.config = o;
542
 
    self._internal = true;
543
 
 
544
 
 
545
 
    cache = GLOBAL_ENV._renderedMods;
546
 
 
547
 
    if (cache) {
548
 
        oeach(cache, function(v, k) {
549
 
            self.moduleInfo[k] = Y.merge(v);
550
 
        });
551
 
 
552
 
        cache = GLOBAL_ENV._conditions;
553
 
        
554
 
        oeach(cache, function(v, k) {
555
 
            self.conditions[k] = Y.merge(v);
556
 
        });
557
 
 
558
 
    } else {
559
 
        oeach(defaults, self.addModule, self);
560
 
    }
561
 
 
562
 
    if (!GLOBAL_ENV._renderedMods) {
563
 
        GLOBAL_ENV._renderedMods = Y.merge(self.moduleInfo);
564
 
        GLOBAL_ENV._conditions = Y.merge(self.conditions);
565
 
    }
566
 
 
567
 
    self._inspectPage();
568
 
 
569
 
    self._internal = false;
570
 
 
571
 
    self._config(o);
572
 
 
573
 
    /**
574
 
     * List of rollup files found in the library metadata
575
 
     * @property rollups
576
 
     */
577
 
    // self.rollups = null;
578
 
 
579
 
    /**
580
 
     * Whether or not to load optional dependencies for 
581
 
     * the requested modules
582
 
     * @property loadOptional
583
 
     * @type boolean
584
 
     * @default false
585
 
     */
586
 
    // self.loadOptional = false;
587
 
 
588
 
    /**
589
 
     * All of the derived dependencies in sorted order, which
590
 
     * will be populated when either calculate() or insert()
591
 
     * is called
592
 
     * @property sorted
593
 
     * @type string[]
594
 
     */
595
 
    self.sorted = [];
596
 
 
597
 
    /**
598
 
     * Set when beginning to compute the dependency tree. 
599
 
     * Composed of what YUI reports to be loaded combined
600
 
     * with what has been loaded by any instance on the page
601
 
     * with the version number specified in the metadata.
602
 
     * @propery loaded
603
 
     * @type {string: boolean}
604
 
     */
605
 
    self.loaded = GLOBAL_LOADED[VERSION];
606
 
 
607
 
    /*
608
 
     * A list of modules to attach to the YUI instance when complete.
609
 
     * If not supplied, the sorted list of dependencies are applied.
610
 
     * @property attaching
611
 
     */
612
 
    // self.attaching = null;
613
 
 
614
 
    /**
615
 
     * Flag to indicate the dependency tree needs to be recomputed
616
 
     * if insert is called again.
617
 
     * @property dirty
618
 
     * @type boolean
619
 
     * @default true
620
 
     */
621
 
    self.dirty = true;
622
 
 
623
 
    /**
624
 
     * List of modules inserted by the utility
625
 
     * @property inserted
626
 
     * @type {string: boolean}
627
 
     */
628
 
    self.inserted = {};
629
 
 
630
 
    /**
631
 
     * List of skipped modules during insert() because the module
632
 
     * was not defined
633
 
     * @property skipped
634
 
     */
635
 
    self.skipped = {};
636
 
 
637
 
    // Y.on('yui:load', self.loadNext, self);
638
 
 
639
 
 
640
 
    /*
641
 
     * Cached sorted calculate results
642
 
     * @property results
643
 
     * @since 3.2.0
644
 
     */
645
 
    //self.results = {};
646
 
 
647
 
};
648
 
 
649
 
Y.Loader.prototype = {
650
 
 
651
 
    FILTER_DEFS: {
652
 
        RAW: { 
653
 
            'searchExp': "-min\\.js", 
654
 
            'replaceStr': ".js"
655
 
        },
656
 
        DEBUG: { 
657
 
            'searchExp': "-min\\.js", 
658
 
            'replaceStr': "-debug.js"
659
 
        }
660
 
    },
661
 
 
662
 
   _inspectPage: function() {
663
 
       oeach(ON_PAGE, function(v, k) {
664
 
           if (v.details) {
665
 
               var m = this.moduleInfo[k],
666
 
                   req = v.details.requires,
667
 
                   mr = m && m.requires;
668
 
               if (m) {
669
 
                   if (!m._inspected && req && mr.length != req.length) {
670
 
                       delete m.expanded;
671
 
                   }
672
 
               } else {
673
 
                   m = this.addModule(v.details, k);
674
 
               }
675
 
               m._inspected = true;
676
 
           }
677
 
       }, this);
678
 
   },
679
 
 
680
 
// returns true if b is not loaded, and is required
681
 
// directly or by means of modules it supersedes.
682
 
   _requires: function(mod1, mod2) {
683
 
 
684
 
        var i, rm, after, after_map, s,
685
 
            info  = this.moduleInfo, 
686
 
            m     = info[mod1], 
687
 
            other = info[mod2]; 
688
 
 
689
 
        // if (loaded[mod2] || !m || !other) {
690
 
        if (!m || !other) {
691
 
            return false;
692
 
        }
693
 
 
694
 
        rm    = m.expanded_map;
695
 
        after = m.after; 
696
 
        after_map = m.after_map; 
697
 
 
698
 
        // check if this module requires the other directly
699
 
        // if (r && YArray.indexOf(r, mod2) > -1) {
700
 
        if (rm && (mod2 in rm)) {
701
 
            return true;
702
 
        }
703
 
 
704
 
        // check if this module should be sorted after the other
705
 
        if (after_map && (mod2 in after_map)) {
706
 
            return true;
707
 
        } else if (after && YArray.indexOf(after, mod2) > -1) {
708
 
            return true;
709
 
        }
710
 
 
711
 
        // check if this module requires one the other supersedes
712
 
        s = info[mod2] && info[mod2].supersedes;
713
 
        if (s) {
714
 
            for (i=0; i<s.length; i++) {
715
 
                if (this._requires(mod1, s[i])) {
716
 
                    return true;
717
 
                }
718
 
            }
719
 
        }
720
 
 
721
 
        // external css files should be sorted below yui css
722
 
        if (m.ext && m.type == CSS && !other.ext && other.type == CSS) {
723
 
            return true;
724
 
        }
725
 
 
726
 
        return false;
727
 
    },
728
 
 
729
 
    _config: function(o) {
730
 
        var i, j, val, f, group, groupName, self = this;
731
 
        // apply config values
732
 
        if (o) {
733
 
            for (i in o) {
734
 
                if (o.hasOwnProperty(i)) {
735
 
                    val = o[i];
736
 
                    if (i == 'require') {
737
 
                        self.require(val);
738
 
                    } else if (i == 'skin') {
739
 
                        Y.mix(self.skin, o[i], true);
740
 
                    } else if (i == 'groups') {
741
 
                        for (j in val) {
742
 
                            if (val.hasOwnProperty(j)) {
743
 
                                // Y.log('group: ' + j);
744
 
                                groupName = j;
745
 
                                group = val[j];
746
 
                                self.addGroup(group, groupName);
747
 
                            }
748
 
                        }
749
 
 
750
 
                    } else if (i == 'modules') {
751
 
                        // add a hash of module definitions
752
 
                        oeach(val, self.addModule, self);
753
 
                    } else if (i == 'gallery') {
754
 
                        this.groups.gallery.update(val);
755
 
                    } else if (i == 'yui2' || i == '2in3') {
756
 
                        this.groups.yui2.update(o['2in3'], o.yui2);
757
 
                    } else if (i == 'maxURLLength') {
758
 
                        self[i] = Math.min(MAX_URL_LENGTH, val);
759
 
                    } else {
760
 
                        self[i] = val;
761
 
                    }
762
 
                }
763
 
            }
764
 
        }
765
 
 
766
 
        // fix filter
767
 
        f = self.filter;
768
 
 
769
 
        if (L.isString(f)) {
770
 
            f = f.toUpperCase();
771
 
            self.filterName = f;
772
 
            self.filter = self.FILTER_DEFS[f];
773
 
            if (f == 'DEBUG') {
774
 
                self.require('yui-log', 'dump');
775
 
            }
776
 
        }
777
 
 
778
 
    },
779
 
 
780
 
    /**
781
 
     * Returns the skin module name for the specified skin name.  If a
782
 
     * module name is supplied, the returned skin module name is 
783
 
     * specific to the module passed in.
784
 
     * @method formatSkin
785
 
     * @param skin {string} the name of the skin
786
 
     * @param mod {string} optional: the name of a module to skin
787
 
     * @return {string} the full skin module name
788
 
     */
789
 
    formatSkin: function(skin, mod) {
790
 
        var s = SKIN_PREFIX + skin;
791
 
        if (mod) {
792
 
            s = s + "-" + mod;
793
 
        }
794
 
 
795
 
        return s;
796
 
    },
797
 
 
798
 
    /**
799
 
     * Adds the skin def to the module info
800
 
     * @method _addSkin
801
 
     * @param skin {string} the name of the skin
802
 
     * @param mod {string} the name of the module
803
 
     * @param parent {string} parent module if this is a skin of a
804
 
     * submodule or plugin
805
 
     * @return {string} the module name for the skin
806
 
     * @private
807
 
     */
808
 
    _addSkin: function(skin, mod, parent) {
809
 
        var mdef, pkg, name,
810
 
            info = this.moduleInfo,
811
 
            sinf = this.skin, 
812
 
            ext  = info[mod] && info[mod].ext;
813
 
 
814
 
        // Add a module definition for the module-specific skin css
815
 
        if (mod) {
816
 
            name = this.formatSkin(skin, mod);
817
 
            if (!info[name]) {
818
 
                mdef = info[mod];
819
 
                pkg = mdef.pkg || mod;
820
 
                this.addModule({
821
 
                    name:  name,
822
 
                    group: mdef.group,
823
 
                    type:  'css',
824
 
                    after: sinf.after,
825
 
                    after_map: YArray.hash(sinf.after),
826
 
                    path:  (parent || pkg) + '/' + sinf.base + skin + '/' + mod + '.css',
827
 
                    ext:   ext
828
 
                });
829
 
 
830
 
                // Y.log('adding skin ' + name + ', ' + parent + ', ' + pkg + ', ' + info[name].path);
831
 
            }
832
 
        }
833
 
 
834
 
        return name;
835
 
    },
836
 
 
837
 
    /** Add a new module group
838
 
     * <dl>
839
 
     *   <dt>name:</dt>      <dd>required, the group name</dd>
840
 
     *   <dt>base:</dt>      <dd>The base dir for this module group</dd>
841
 
     *   <dt>root:</dt>      <dd>The root path to add to each combo resource path</dd>
842
 
     *   <dt>combine:</dt>   <dd>combo handle</dd>
843
 
     *   <dt>comboBase:</dt> <dd>combo service base path</dd>
844
 
     *   <dt>modules:</dt>   <dd>the group of modules</dd>
845
 
     * </dl>
846
 
     * @method addGroup
847
 
     * @param o An object containing the module data
848
 
     * @param name the module name (optional), required if not in the module data
849
 
     * @return {boolean} true if the module was added, false if 
850
 
     * the object passed in did not provide all required attributes
851
 
     */
852
 
    addGroup: function(o, name) {
853
 
        var mods = o.modules, 
854
 
            self = this;
855
 
        name   = name || o.name;
856
 
        o.name = name;
857
 
        self.groups[name] = o;
858
 
 
859
 
        if (o.patterns) {
860
 
            oeach(o.patterns, function(v, k) {
861
 
                v.group = name;
862
 
                self.patterns[k] = v;
863
 
            });
864
 
        }
865
 
 
866
 
        if (mods) {
867
 
            oeach(mods, function(v, k) {
868
 
                v.group = name;
869
 
                self.addModule(v, k);
870
 
            }, self);
871
 
        }
872
 
    },
873
 
 
874
 
    /** Add a new module to the component metadata.         
875
 
     * <dl>
876
 
     *     <dt>name:</dt>       <dd>required, the component name</dd>
877
 
     *     <dt>type:</dt>       <dd>required, the component type (js or css)</dd>
878
 
     *     <dt>path:</dt>       <dd>required, the path to the script from "base"</dd>
879
 
     *     <dt>requires:</dt>   <dd>array of modules required by this component</dd>
880
 
     *     <dt>optional:</dt>   <dd>array of optional modules for this component</dd>
881
 
     *     <dt>supersedes:</dt> <dd>array of the modules this component replaces</dd>
882
 
     *     <dt>after:</dt>      <dd>array of modules the components which, if present, should be sorted above this one</dd>
883
 
     *     <dt>after_map:</dt>  <dd>faster alternative to 'after' -- supply a hash instead of an array</dd>
884
 
     *     <dt>rollup:</dt>     <dd>the number of superseded modules required for automatic rollup</dd>
885
 
     *     <dt>fullpath:</dt>   <dd>If fullpath is specified, this is used instead of the configured base + path</dd>
886
 
     *     <dt>skinnable:</dt>  <dd>flag to determine if skin assets should automatically be pulled in</dd>
887
 
     *     <dt>submodules:</dt> <dd>a hash of submodules</dd>
888
 
     *     <dt>group:</dt>      <dd>The group the module belongs to -- this is set automatically when
889
 
     *                          it is added as part of a group configuration.</dd>
890
 
     *     <dt>lang:</dt>       <dd>array of BCP 47 language tags of
891
 
     *                              languages for which this module has localized resource bundles,
892
 
     *                              e.g., ["en-GB","zh-Hans-CN"]</dd>
893
 
     *     <dt>condition:</dt>  <dd>Specifies that the module should be loaded automatically if
894
 
     *                              a condition is met.  This is an object with two fields:
895
 
     *                              [trigger] - the name of a module that can trigger the auto-load
896
 
     *                              [test] - a function that returns true when the module is to be loaded
897
 
     *                          </dd>
898
 
     * </dl>
899
 
     * @method addModule
900
 
     * @param o An object containing the module data
901
 
     * @param name the module name (optional), required if not in the module data
902
 
     * @return the module definition or null if 
903
 
     * the object passed in did not provide all required attributes
904
 
     */
905
 
    addModule: function(o, name) {
906
 
 
907
 
        name = name || o.name;
908
 
        o.name = name;
909
 
 
910
 
        if (!o || !o.name) {
911
 
            return null;
912
 
        }
913
 
 
914
 
        if (!o.type) {
915
 
            o.type = JS;
916
 
        }
917
 
 
918
 
        if (!o.path && !o.fullpath) {
919
 
            o.path = _path(name, name, o.type);
920
 
        }
921
 
 
922
 
        o.ext = ('ext' in o) ? o.ext : (this._internal) ? false : true;
923
 
        o.requires = o.requires || [];
924
 
 
925
 
        // Handle submodule logic
926
 
        var subs = o.submodules, i, l, sup, s, smod, plugins, plug,
927
 
            j, langs, packName, supName, flatSup, flatLang, lang, ret,
928
 
            overrides, skinname,
929
 
            conditions = this.conditions, condmod;
930
 
            // , existing = this.moduleInfo[name], newr;
931
 
 
932
 
        this.moduleInfo[name] = o;
933
 
 
934
 
        if (!o.langPack && o.lang) {
935
 
            langs = YArray(o.lang);
936
 
            for (j=0; j < langs.length; j++) {
937
 
                lang = langs[j];
938
 
                packName = this.getLangPackName(lang, name);
939
 
                smod = this.moduleInfo[packName];
940
 
                if (!smod) {
941
 
                    smod = this._addLangPack(lang, o, packName);
942
 
                }
943
 
            }
944
 
        }
945
 
 
946
 
        if (subs) {
947
 
            sup = o.supersedes || []; 
948
 
            l   = 0;
949
 
 
950
 
            for (i in subs) {
951
 
                if (subs.hasOwnProperty(i)) {
952
 
                    s = subs[i];
953
 
 
954
 
                    s.path = s.path || _path(name, i, o.type);
955
 
                    s.pkg = name;
956
 
                    s.group = o.group;
957
 
 
958
 
                    if (s.supersedes) {
959
 
                        sup = sup.concat(s.supersedes);
960
 
                    }
961
 
 
962
 
                    smod = this.addModule(s, i);
963
 
                    sup.push(i);
964
 
 
965
 
                    if (smod.skinnable) {
966
 
                        o.skinnable = true;
967
 
                        overrides = this.skin.overrides;
968
 
                        if (overrides && overrides[i]) {
969
 
                            for (j=0; j<overrides[i].length; j++) {
970
 
                                skinname = this._addSkin(overrides[i][j], i, name);
971
 
                                sup.push(skinname);
972
 
                            }
973
 
                        }
974
 
                        skinname = this._addSkin(this.skin.defaultSkin, i, name);
975
 
                        sup.push(skinname);
976
 
                    }
977
 
 
978
 
                    // looks like we are expected to work out the metadata
979
 
                    // for the parent module language packs from what is
980
 
                    // specified in the child modules.
981
 
                    if (s.lang && s.lang.length) {
982
 
 
983
 
                        langs = YArray(s.lang);
984
 
                        for (j=0; j < langs.length; j++) {
985
 
                            lang = langs[j];
986
 
                            packName = this.getLangPackName(lang, name);
987
 
                            supName = this.getLangPackName(lang, i);
988
 
                            smod = this.moduleInfo[packName];
989
 
 
990
 
                            if (!smod) {
991
 
                                smod = this._addLangPack(lang, o, packName);
992
 
                            }
993
 
 
994
 
                            flatSup = flatSup || YArray.hash(smod.supersedes);
995
 
 
996
 
                            if (!(supName in flatSup)) {
997
 
                                smod.supersedes.push(supName);
998
 
                            }
999
 
 
1000
 
                            o.lang = o.lang || [];
1001
 
 
1002
 
                            flatLang = flatLang || YArray.hash(o.lang);
1003
 
 
1004
 
                            if (!(lang in flatLang)) {
1005
 
                                o.lang.push(lang);
1006
 
                            }
1007
 
 
1008
 
                            // Y.log('pack ' + packName + ' should supersede ' + supName);
1009
 
                            // Add rollup file, need to add to supersedes list too 
1010
 
                        }
1011
 
                    }
1012
 
 
1013
 
                    l++;
1014
 
                }
1015
 
            }
1016
 
            o.supersedes = YObject.keys(YArray.hash(sup));
1017
 
            o.rollup = (l<4) ? l : Math.min(l-1, 4);
1018
 
        }
1019
 
 
1020
 
        plugins = o.plugins;
1021
 
        if (plugins) {
1022
 
            for (i in plugins) {
1023
 
                if (plugins.hasOwnProperty(i)) {
1024
 
                    plug = plugins[i];
1025
 
                    plug.pkg = name;
1026
 
                    plug.path = plug.path || _path(name, i, o.type);
1027
 
                    plug.requires = plug.requires || [];
1028
 
                    plug.group = o.group;
1029
 
                    // plug.requires.push(name);
1030
 
                    this.addModule(plug, i);
1031
 
                    if (o.skinnable) {
1032
 
                        this._addSkin(this.skin.defaultSkin, i, name);
1033
 
                    }
1034
 
 
1035
 
                }
1036
 
            }
1037
 
        }
1038
 
 
1039
 
        if (o.condition) {
1040
 
            condmod = o.condition.trigger;
1041
 
            conditions[condmod] = conditions[condmod] || {};
1042
 
            conditions[condmod][name] = o.condition;
1043
 
        }
1044
 
 
1045
 
        // this.dirty = true;
1046
 
 
1047
 
        if (o.configFn) {
1048
 
            ret = o.configFn(o);
1049
 
            if (ret === false) {
1050
 
                delete this.moduleInfo[name];
1051
 
                o = null;
1052
 
            }
1053
 
        }
1054
 
 
1055
 
        return o;
1056
 
    },
1057
 
 
1058
 
    /**
1059
 
     * Add a requirement for one or more module
1060
 
     * @method require
1061
 
     * @param what {string[] | string*} the modules to load
1062
 
     */
1063
 
    require: function(what) {
1064
 
        var a = (typeof what === "string") ? arguments : what;
1065
 
        this.dirty = true;
1066
 
        Y.mix(this.required, YArray.hash(a));
1067
 
    },
1068
 
 
1069
 
    /**
1070
 
     * Returns an object containing properties for all modules required
1071
 
     * in order to load the requested module
1072
 
     * @method getRequires
1073
 
     * @param mod The module definition from moduleInfo
1074
 
     */
1075
 
    getRequires: function(mod) {
1076
 
        if (!mod || mod._parsed) {
1077
 
            return NO_REQUIREMENTS;
1078
 
        }
1079
 
 
1080
 
        var i, m, j, add, packName, lang,
1081
 
            name = mod.name, cond, go,
1082
 
            adddef = ON_PAGE[name] && ON_PAGE[name].details,
1083
 
            d      = [], 
1084
 
            r, old_mod,
1085
 
            o, skinmod, skindef,
1086
 
            intl   = mod.lang || mod.intl,
1087
 
            info   = this.moduleInfo,
1088
 
            hash   = {};
1089
 
 
1090
 
        // pattern match leaves module stub that needs to be filled out
1091
 
        if (mod.temp && adddef) {
1092
 
 
1093
 
            old_mod = mod;
1094
 
 
1095
 
            mod = this.addModule(adddef, name);
1096
 
            mod.group = old_mod.group;
1097
 
            mod.pkg = old_mod.pkg;
1098
 
            delete mod.expanded;
1099
 
            // console.log('TEMP MOD: ' + name + ', ' + mod.requires);
1100
 
            // console.log(Y.dump(mod));
1101
 
        }
1102
 
 
1103
 
        // if (!this.dirty && mod.expanded && (!mod.langCache || mod.langCache == this.lang)) {
1104
 
        if (mod.expanded && (!mod.langCache || mod.langCache == this.lang)) {
1105
 
            // Y.log('already expanded ' + name + ', ' + mod.expanded);
1106
 
            return mod.expanded;
1107
 
        }
1108
 
 
1109
 
        r      = mod.requires;
1110
 
        o      = mod.optional; 
1111
 
 
1112
 
        // Y.log("getRequires: " + name + " (dirty:" + this.dirty + ", expanded:" + mod.expanded + ")");
1113
 
 
1114
 
        mod._parsed = true;
1115
 
 
1116
 
        // Create skin modules
1117
 
        if (mod.skinnable) {
1118
 
            skindef = this.skin.overrides;
1119
 
            if (skindef && skindef[name]) {
1120
 
                for (i=0; i<skindef[name].length; i++) {
1121
 
                    skinmod = this._addSkin(skindef[name][i], name);
1122
 
                    d.push(skinmod);
1123
 
                }
1124
 
            } else {
1125
 
                skinmod = this._addSkin(this.skin.defaultSkin, name);
1126
 
                d.push(skinmod);
1127
 
            }
1128
 
        }
1129
 
 
1130
 
        for (i=0; i<r.length; i++) {
1131
 
            // Y.log(name + ' requiring ' + r[i]);
1132
 
            if (!hash[r[i]]) {
1133
 
                d.push(r[i]);
1134
 
                hash[r[i]] = true;
1135
 
                m = this.getModule(r[i]);
1136
 
                if (m) {
1137
 
                    add = this.getRequires(m);
1138
 
                    intl = intl || (m.expanded_map && (INTL in m.expanded_map));
1139
 
                    for (j=0; j<add.length; j++) {
1140
 
                        d.push(add[j]);
1141
 
                    }
1142
 
                }
1143
 
            }
1144
 
        }
1145
 
 
1146
 
        // get the requirements from superseded modules, if any
1147
 
        r=mod.supersedes;
1148
 
        if (r) {
1149
 
            for (i=0; i<r.length; i++) {
1150
 
                if (!hash[r[i]]) {
1151
 
 
1152
 
                    // if this module has submodules, the requirements list is
1153
 
                    // expanded to include the submodules.  This is so we can
1154
 
                    // prevent dups when a submodule is already loaded and the
1155
 
                    // parent is requested.
1156
 
                    if (mod.submodules) {
1157
 
                        d.push(r[i]); 
1158
 
                    }
1159
 
 
1160
 
                    hash[r[i]] = true;
1161
 
                    m = this.getModule(r[i]);
1162
 
 
1163
 
                    if (m) {
1164
 
                        add = this.getRequires(m);
1165
 
                        intl = intl || (m.expanded_map && (INTL in m.expanded_map));
1166
 
                        for (j=0; j<add.length; j++) {
1167
 
                            d.push(add[j]);
1168
 
                        }
1169
 
                    }
1170
 
                }
1171
 
            }
1172
 
        }
1173
 
 
1174
 
        if (o && this.loadOptional) {
1175
 
            for (i=0; i<o.length; i++) {
1176
 
                if (!hash[o[i]]) {
1177
 
                    d.push(o[i]);
1178
 
                    hash[o[i]] = true;
1179
 
                    m = info[o[i]];
1180
 
                    if (m) {
1181
 
                        add = this.getRequires(m);
1182
 
                        intl = intl || (m.expanded_map && (INTL in m.expanded_map));
1183
 
                        for (j=0; j<add.length; j++) {
1184
 
                            d.push(add[j]);
1185
 
                        }
1186
 
                    }
1187
 
                }
1188
 
            }
1189
 
        }
1190
 
 
1191
 
        cond = this.conditions[name];
1192
 
 
1193
 
        if (cond) {
1194
 
            oeach(cond, function(def, condmod) {
1195
 
 
1196
 
                if (!hash[condmod]) {
1197
 
                    go = def && ((def.ua && Y.UA[def.ua]) || 
1198
 
                                 (def.test && def.test(Y, r)));
1199
 
                    if (go) {
1200
 
                        hash[condmod] = true;
1201
 
                        d.push(condmod);
1202
 
                        m = this.getModule(condmod);
1203
 
                        if (m) {
1204
 
                            add = this.getRequires(m);
1205
 
                            for (j=0; j<add.length; j++) {
1206
 
                                d.push(add[j]);
1207
 
                            }
1208
 
                        }
1209
 
                    }
1210
 
                }
1211
 
            }, this);
1212
 
        }
1213
 
 
1214
 
        mod._parsed = false;
1215
 
 
1216
 
        if (intl) {
1217
 
 
1218
 
            if (mod.lang && !mod.langPack && Y.Intl) {
1219
 
                lang = Y.Intl.lookupBestLang(this.lang || ROOT_LANG, mod.lang);
1220
 
// Y.log('Best lang: ' + lang + ', this.lang: ' + this.lang + ', mod.lang: ' + mod.lang);
1221
 
                mod.langCache = this.lang;
1222
 
                packName = this.getLangPackName(lang, name);
1223
 
                if (packName) {
1224
 
                    d.unshift(packName);
1225
 
                }
1226
 
            }
1227
 
 
1228
 
            d.unshift(INTL);
1229
 
        }
1230
 
 
1231
 
        mod.expanded_map = YArray.hash(d);
1232
 
 
1233
 
        mod.expanded = YObject.keys(mod.expanded_map);
1234
 
 
1235
 
        return mod.expanded;
1236
 
    },
1237
 
 
1238
 
 
1239
 
    /**
1240
 
     * Returns a hash of module names the supplied module satisfies.
1241
 
     * @method getProvides
1242
 
     * @param name {string} The name of the module
1243
 
     * @return what this module provides
1244
 
     */
1245
 
    getProvides: function(name) {
1246
 
        var m = this.getModule(name), o, s;
1247
 
            // supmap = this.provides;
1248
 
 
1249
 
        if (!m) {
1250
 
            return NOT_FOUND;
1251
 
        }
1252
 
 
1253
 
        if (m && !m.provides) {
1254
 
            o = {};
1255
 
            s = m.supersedes;
1256
 
 
1257
 
            if (s) {
1258
 
                YArray.each(s, function(v) {
1259
 
                    Y.mix(o, this.getProvides(v));
1260
 
                }, this);
1261
 
            }
1262
 
 
1263
 
            o[name] = true;
1264
 
            m.provides = o;
1265
 
 
1266
 
        }
1267
 
 
1268
 
        return m.provides;
1269
 
    },
1270
 
 
1271
 
    /**
1272
 
     * Calculates the dependency tree, the result is stored in the sorted 
1273
 
     * property
1274
 
     * @method calculate
1275
 
     * @param o optional options object
1276
 
     * @param type optional argument to prune modules 
1277
 
     */
1278
 
 
1279
 
    calculate: function(o, type) {
1280
 
        if (o || type || this.dirty) {
1281
 
 
1282
 
            if (o) {
1283
 
                this._config(o);
1284
 
            }
1285
 
 
1286
 
            if (!this._init) {
1287
 
                this._setup();
1288
 
            }
1289
 
 
1290
 
            this._explode();
1291
 
            if (this.allowRollup) {
1292
 
                this._rollup();
1293
 
            }
1294
 
            this._reduce();
1295
 
            this._sort();
1296
 
        }
1297
 
    },
1298
 
 
1299
 
    _addLangPack: function(lang, m, packName) {
1300
 
        var name     = m.name, 
1301
 
            packPath,
1302
 
            existing = this.moduleInfo[packName];
1303
 
 
1304
 
        if (!existing) {
1305
 
 
1306
 
            packPath = _path((m.pkg || name), packName, JS, true);
1307
 
 
1308
 
            this.addModule({ path:       packPath,
1309
 
                             intl:       true,
1310
 
                             langPack:   true,
1311
 
                             ext:        m.ext,
1312
 
                             group:      m.group,
1313
 
                             supersedes: []       }, packName, true);
1314
 
 
1315
 
            if (lang) {
1316
 
                Y.Env.lang = Y.Env.lang || {};
1317
 
                Y.Env.lang[lang] = Y.Env.lang[lang] || {};
1318
 
                Y.Env.lang[lang][name] = true;
1319
 
            }
1320
 
        }
1321
 
 
1322
 
        return this.moduleInfo[packName];
1323
 
    },
1324
 
 
1325
 
    /**
1326
 
     * Investigates the current YUI configuration on the page.  By default,
1327
 
     * modules already detected will not be loaded again unless a force
1328
 
     * option is encountered.  Called by calculate()
1329
 
     * @method _setup
1330
 
     * @private
1331
 
     */
1332
 
    _setup: function() {
1333
 
        var info = this.moduleInfo, name, i, j, m, l, 
1334
 
            packName;
1335
 
 
1336
 
        for (name in info) {
1337
 
            if (info.hasOwnProperty(name)) {
1338
 
                m = info[name];
1339
 
                if (m) {
1340
 
 
1341
 
                    // remove dups
1342
 
                    m.requires = YObject.keys(YArray.hash(m.requires));
1343
 
 
1344
 
                    // Create lang pack modules
1345
 
                    if (m.lang && m.lang.length) {
1346
 
                        // Setup root package if the module has lang defined, 
1347
 
                        // it needs to provide a root language pack
1348
 
                        packName = this.getLangPackName(ROOT_LANG, name);
1349
 
                        this._addLangPack(null, m, packName);
1350
 
                    }
1351
 
 
1352
 
                }
1353
 
            }
1354
 
        }
1355
 
 
1356
 
        //l = Y.merge(this.inserted);
1357
 
        l = {};
1358
 
 
1359
 
        // available modules
1360
 
        if (!this.ignoreRegistered) {
1361
 
            Y.mix(l, GLOBAL_ENV.mods);
1362
 
        }
1363
 
        
1364
 
        // add the ignore list to the list of loaded packages
1365
 
        if (this.ignore) {
1366
 
            Y.mix(l, YArray.hash(this.ignore));
1367
 
        }
1368
 
 
1369
 
        // expand the list to include superseded modules
1370
 
        for (j in l) {
1371
 
            if (l.hasOwnProperty(j)) {
1372
 
                Y.mix(l, this.getProvides(j));
1373
 
            }
1374
 
        }
1375
 
 
1376
 
        // remove modules on the force list from the loaded list
1377
 
        if (this.force) {
1378
 
            for (i=0; i<this.force.length; i++) {
1379
 
                if (this.force[i] in l) {
1380
 
                    delete l[this.force[i]];
1381
 
                }
1382
 
            }
1383
 
        }
1384
 
 
1385
 
        Y.mix(this.loaded, l);
1386
 
 
1387
 
        this._init = true;
1388
 
    },
1389
 
    
1390
 
    /**
1391
 
     * Builds a module name for a language pack
1392
 
     * @function getLangPackName
1393
 
     * @param lang {string} the language code
1394
 
     * @param mname {string} the module to build it for
1395
 
     * @return {string} the language pack module name
1396
 
     */
1397
 
    getLangPackName: function(lang, mname) {
1398
 
        return ('lang/' + mname + ((lang) ? '_' + lang : ''));
1399
 
    },
1400
 
 
1401
 
    /**
1402
 
     * Inspects the required modules list looking for additional 
1403
 
     * dependencies.  Expands the required list to include all 
1404
 
     * required modules.  Called by calculate()
1405
 
     * @method _explode
1406
 
     * @private
1407
 
     */
1408
 
    _explode: function() {
1409
 
        var r = this.required, m, reqs, done = {},
1410
 
            self = this;
1411
 
 
1412
 
        // the setup phase is over, all modules have been created
1413
 
        self.dirty = false;
1414
 
 
1415
 
        oeach(r, function(v, name) {
1416
 
            if (!done[name]) {
1417
 
                done[name] = true;
1418
 
                m = self.getModule(name);
1419
 
                if (m) {
1420
 
                    var expound = m.expound;
1421
 
 
1422
 
                    if (expound) {
1423
 
                        r[expound] = self.getModule(expound);
1424
 
                        reqs = self.getRequires(r[expound]);
1425
 
                        Y.mix(r, YArray.hash(reqs));
1426
 
                    }
1427
 
 
1428
 
                    reqs = self.getRequires(m);
1429
 
                    Y.mix(r, YArray.hash(reqs));
1430
 
 
1431
 
                    // sups = m.supersedes;
1432
 
 
1433
 
                    // if (sups) {
1434
 
                    //     YArray.each(sups, function(sup) {
1435
 
                    //         if (sup in self.loaded) {
1436
 
                    //             delete r[name];
1437
 
                    //         }
1438
 
                    //         // if (sup in self.conditions) {
1439
 
                    //         r[sup] = true;
1440
 
                    //         //}
1441
 
                    //     });
1442
 
                    // }
1443
 
 
1444
 
                    // remove the definition for a rollup with
1445
 
                    // submodules -- getRequires() includes the
1446
 
                    // submodules.  Removing the parent makes
1447
 
                    // it possible to prevent submodule duplication
1448
 
                    // if the parent is requested after a submodule
1449
 
                    // has been loaded.
1450
 
                    // if (m.submodules) {
1451
 
                    //     delete r[name];
1452
 
                    // }
1453
 
                }
1454
 
            }
1455
 
        });
1456
 
 
1457
 
        // Y.log('After explode: ' + YObject.keys(r));
1458
 
    },
1459
 
 
1460
 
    getModule: function(mname) {
1461
 
        //TODO: Remove name check - it's a quick hack to fix pattern WIP
1462
 
        if (!mname) {
1463
 
            return null;
1464
 
        }
1465
 
 
1466
 
        var p, found, pname, 
1467
 
            m = this.moduleInfo[mname], 
1468
 
            patterns = this.patterns;
1469
 
 
1470
 
        // check the patterns library to see if we should automatically add
1471
 
        // the module with defaults
1472
 
        if (!m) {
1473
 
           // Y.log('testing patterns ' + YObject.keys(patterns));
1474
 
            for (pname in patterns) {
1475
 
                if (patterns.hasOwnProperty(pname)) {
1476
 
                    // Y.log('testing pattern ' + i);
1477
 
                    p = patterns[pname];
1478
 
 
1479
 
                    // use the metadata supplied for the pattern
1480
 
                    // as the module definition.
1481
 
                    if (mname.indexOf(pname) > -1) {
1482
 
                        found = p;
1483
 
                        break;
1484
 
                    }
1485
 
                }
1486
 
            }
1487
 
 
1488
 
            if (found) {
1489
 
                if (p.action) {
1490
 
                    // Y.log('executing pattern action: ' + pname);
1491
 
                    p.action.call(this, mname, pname);
1492
 
                } else {
1493
 
Y.log('Undefined module: ' + mname + ', matched a pattern: ' + pname, 'info', 'loader');
1494
 
                    // ext true or false?
1495
 
                    m = this.addModule(Y.merge(found), mname);
1496
 
                    m.temp = true;
1497
 
                }
1498
 
            }
1499
 
        }
1500
 
 
1501
 
        return m;
1502
 
    },
1503
 
 
1504
 
    // impl in rollup submodule
1505
 
    _rollup: function() { },
1506
 
 
1507
 
    /**
1508
 
     * Remove superceded modules and loaded modules.  Called by
1509
 
     * calculate() after we have the mega list of all dependencies
1510
 
     * @method _reduce
1511
 
     * @private
1512
 
     */
1513
 
    _reduce: function(r) {
1514
 
 
1515
 
        r = r || this.required;
1516
 
 
1517
 
        var i, j, s, m, type = this.loadType;
1518
 
        for (i in r) {
1519
 
            if (r.hasOwnProperty(i)) {
1520
 
                m = this.getModule(i);
1521
 
                // remove if already loaded
1522
 
                if (((this.loaded[i] || ON_PAGE[i]) && !this.forceMap[i] && !this.ignoreRegistered) || (type && m && m.type != type)) { 
1523
 
                    delete r[i];
1524
 
                } 
1525
 
                // remove anything this module supersedes
1526
 
                s = m && m.supersedes;
1527
 
                if (s) {
1528
 
                    for (j=0; j<s.length; j++) {
1529
 
                        if (s[j] in r) {
1530
 
                            delete r[s[j]];
1531
 
                        }
1532
 
                    }
1533
 
                }
1534
 
            }
1535
 
        }
1536
 
        // Y.log('required now: ' + YObject.keys(r));
1537
 
        
1538
 
        return r;
1539
 
    },
1540
 
 
1541
 
    _finish: function(msg, success) {
1542
 
        Y.log('loader finishing: ' + msg + ', ' + Y.id + ', ' + this.data, "info", "loader");
1543
 
 
1544
 
        _queue.running = false;
1545
 
 
1546
 
        var onEnd = this.onEnd;
1547
 
        if (onEnd) {
1548
 
            onEnd.call(this.context, {
1549
 
                msg: msg,
1550
 
                data: this.data,
1551
 
                success: success
1552
 
            });
1553
 
        }
1554
 
        this._continue();
1555
 
    },
1556
 
 
1557
 
    _onSuccess: function() {
1558
 
        // Y.log('loader _onSuccess, skipping: ' + Y.Object.keys(this.skipped), "info", "loader");
1559
 
        var skipped = Y.merge(this.skipped), fn;
1560
 
 
1561
 
        oeach(skipped, function(k) {
1562
 
            delete this.inserted[k];
1563
 
        }, this);
1564
 
 
1565
 
        this.skipped = {};
1566
 
 
1567
 
        // Y.mix(this.loaded, this.inserted);
1568
 
        oeach(this.inserted, function(v, k) {
1569
 
            Y.mix(this.loaded, this.getProvides(k));
1570
 
        }, this);
1571
 
 
1572
 
        fn = this.onSuccess;
1573
 
        if (fn) {
1574
 
            fn.call(this.context, {
1575
 
                msg: 'success',
1576
 
                data: this.data,
1577
 
                success: true,
1578
 
                skipped: skipped
1579
 
            });
1580
 
        }
1581
 
        this._finish('success', true);
1582
 
    },
1583
 
 
1584
 
    _onFailure: function(o) {
1585
 
        Y.log('load error: ' + o.msg + ', ' + Y.id, "error", "loader");
1586
 
        var f = this.onFailure, msg = 'failure: ' + o.msg;
1587
 
        if (f) {
1588
 
            f.call(this.context, {
1589
 
                msg: msg,
1590
 
                data: this.data,
1591
 
                success: false
1592
 
            });
1593
 
        }
1594
 
        this._finish(msg, false);
1595
 
    },
1596
 
 
1597
 
    _onTimeout: function() {
1598
 
        Y.log('loader timeout: ' + Y.id, "error", "loader");
1599
 
        var f = this.onTimeout;
1600
 
        if (f) {
1601
 
            f.call(this.context, {
1602
 
                msg: 'timeout',
1603
 
                data: this.data,
1604
 
                success: false
1605
 
            });
1606
 
        }
1607
 
        this._finish('timeout', false);
1608
 
    },
1609
 
 
1610
 
    
1611
 
    /**
1612
 
     * Sorts the dependency tree.  The last step of calculate()
1613
 
     * @method _sort
1614
 
     * @private
1615
 
     */
1616
 
    _sort: function() {
1617
 
 
1618
 
 
1619
 
        // create an indexed list
1620
 
        var s = YObject.keys(this.required), 
1621
 
            // loaded = this.loaded,
1622
 
            done = {},
1623
 
            p=0, l, a, b, j, k, moved, doneKey;
1624
 
 
1625
 
 
1626
 
        // keep going until we make a pass without moving anything
1627
 
        for (;;) {
1628
 
           
1629
 
            l     = s.length; 
1630
 
            moved = false;
1631
 
 
1632
 
            // start the loop after items that are already sorted
1633
 
            for (j=p; j<l; j++) {
1634
 
 
1635
 
                // check the next module on the list to see if its
1636
 
                // dependencies have been met
1637
 
                a = s[j];
1638
 
 
1639
 
                // check everything below current item and move if we
1640
 
                // find a requirement for the current item
1641
 
                for (k=j+1; k<l; k++) {
1642
 
                    doneKey = a + s[k];
1643
 
 
1644
 
                    if (!done[doneKey] && this._requires(a, s[k])) {
1645
 
 
1646
 
                        // extract the dependency so we can move it up
1647
 
                        b = s.splice(k, 1);
1648
 
 
1649
 
                        // insert the dependency above the item that 
1650
 
                        // requires it
1651
 
                        s.splice(j, 0, b[0]);
1652
 
 
1653
 
                        // only swap two dependencies once to short circut
1654
 
                        // circular dependencies
1655
 
                        done[doneKey] = true;
1656
 
 
1657
 
                        // keep working 
1658
 
                        moved = true;
1659
 
 
1660
 
                        break;
1661
 
                    }
1662
 
                }
1663
 
 
1664
 
                // jump out of loop if we moved something
1665
 
                if (moved) {
1666
 
                    break;
1667
 
                // this item is sorted, move our pointer and keep going
1668
 
                } else {
1669
 
                    p++;
1670
 
                }
1671
 
            }
1672
 
 
1673
 
            // when we make it here and moved is false, we are 
1674
 
            // finished sorting
1675
 
            if (!moved) {
1676
 
                break;
1677
 
            }
1678
 
 
1679
 
        }
1680
 
 
1681
 
        this.sorted = s;
1682
 
 
1683
 
    },
1684
 
 
1685
 
    _insert: function(source, o, type) {
1686
 
 
1687
 
        // Y.log('private _insert() ' + (type || '') + ', ' + Y.id, "info", "loader");
1688
 
 
1689
 
        // restore the state at the time of the request
1690
 
        if (source) {
1691
 
            this._config(source);
1692
 
        }
1693
 
 
1694
 
        // build the dependency list
1695
 
        this.calculate(o); // don't include type so we can process CSS and script in
1696
 
                           // one pass when the type is not specified.
1697
 
        this.loadType = type;
1698
 
 
1699
 
        if (!type) {
1700
 
 
1701
 
            var self = this;
1702
 
 
1703
 
            // Y.log("trying to load css first");
1704
 
            this._internalCallback = function() {
1705
 
 
1706
 
                var f = self.onCSS, n, p, sib;
1707
 
 
1708
 
                // IE hack for style overrides that are not being applied
1709
 
                if (this.insertBefore && Y.UA.ie) {
1710
 
                    n = Y.config.doc.getElementById(this.insertBefore);
1711
 
                    p = n.parentNode;
1712
 
                    sib = n.nextSibling;
1713
 
                    p.removeChild(n);
1714
 
                    if (sib) {
1715
 
                        p.insertBefore(n, sib);
1716
 
                    } else {
1717
 
                        p.appendChild(n);
1718
 
                    }
1719
 
                }
1720
 
 
1721
 
                if (f) {
1722
 
                    f.call(self.context, Y);
1723
 
                }
1724
 
                self._internalCallback = null;
1725
 
 
1726
 
                self._insert(null, null, JS);
1727
 
            };
1728
 
 
1729
 
            this._insert(null, null, CSS);
1730
 
 
1731
 
            return;
1732
 
        }
1733
 
 
1734
 
        // set a flag to indicate the load has started
1735
 
        this._loading = true;
1736
 
 
1737
 
        // flag to indicate we are done with the combo service
1738
 
        // and any additional files will need to be loaded
1739
 
        // individually
1740
 
        this._combineComplete = {};
1741
 
 
1742
 
        // start the load
1743
 
        this.loadNext();
1744
 
 
1745
 
    },
1746
 
 
1747
 
    // Once a loader operation is completely finished, process
1748
 
    // any additional queued items.
1749
 
    _continue: function() {
1750
 
        if (!(_queue.running) && _queue.size() > 0) {
1751
 
            _queue.running = true;
1752
 
            _queue.next()();
1753
 
        }
1754
 
    },
1755
 
 
1756
 
    /**
1757
 
     * inserts the requested modules and their dependencies.  
1758
 
     * <code>type</code> can be "js" or "css".  Both script and 
1759
 
     * css are inserted if type is not provided.
1760
 
     * @method insert
1761
 
     * @param o optional options object
1762
 
     * @param type {string} the type of dependency to insert
1763
 
     */
1764
 
    insert: function(o, type) {
1765
 
        // Y.log('public insert() ' + (type || '') + ', ' + Y.Object.keys(this.required), "info", "loader");
1766
 
        var self = this, copy = Y.merge(this, true);
1767
 
        delete copy.require;
1768
 
        delete copy.dirty;
1769
 
        _queue.add(function() {
1770
 
            self._insert(copy, o, type);
1771
 
        });
1772
 
        this._continue();
1773
 
    },
1774
 
 
1775
 
    /**
1776
 
     * Executed every time a module is loaded, and if we are in a load
1777
 
     * cycle, we attempt to load the next script.  Public so that it
1778
 
     * is possible to call this if using a method other than
1779
 
     * Y.register to determine when scripts are fully loaded
1780
 
     * @method loadNext
1781
 
     * @param mname {string} optional the name of the module that has
1782
 
     * been loaded (which is usually why it is time to load the next
1783
 
     * one)
1784
 
     */
1785
 
    loadNext: function(mname) {
1786
 
        // It is possible that this function is executed due to something
1787
 
        // else one the page loading a YUI module.  Only react when we
1788
 
        // are actively loading something
1789
 
        if (!this._loading) {
1790
 
            return;
1791
 
        }
1792
 
 
1793
 
        var s, len, i, m, url, fn, msg, attr, group, groupName, j, frag, 
1794
 
            comboSource, comboSources, mods, combining, urls, comboBase,
1795
 
            // provided,
1796
 
            type          = this.loadType, 
1797
 
            self          = this,
1798
 
            handleSuccess = function(o) {
1799
 
                                self.loadNext(o.data);
1800
 
                            },
1801
 
            handleCombo   = function(o) {
1802
 
                                self._combineComplete[type] = true;
1803
 
                                var i, len = combining.length;
1804
 
 
1805
 
                                for (i=0; i<len; i++) {
1806
 
                                    // self.loaded[combining[i]]   = true;
1807
 
                                    self.inserted[combining[i]] = true;
1808
 
 
1809
 
                                    // provided = this.getProvides(combining[i]);
1810
 
 
1811
 
                                    // Y.mix(self.loaded, provided);
1812
 
                                    // Y.mix(self.inserted, provided);
1813
 
                                }
1814
 
 
1815
 
                                handleSuccess(o);
1816
 
                            };
1817
 
 
1818
 
        if (this.combine && (!this._combineComplete[type])) {
1819
 
 
1820
 
            combining = [];
1821
 
 
1822
 
            this._combining = combining; 
1823
 
            s = this.sorted;
1824
 
            len = s.length;
1825
 
 
1826
 
            // the default combo base
1827
 
            comboBase = this.comboBase;
1828
 
 
1829
 
            url = comboBase;
1830
 
            urls = [];
1831
 
 
1832
 
            comboSources = {};
1833
 
 
1834
 
            for (i=0; i<len; i++) {
1835
 
                comboSource = comboBase;
1836
 
                m = this.getModule(s[i]);
1837
 
                groupName = m && m.group;
1838
 
                if (groupName) {
1839
 
 
1840
 
                    group = this.groups[groupName];
1841
 
 
1842
 
                    if (!group.combine) {
1843
 
                        m.combine = false;
1844
 
                        continue;
1845
 
                    }
1846
 
                    m.combine = true;
1847
 
                    if (group.comboBase) {
1848
 
                        comboSource = group.comboBase;
1849
 
                    }
1850
 
 
1851
 
                    if (group.root) {
1852
 
                        m.root = group.root;
1853
 
                    }
1854
 
 
1855
 
                }
1856
 
 
1857
 
                comboSources[comboSource] = comboSources[comboSource] || [];
1858
 
                comboSources[comboSource].push(m);
1859
 
            }
1860
 
 
1861
 
            for (j in comboSources) {
1862
 
                if (comboSources.hasOwnProperty(j)) {
1863
 
                    url = j;
1864
 
                    mods = comboSources[j];
1865
 
                    len = mods.length;
1866
 
 
1867
 
                    for (i=0; i<len; i++) {
1868
 
                        // m = this.getModule(s[i]);
1869
 
                        m = mods[i];
1870
 
 
1871
 
                        // Do not try to combine non-yui JS unless combo def is found
1872
 
                        if (m && (m.type === type) && (m.combine || !m.ext)) {
1873
 
 
1874
 
                            frag = (m.root || this.root) + m.path;
1875
 
 
1876
 
                            if ((url !== j) && (i < (len - 1)) && ((frag.length + url.length) > this.maxURLLength)) {
1877
 
                                urls.push(this._filter(url));
1878
 
                                url = j;
1879
 
                            }
1880
 
 
1881
 
                            url += frag;
1882
 
                            if (i < (len - 1)) {
1883
 
                                url += '&';
1884
 
                            }
1885
 
 
1886
 
                            combining.push(m.name);
1887
 
                        }
1888
 
 
1889
 
                    }
1890
 
 
1891
 
                    if (combining.length && (url != j)) {
1892
 
                        urls.push(this._filter(url));
1893
 
                    }
1894
 
                }
1895
 
            }
1896
 
 
1897
 
            if (combining.length) {
1898
 
 
1899
 
Y.log('Attempting to use combo: ' + combining, "info", "loader");
1900
 
 
1901
 
                // if (m.type === CSS) {
1902
 
                if (type === CSS) {
1903
 
                    fn = Y.Get.css;
1904
 
                    attr = this.cssAttributes;
1905
 
                } else {
1906
 
                    fn = Y.Get.script;
1907
 
                    attr = this.jsAttributes;
1908
 
                }
1909
 
 
1910
 
                fn(urls, {
1911
 
                    data:         this._loading,
1912
 
                    onSuccess:    handleCombo,
1913
 
                    onFailure:    this._onFailure,
1914
 
                    onTimeout:    this._onTimeout,
1915
 
                    insertBefore: this.insertBefore,
1916
 
                    charset:      this.charset,
1917
 
                    attributes:   attr,
1918
 
                    timeout:      this.timeout,
1919
 
                    autopurge:    false,
1920
 
                    context:      this
1921
 
                });
1922
 
 
1923
 
                return;
1924
 
 
1925
 
            } else {
1926
 
                this._combineComplete[type] = true;
1927
 
            }
1928
 
        }
1929
 
 
1930
 
        if (mname) {
1931
 
 
1932
 
            // if the module that was just loaded isn't what we were expecting,
1933
 
            // continue to wait
1934
 
            if (mname !== this._loading) {
1935
 
                return;
1936
 
            }
1937
 
 
1938
 
// Y.log("loadNext executing, just loaded " + mname + ", " + Y.id, "info", "loader");
1939
 
 
1940
 
            // The global handler that is called when each module is loaded
1941
 
            // will pass that module name to this function.  Storing this
1942
 
            // data to avoid loading the same module multiple times
1943
 
            // centralize this in the callback
1944
 
            this.inserted[mname] = true;
1945
 
            // this.loaded[mname] = true;
1946
 
 
1947
 
            // provided = this.getProvides(mname);
1948
 
            // Y.mix(this.loaded, provided);
1949
 
            // Y.mix(this.inserted, provided);
1950
 
 
1951
 
            if (this.onProgress) {
1952
 
                this.onProgress.call(this.context, {
1953
 
                        name: mname,
1954
 
                        data: this.data
1955
 
                    });
1956
 
            }
1957
 
        }
1958
 
 
1959
 
        s   = this.sorted;
1960
 
        len = s.length;
1961
 
 
1962
 
        for (i=0; i<len; i=i+1) {
1963
 
            // this.inserted keeps track of what the loader has loaded.
1964
 
            // move on if this item is done.
1965
 
            if (s[i] in this.inserted) {
1966
 
                continue;
1967
 
            }
1968
 
 
1969
 
            // Because rollups will cause multiple load notifications
1970
 
            // from Y, loadNext may be called multiple times for
1971
 
            // the same module when loading a rollup.  We can safely
1972
 
            // skip the subsequent requests
1973
 
            if (s[i] === this._loading) {
1974
 
                Y.log("still loading " + s[i] + ", waiting", "info", "loader");
1975
 
                return;
1976
 
            }
1977
 
 
1978
 
            // log("inserting " + s[i]);
1979
 
            m = this.getModule(s[i]);
1980
 
 
1981
 
            if (!m) {
1982
 
                msg = "Undefined module " + s[i] + " skipped";
1983
 
                Y.log(msg, 'warn', 'loader');
1984
 
                // this.inserted[s[i]] = true;
1985
 
                this.skipped[s[i]]  = true;
1986
 
                continue;
1987
 
 
1988
 
            }
1989
 
 
1990
 
            group = (m.group && this.groups[m.group]) || NOT_FOUND;
1991
 
 
1992
 
            // The load type is stored to offer the possibility to load
1993
 
            // the css separately from the script.
1994
 
            if (!type || type === m.type) {
1995
 
                this._loading = s[i];
1996
 
                Y.log("attempting to load " + s[i] + ", " + this.base, "info", "loader");
1997
 
 
1998
 
                if (m.type === CSS) {
1999
 
                    fn = Y.Get.css;
2000
 
                    attr = this.cssAttributes;
2001
 
                } else {
2002
 
                    fn = Y.Get.script;
2003
 
                    attr = this.jsAttributes;
2004
 
                }
2005
 
 
2006
 
                url = (m.fullpath) ? this._filter(m.fullpath, s[i]) : this._url(m.path, s[i], group.base || m.base);
2007
 
 
2008
 
                fn(url, {
2009
 
                    data:         s[i],
2010
 
                    onSuccess:    handleSuccess,
2011
 
                    insertBefore: this.insertBefore,
2012
 
                    charset:      this.charset,
2013
 
                    attributes:   attr,
2014
 
                    onFailure:    this._onFailure,
2015
 
                    onTimeout:    this._onTimeout,
2016
 
                    timeout:      this.timeout,
2017
 
                    autopurge:    false,
2018
 
                    context:      self 
2019
 
                });
2020
 
 
2021
 
                return;
2022
 
            }
2023
 
        }
2024
 
 
2025
 
        // we are finished
2026
 
        this._loading = null;
2027
 
 
2028
 
        fn = this._internalCallback;
2029
 
 
2030
 
        // internal callback for loading css first
2031
 
        if (fn) {
2032
 
            // Y.log('loader internal');
2033
 
            this._internalCallback = null;
2034
 
            fn.call(this);
2035
 
        } else {
2036
 
            // Y.log('loader complete');
2037
 
            this._onSuccess();
2038
 
        }
2039
 
    },
2040
 
 
2041
 
    /**
2042
 
     * Apply filter defined for this instance to a url/path
2043
 
     * method _filter
2044
 
     * @param u {string} the string to filter
2045
 
     * @param name {string} the name of the module, if we are processing
2046
 
     * a single module as opposed to a combined url
2047
 
     * @return {string} the filtered string
2048
 
     * @private
2049
 
     */
2050
 
    _filter: function(u, name) {
2051
 
        var f = this.filter, 
2052
 
            hasFilter = name && (name in this.filters),
2053
 
            modFilter = hasFilter && this.filters[name];
2054
 
 
2055
 
        if (u) {
2056
 
            if (hasFilter) {
2057
 
                f = (L.isString(modFilter)) ? 
2058
 
                    this.FILTER_DEFS[modFilter.toUpperCase()] || null : 
2059
 
                    modFilter;
2060
 
            }
2061
 
            if (f) {
2062
 
                u = u.replace(new RegExp(f.searchExp, 'g'), f.replaceStr);
2063
 
            }
2064
 
        }
2065
 
 
2066
 
        return u;
2067
 
    },
2068
 
 
2069
 
    /**
2070
 
     * Generates the full url for a module
2071
 
     * method _url
2072
 
     * @param path {string} the path fragment
2073
 
     * @return {string} the full url
2074
 
     * @private
2075
 
     */
2076
 
    _url: function(path, name, base) {
2077
 
        return this._filter((base || this.base || "") + path, name);
2078
 
    }
2079
 
};
2080
 
 
2081
 
 
2082
 
 
2083
 
}, '3.2.0' ,{requires:['get']});