~ubuntu-branches/ubuntu/raring/maas/raring-updates

« back to all changes in this revision

Viewing changes to src/maasserver/static/jslibs/yui/3.4.1/build/loader-base/loader-base-debug.js

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez
  • Date: 2012-07-03 17:42:37 UTC
  • mfrom: (1.1.13)
  • Revision ID: package-import@ubuntu.com-20120703174237-p8l0keuuznfg721k
Tags: 0.1+bzr709+dfsg-0ubuntu1
* New Upstream release
* debian/control:
  - Depends on python-celery, python-tempita, libjs-yui3-{full,min},
    libjs-raphael
* debian/maas.install:
  - Install apiclient, celeryconfig.py, maas-import-pxe-files, preseeds_v2.
  - Update to install various files from chroot, rather tha manually copy
    them from the source.
* debian/maas.links: symlink celeryconfig.py
* debian/maas.maas-celery.upstart: Add job.
* debian/rules:
  - Install celery upstart job.
  - Do not install jslibs as packages are now used.
  - Drop copying of maas_local_settings_sample.py as source now ships
    a maas_local_settings.py
* debian/patches:
  - 04-maas-http-fix.patch: Drop. Merged upstream.
  - 01-fix-database-settings.patch: Refreshed.
  - 99_enums_js.patch: Added until creation of enum.js / build process
    is fixed.
* debian/maas.postinst: Update bzr version to correctly handle upgrades.

Show diffs side-by-side

added added

removed removed

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