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