| /* |
| Copyright (c) 2008, Yahoo! Inc. All rights reserved. |
| Code licensed under the BSD License: |
| http://developer.yahoo.net/yui/license.txt |
| version: 2.6.0 |
| */ |
| /** |
| * The YAHOO object is the single global object used by YUI Library. It |
| * contains utility function for setting up namespaces, inheritance, and |
| * logging. YAHOO.util, YAHOO.widget, and YAHOO.example are namespaces |
| * created automatically for and used by the library. |
| * @module yahoo |
| * @title YAHOO Global |
| */ |
| |
| /** |
| * YAHOO_config is not included as part of the library. Instead it is an |
| * object that can be defined by the implementer immediately before |
| * including the YUI library. The properties included in this object |
| * will be used to configure global properties needed as soon as the |
| * library begins to load. |
| * @class YAHOO_config |
| * @static |
| */ |
| |
| /** |
| * A reference to a function that will be executed every time a YAHOO module |
| * is loaded. As parameter, this function will receive the version |
| * information for the module. See <a href="YAHOO.env.html#getVersion"> |
| * YAHOO.env.getVersion</a> for the description of the version data structure. |
| * @property listener |
| * @type Function |
| * @static |
| * @default undefined |
| */ |
| |
| /** |
| * Set to true if the library will be dynamically loaded after window.onload. |
| * Defaults to false |
| * @property injecting |
| * @type boolean |
| * @static |
| * @default undefined |
| */ |
| |
| /** |
| * Instructs the yuiloader component to dynamically load yui components and |
| * their dependencies. See the yuiloader documentation for more information |
| * about dynamic loading |
| * @property load |
| * @static |
| * @default undefined |
| * @see yuiloader |
| */ |
| |
| /** |
| * Forces the use of the supplied locale where applicable in the library |
| * @property locale |
| * @type string |
| * @static |
| * @default undefined |
| */ |
| |
| if (typeof YAHOO == "undefined" || !YAHOO) { |
| /** |
| * The YAHOO global namespace object. If YAHOO is already defined, the |
| * existing YAHOO object will not be overwritten so that defined |
| * namespaces are preserved. |
| * @class YAHOO |
| * @static |
| */ |
| var YAHOO = {}; |
| } |
| |
| /** |
| * Returns the namespace specified and creates it if it doesn't exist |
| * <pre> |
| * YAHOO.namespace("property.package"); |
| * YAHOO.namespace("YAHOO.property.package"); |
| * </pre> |
| * Either of the above would create YAHOO.property, then |
| * YAHOO.property.package |
| * |
| * Be careful when naming packages. Reserved words may work in some browsers |
| * and not others. For instance, the following will fail in Safari: |
| * <pre> |
| * YAHOO.namespace("really.long.nested.namespace"); |
| * </pre> |
| * This fails because "long" is a future reserved word in ECMAScript |
| * |
| * @method namespace |
| * @static |
| * @param {String*} arguments 1-n namespaces to create |
| * @return {Object} A reference to the last namespace object created |
| */ |
| YAHOO.namespace = function() { |
| var a=arguments, o=null, i, j, d; |
| for (i=0; i<a.length; i=i+1) { |
| d=a[i].split("."); |
| o=YAHOO; |
| |
| // YAHOO is implied, so it is ignored if it is included |
| for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; j=j+1) { |
| o[d[j]]=o[d[j]] || {}; |
| o=o[d[j]]; |
| } |
| } |
| |
| return o; |
| }; |
| |
| /** |
| * Uses YAHOO.widget.Logger to output a log message, if the widget is |
| * available. |
| * |
| * @method log |
| * @static |
| * @param {String} msg The message to log. |
| * @param {String} cat The log category for the message. Default |
| * categories are "info", "warn", "error", time". |
| * Custom categories can be used as well. (opt) |
| * @param {String} src The source of the the message (opt) |
| * @return {Boolean} True if the log operation was successful. |
| */ |
| YAHOO.log = function(msg, cat, src) { |
| var l=YAHOO.widget.Logger; |
| if(l && l.log) { |
| return l.log(msg, cat, src); |
| } else { |
| return false; |
| } |
| }; |
| |
| /** |
| * Registers a module with the YAHOO object |
| * @method register |
| * @static |
| * @param {String} name the name of the module (event, slider, etc) |
| * @param {Function} mainClass a reference to class in the module. This |
| * class will be tagged with the version info |
| * so that it will be possible to identify the |
| * version that is in use when multiple versions |
| * have loaded |
| * @param {Object} data metadata object for the module. Currently it |
| * is expected to contain a "version" property |
| * and a "build" property at minimum. |
| */ |
| YAHOO.register = function(name, mainClass, data) { |
| var mods = YAHOO.env.modules; |
| if (!mods[name]) { |
| mods[name] = { versions:[], builds:[] }; |
| } |
| var m=mods[name],v=data.version,b=data.build,ls=YAHOO.env.listeners; |
| m.name = name; |
| m.version = v; |
| m.build = b; |
| m.versions.push(v); |
| m.builds.push(b); |
| m.mainClass = mainClass; |
| // fire the module load listeners |
| for (var i=0;i<ls.length;i=i+1) { |
| ls[i](m); |
| } |
| // label the main class |
| if (mainClass) { |
| mainClass.VERSION = v; |
| mainClass.BUILD = b; |
| } else { |
| YAHOO.log("mainClass is undefined for module " + name, "warn"); |
| } |
| }; |
| |
| /** |
| * YAHOO.env is used to keep track of what is known about the YUI library and |
| * the browsing environment |
| * @class YAHOO.env |
| * @static |
| */ |
| YAHOO.env = YAHOO.env || { |
| |
| /** |
| * Keeps the version info for all YUI modules that have reported themselves |
| * @property modules |
| * @type Object[] |
| */ |
| modules: [], |
| |
| /** |
| * List of functions that should be executed every time a YUI module |
| * reports itself. |
| * @property listeners |
| * @type Function[] |
| */ |
| listeners: [] |
| }; |
| |
| /** |
| * Returns the version data for the specified module: |
| * <dl> |
| * <dt>name:</dt> <dd>The name of the module</dd> |
| * <dt>version:</dt> <dd>The version in use</dd> |
| * <dt>build:</dt> <dd>The build number in use</dd> |
| * <dt>versions:</dt> <dd>All versions that were registered</dd> |
| * <dt>builds:</dt> <dd>All builds that were registered.</dd> |
| * <dt>mainClass:</dt> <dd>An object that was was stamped with the |
| * current version and build. If |
| * mainClass.VERSION != version or mainClass.BUILD != build, |
| * multiple versions of pieces of the library have been |
| * loaded, potentially causing issues.</dd> |
| * </dl> |
| * |
| * @method getVersion |
| * @static |
| * @param {String} name the name of the module (event, slider, etc) |
| * @return {Object} The version info |
| */ |
| YAHOO.env.getVersion = function(name) { |
| return YAHOO.env.modules[name] || null; |
| }; |
| |
| /** |
| * Do not fork for a browser if it can be avoided. Use feature detection when |
| * you can. Use the user agent as a last resort. YAHOO.env.ua stores a version |
| * number for the browser engine, 0 otherwise. This value may or may not map |
| * to the version number of the browser using the engine. The value is |
| * presented as a float so that it can easily be used for boolean evaluation |
| * as well as for looking for a particular range of versions. Because of this, |
| * some of the granularity of the version info may be lost (e.g., Gecko 1.8.0.9 |
| * reports 1.8). |
| * @class YAHOO.env.ua |
| * @static |
| */ |
| YAHOO.env.ua = function() { |
| var o={ |
| |
| /** |
| * Internet Explorer version number or 0. Example: 6 |
| * @property ie |
| * @type float |
| */ |
| ie:0, |
| |
| /** |
| * Opera version number or 0. Example: 9.2 |
| * @property opera |
| * @type float |
| */ |
| opera:0, |
| |
| /** |
| * Gecko engine revision number. Will evaluate to 1 if Gecko |
| * is detected but the revision could not be found. Other browsers |
| * will be 0. Example: 1.8 |
| * <pre> |
| * Firefox 1.0.0.4: 1.7.8 <-- Reports 1.7 |
| * Firefox 1.5.0.9: 1.8.0.9 <-- Reports 1.8 |
| * Firefox 2.0.0.3: 1.8.1.3 <-- Reports 1.8 |
| * Firefox 3 alpha: 1.9a4 <-- Reports 1.9 |
| * </pre> |
| * @property gecko |
| * @type float |
| */ |
| gecko:0, |
| |
| /** |
| * AppleWebKit version. KHTML browsers that are not WebKit browsers |
| * will evaluate to 1, other browsers 0. Example: 418.9.1 |
| * <pre> |
| * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the |
| * latest available for Mac OSX 10.3. |
| * Safari 2.0.2: 416 <-- hasOwnProperty introduced |
| * Safari 2.0.4: 418 <-- preventDefault fixed |
| * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run |
| * different versions of webkit |
| * Safari 2.0.4 (419.3): 419 <-- Tiger installations that have been |
| * updated, but not updated |
| * to the latest patch. |
| * Webkit 212 nightly: 522+ <-- Safari 3.0 precursor (with native SVG |
| * and many major issues fixed). |
| * 3.x yahoo.com, flickr:422 <-- Safari 3.x hacks the user agent |
| * string when hitting yahoo.com and |
| * flickr.com. |
| * Safari 3.0.4 (523.12):523.12 <-- First Tiger release - automatic update |
| * from 2.x via the 10.4.11 OS patch |
| * Webkit nightly 1/2008:525+ <-- Supports DOMContentLoaded event. |
| * yahoo.com user agent hack removed. |
| * |
| * </pre> |
| * http://developer.apple.com/internet/safari/uamatrix.html |
| * @property webkit |
| * @type float |
| */ |
| webkit: 0, |
| |
| /** |
| * The mobile property will be set to a string containing any relevant |
| * user agent information when a modern mobile browser is detected. |
| * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series |
| * devices with the WebKit-based browser, and Opera Mini. |
| * @property mobile |
| * @type string |
| */ |
| mobile: null, |
| |
| /** |
| * Adobe AIR version number or 0. Only populated if webkit is detected. |
| * Example: 1.0 |
| * @property air |
| * @type float |
| */ |
| air: 0 |
| |
| }; |
| |
| var ua=navigator.userAgent, m; |
| |
| // Modern KHTML browsers should qualify as Safari X-Grade |
| if ((/KHTML/).test(ua)) { |
| o.webkit=1; |
| } |
| // Modern WebKit browsers are at least X-Grade |
| m=ua.match(/AppleWebKit\/([^\s]*)/); |
| if (m&&m[1]) { |
| o.webkit=parseFloat(m[1]); |
| |
| // Mobile browser check |
| if (/ Mobile\//.test(ua)) { |
| o.mobile = "Apple"; // iPhone or iPod Touch |
| } else { |
| m=ua.match(/NokiaN[^\/]*/); |
| if (m) { |
| o.mobile = m[0]; // Nokia N-series, ex: NokiaN95 |
| } |
| } |
| |
| m=ua.match(/AdobeAIR\/([^\s]*)/); |
| if (m) { |
| o.air = m[0]; // Adobe AIR 1.0 or better |
| } |
| |
| } |
| |
| if (!o.webkit) { // not webkit |
| // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr) |
| m=ua.match(/Opera[\s\/]([^\s]*)/); |
| if (m&&m[1]) { |
| o.opera=parseFloat(m[1]); |
| m=ua.match(/Opera Mini[^;]*/); |
| if (m) { |
| o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316 |
| } |
| } else { // not opera or webkit |
| m=ua.match(/MSIE\s([^;]*)/); |
| if (m&&m[1]) { |
| o.ie=parseFloat(m[1]); |
| } else { // not opera, webkit, or ie |
| m=ua.match(/Gecko\/([^\s]*)/); |
| if (m) { |
| o.gecko=1; // Gecko detected, look for revision |
| m=ua.match(/rv:([^\s\)]*)/); |
| if (m&&m[1]) { |
| o.gecko=parseFloat(m[1]); |
| } |
| } |
| } |
| } |
| } |
| |
| return o; |
| }(); |
| |
| /* |
| * Initializes the global by creating the default namespaces and applying |
| * any new configuration information that is detected. This is the setup |
| * for env. |
| * @method init |
| * @static |
| * @private |
| */ |
| (function() { |
| YAHOO.namespace("util", "widget", "example"); |
| if ("undefined" !== typeof YAHOO_config) { |
| var l=YAHOO_config.listener,ls=YAHOO.env.listeners,unique=true,i; |
| if (l) { |
| // if YAHOO is loaded multiple times we need to check to see if |
| // this is a new config object. If it is, add the new component |
| // load listener to the stack |
| for (i=0;i<ls.length;i=i+1) { |
| if (ls[i]==l) { |
| unique=false; |
| break; |
| } |
| } |
| if (unique) { |
| ls.push(l); |
| } |
| } |
| } |
| })(); |
| /** |
| * Provides the language utilites and extensions used by the library |
| * @class YAHOO.lang |
| */ |
| YAHOO.lang = YAHOO.lang || {}; |
| |
| (function() { |
| |
| var L = YAHOO.lang, |
| |
| // ADD = ["toString", "valueOf", "hasOwnProperty"], |
| ADD = ["toString", "valueOf"], |
| |
| OB = { |
| |
| /** |
| * Determines whether or not the provided object is an array. |
| * Testing typeof/instanceof/constructor of arrays across frame |
| * boundaries isn't possible in Safari unless you have a reference |
| * to the other frame to test against its Array prototype. To |
| * handle this case, we test well-known array properties instead. |
| * properties. |
| * @method isArray |
| * @param {any} o The object being testing |
| * @return {boolean} the result |
| */ |
| isArray: function(o) { |
| if (o) { |
| return L.isNumber(o.length) && L.isFunction(o.splice); |
| } |
| return false; |
| }, |
| |
| /** |
| * Determines whether or not the provided object is a boolean |
| * @method isBoolean |
| * @param {any} o The object being testing |
| * @return {boolean} the result |
| */ |
| isBoolean: function(o) { |
| return typeof o === 'boolean'; |
| }, |
| |
| /** |
| * Determines whether or not the provided object is a function |
| * @method isFunction |
| * @param {any} o The object being testing |
| * @return {boolean} the result |
| */ |
| isFunction: function(o) { |
| return typeof o === 'function'; |
| }, |
| |
| /** |
| * Determines whether or not the provided object is null |
| * @method isNull |
| * @param {any} o The object being testing |
| * @return {boolean} the result |
| */ |
| isNull: function(o) { |
| return o === null; |
| }, |
| |
| /** |
| * Determines whether or not the provided object is a legal number |
| * @method isNumber |
| * @param {any} o The object being testing |
| * @return {boolean} the result |
| */ |
| isNumber: function(o) { |
| return typeof o === 'number' && isFinite(o); |
| }, |
| |
| /** |
| * Determines whether or not the provided object is of type object |
| * or function |
| * @method isObject |
| * @param {any} o The object being testing |
| * @return {boolean} the result |
| */ |
| isObject: function(o) { |
| return (o && (typeof o === 'object' || L.isFunction(o))) || false; |
| }, |
| |
| /** |
| * Determines whether or not the provided object is a string |
| * @method isString |
| * @param {any} o The object being testing |
| * @return {boolean} the result |
| */ |
| isString: function(o) { |
| return typeof o === 'string'; |
| }, |
| |
| /** |
| * Determines whether or not the provided object is undefined |
| * @method isUndefined |
| * @param {any} o The object being testing |
| * @return {boolean} the result |
| */ |
| isUndefined: function(o) { |
| return typeof o === 'undefined'; |
| }, |
| |
| |
| /** |
| * IE will not enumerate native functions in a derived object even if the |
| * function was overridden. This is a workaround for specific functions |
| * we care about on the Object prototype. |
| * @property _IEEnumFix |
| * @param {Function} r the object to receive the augmentation |
| * @param {Function} s the object that supplies the properties to augment |
| * @static |
| * @private |
| */ |
| _IEEnumFix: (YAHOO.env.ua.ie) ? function(r, s) { |
| for (var i=0;i<ADD.length;i=i+1) { |
| var fname=ADD[i],f=s[fname]; |
| if (L.isFunction(f) && f!=Object.prototype[fname]) { |
| r[fname]=f; |
| } |
| } |
| } : function(){}, |
| |
| /** |
| * Utility to set up the prototype, constructor and superclass properties to |
| * support an inheritance strategy that can chain constructors and methods. |
| * Static members will not be inherited. |
| * |
| * @method extend |
| * @static |
| * @param {Function} subc the object to modify |
| * @param {Function} superc the object to inherit |
| * @param {Object} overrides additional properties/methods to add to the |
| * subclass prototype. These will override the |
| * matching items obtained from the superclass |
| * if present. |
| */ |
| extend: function(subc, superc, overrides) { |
| if (!superc||!subc) { |
| throw new Error("extend failed, please check that " + |
| "all dependencies are included."); |
| } |
| var F = function() {}; |
| F.prototype=superc.prototype; |
| subc.prototype=new F(); |
| subc.prototype.constructor=subc; |
| subc.superclass=superc.prototype; |
| if (superc.prototype.constructor == Object.prototype.constructor) { |
| superc.prototype.constructor=superc; |
| } |
| |
| if (overrides) { |
| for (var i in overrides) { |
| if (L.hasOwnProperty(overrides, i)) { |
| subc.prototype[i]=overrides[i]; |
| } |
| } |
| |
| L._IEEnumFix(subc.prototype, overrides); |
| } |
| }, |
| |
| /** |
| * Applies all properties in the supplier to the receiver if the |
| * receiver does not have these properties yet. Optionally, one or |
| * more methods/properties can be specified (as additional |
| * parameters). This option will overwrite the property if receiver |
| * has it already. If true is passed as the third parameter, all |
| * properties will be applied and _will_ overwrite properties in |
| * the receiver. |
| * |
| * @method augmentObject |
| * @static |
| * @since 2.3.0 |
| * @param {Function} r the object to receive the augmentation |
| * @param {Function} s the object that supplies the properties to augment |
| * @param {String*|boolean} arguments zero or more properties methods |
| * to augment the receiver with. If none specified, everything |
| * in the supplier will be used unless it would |
| * overwrite an existing property in the receiver. If true |
| * is specified as the third parameter, all properties will |
| * be applied and will overwrite an existing property in |
| * the receiver |
| */ |
| augmentObject: function(r, s) { |
| if (!s||!r) { |
| throw new Error("Absorb failed, verify dependencies."); |
| } |
| var a=arguments, i, p, override=a[2]; |
| if (override && override!==true) { // only absorb the specified properties |
| for (i=2; i<a.length; i=i+1) { |
| r[a[i]] = s[a[i]]; |
| } |
| } else { // take everything, overwriting only if the third parameter is true |
| for (p in s) { |
| if (override || !(p in r)) { |
| r[p] = s[p]; |
| } |
| } |
| |
| L._IEEnumFix(r, s); |
| } |
| }, |
| |
| /** |
| * Same as YAHOO.lang.augmentObject, except it only applies prototype properties |
| * @see YAHOO.lang.augmentObject |
| * @method augmentProto |
| * @static |
| * @param {Function} r the object to receive the augmentation |
| * @param {Function} s the object that supplies the properties to augment |
| * @param {String*|boolean} arguments zero or more properties methods |
| * to augment the receiver with. If none specified, everything |
| * in the supplier will be used unless it would overwrite an existing |
| * property in the receiver. if true is specified as the third |
| * parameter, all properties will be applied and will overwrite an |
| * existing property in the receiver |
| */ |
| augmentProto: function(r, s) { |
| if (!s||!r) { |
| throw new Error("Augment failed, verify dependencies."); |
| } |
| //var a=[].concat(arguments); |
| var a=[r.prototype,s.prototype]; |
| for (var i=2;i<arguments.length;i=i+1) { |
| a.push(arguments[i]); |
| } |
| L.augmentObject.apply(this, a); |
| }, |
| |
| |
| /** |
| * Returns a simple string representation of the object or array. |
| * Other types of objects will be returned unprocessed. Arrays |
| * are expected to be indexed. Use object notation for |
| * associative arrays. |
| * @method dump |
| * @since 2.3.0 |
| * @param o {Object} The object to dump |
| * @param d {int} How deep to recurse child objects, default 3 |
| * @return {String} the dump result |
| */ |
| dump: function(o, d) { |
| var i,len,s=[],OBJ="{...}",FUN="f(){...}", |
| COMMA=', ', ARROW=' => '; |
| |
| // Cast non-objects to string |
| // Skip dates because the std toString is what we want |
| // Skip HTMLElement-like objects because trying to dump |
| // an element will cause an unhandled exception in FF 2.x |
| if (!L.isObject(o)) { |
| return o + ""; |
| } else if (o instanceof Date || ("nodeType" in o && "tagName" in o)) { |
| return o; |
| } else if (L.isFunction(o)) { |
| return FUN; |
| } |
| |
| // dig into child objects the depth specifed. Default 3 |
| d = (L.isNumber(d)) ? d : 3; |
| |
| // arrays [1, 2, 3] |
| if (L.isArray(o)) { |
| s.push("["); |
| for (i=0,len=o.length;i<len;i=i+1) { |
| if (L.isObject(o[i])) { |
| s.push((d > 0) ? L.dump(o[i], d-1) : OBJ); |
| } else { |
| s.push(o[i]); |
| } |
| s.push(COMMA); |
| } |
| if (s.length > 1) { |
| s.pop(); |
| } |
| s.push("]"); |
| // objects {k1 => v1, k2 => v2} |
| } else { |
| s.push("{"); |
| for (i in o) { |
| if (L.hasOwnProperty(o, i)) { |
| s.push(i + ARROW); |
| if (L.isObject(o[i])) { |
| s.push((d > 0) ? L.dump(o[i], d-1) : OBJ); |
| } else { |
| s.push(o[i]); |
| } |
| s.push(COMMA); |
| } |
| } |
| if (s.length > 1) { |
| s.pop(); |
| } |
| s.push("}"); |
| } |
| |
| return s.join(""); |
| }, |
| |
| /** |
| * Does variable substitution on a string. It scans through the string |
| * looking for expressions enclosed in { } braces. If an expression |
| * is found, it is used a key on the object. If there is a space in |
| * the key, the first word is used for the key and the rest is provided |
| * to an optional function to be used to programatically determine the |
| * value (the extra information might be used for this decision). If |
| * the value for the key in the object, or what is returned from the |
| * function has a string value, number value, or object value, it is |
| * substituted for the bracket expression and it repeats. If this |
| * value is an object, it uses the Object's toString() if this has |
| * been overridden, otherwise it does a shallow dump of the key/value |
| * pairs. |
| * @method substitute |
| * @since 2.3.0 |
| * @param s {String} The string that will be modified. |
| * @param o {Object} An object containing the replacement values |
| * @param f {Function} An optional function that can be used to |
| * process each match. It receives the key, |
| * value, and any extra metadata included with |
| * the key inside of the braces. |
| * @return {String} the substituted string |
| */ |
| substitute: function (s, o, f) { |
| var i, j, k, key, v, meta, saved=[], token, |
| DUMP='dump', SPACE=' ', LBRACE='{', RBRACE='}'; |
| |
| |
| for (;;) { |
| i = s.lastIndexOf(LBRACE); |
| if (i < 0) { |
| break; |
| } |
| j = s.indexOf(RBRACE, i); |
| if (i + 1 >= j) { |
| break; |
| } |
| |
| //Extract key and meta info |
| token = s.substring(i + 1, j); |
| key = token; |
| meta = null; |
| k = key.indexOf(SPACE); |
| if (k > -1) { |
| meta = key.substring(k + 1); |
| key = key.substring(0, k); |
| } |
| |
| // lookup the value |
| v = o[key]; |
| |
| // if a substitution function was provided, execute it |
| if (f) { |
| v = f(key, v, meta); |
| } |
| |
| if (L.isObject(v)) { |
| if (L.isArray(v)) { |
| v = L.dump(v, parseInt(meta, 10)); |
| } else { |
| meta = meta || ""; |
| |
| // look for the keyword 'dump', if found force obj dump |
| var dump = meta.indexOf(DUMP); |
| if (dump > -1) { |
| meta = meta.substring(4); |
| } |
| |
| // use the toString if it is not the Object toString |
| // and the 'dump' meta info was not found |
| if (v.toString===Object.prototype.toString||dump>-1) { |
| v = L.dump(v, parseInt(meta, 10)); |
| } else { |
| v = v.toString(); |
| } |
| } |
| } else if (!L.isString(v) && !L.isNumber(v)) { |
| // This {block} has no replace string. Save it for later. |
| v = "~-" + saved.length + "-~"; |
| saved[saved.length] = token; |
| |
| // break; |
| } |
| |
| s = s.substring(0, i) + v + s.substring(j + 1); |
| |
| |
| } |
| |
| // restore saved {block}s |
| for (i=saved.length-1; i>=0; i=i-1) { |
| s = s.replace(new RegExp("~-" + i + "-~"), "{" + saved[i] + "}", "g"); |
| } |
| |
| return s; |
| }, |
| |
| |
| /** |
| * Returns a string without any leading or trailing whitespace. If |
| * the input is not a string, the input will be returned untouched. |
| * @method trim |
| * @since 2.3.0 |
| * @param s {string} the string to trim |
| * @return {string} the trimmed string |
| */ |
| trim: function(s){ |
| try { |
| return s.replace(/^\s+|\s+$/g, ""); |
| } catch(e) { |
| return s; |
| } |
| }, |
| |
| /** |
| * Returns a new object containing all of the properties of |
| * all the supplied objects. The properties from later objects |
| * will overwrite those in earlier objects. |
| * @method merge |
| * @since 2.3.0 |
| * @param arguments {Object*} the objects to merge |
| * @return the new merged object |
| */ |
| merge: function() { |
| var o={}, a=arguments; |
| for (var i=0, l=a.length; i<l; i=i+1) { |
| L.augmentObject(o, a[i], true); |
| } |
| return o; |
| }, |
| |
| /** |
| * Executes the supplied function in the context of the supplied |
| * object 'when' milliseconds later. Executes the function a |
| * single time unless periodic is set to true. |
| * @method later |
| * @since 2.4.0 |
| * @param when {int} the number of milliseconds to wait until the fn |
| * is executed |
| * @param o the context object |
| * @param fn {Function|String} the function to execute or the name of |
| * the method in the 'o' object to execute |
| * @param data [Array] data that is provided to the function. This accepts |
| * either a single item or an array. If an array is provided, the |
| * function is executed with one parameter for each array item. If |
| * you need to pass a single array parameter, it needs to be wrapped in |
| * an array [myarray] |
| * @param periodic {boolean} if true, executes continuously at supplied |
| * interval until canceled |
| * @return a timer object. Call the cancel() method on this object to |
| * stop the timer. |
| */ |
| later: function(when, o, fn, data, periodic) { |
| when = when || 0; |
| o = o || {}; |
| var m=fn, d=data, f, r; |
| |
| if (L.isString(fn)) { |
| m = o[fn]; |
| } |
| |
| if (!m) { |
| throw new TypeError("method undefined"); |
| } |
| |
| if (!L.isArray(d)) { |
| d = [data]; |
| } |
| |
| f = function() { |
| m.apply(o, d); |
| }; |
| |
| r = (periodic) ? setInterval(f, when) : setTimeout(f, when); |
| |
| return { |
| interval: periodic, |
| cancel: function() { |
| if (this.interval) { |
| clearInterval(r); |
| } else { |
| clearTimeout(r); |
| } |
| } |
| }; |
| }, |
| |
| /** |
| * A convenience method for detecting a legitimate non-null value. |
| * Returns false for null/undefined/NaN, true for other values, |
| * including 0/false/'' |
| * @method isValue |
| * @since 2.3.0 |
| * @param o {any} the item to test |
| * @return {boolean} true if it is not null/undefined/NaN || false |
| */ |
| isValue: function(o) { |
| // return (o || o === false || o === 0 || o === ''); // Infinity fails |
| return (L.isObject(o) || L.isString(o) || L.isNumber(o) || L.isBoolean(o)); |
| } |
| |
| }; |
| |
| /** |
| * Determines whether or not the property was added |
| * to the object instance. Returns false if the property is not present |
| * in the object, or was inherited from the prototype. |
| * This abstraction is provided to enable hasOwnProperty for Safari 1.3.x. |
| * There is a discrepancy between YAHOO.lang.hasOwnProperty and |
| * Object.prototype.hasOwnProperty when the property is a primitive added to |
| * both the instance AND prototype with the same value: |
| * <pre> |
| * var A = function() {}; |
| * A.prototype.foo = 'foo'; |
| * var a = new A(); |
| * a.foo = 'foo'; |
| * alert(a.hasOwnProperty('foo')); // true |
| * alert(YAHOO.lang.hasOwnProperty(a, 'foo')); // false when using fallback |
| * </pre> |
| * @method hasOwnProperty |
| * @param {any} o The object being testing |
| * @param prop {string} the name of the property to test |
| * @return {boolean} the result |
| */ |
| L.hasOwnProperty = (Object.prototype.hasOwnProperty) ? |
| function(o, prop) { |
| return o && o.hasOwnProperty(prop); |
| } : function(o, prop) { |
| return !L.isUndefined(o[prop]) && |
| o.constructor.prototype[prop] !== o[prop]; |
| }; |
| |
| // new lang wins |
| OB.augmentObject(L, OB, true); |
| |
| /* |
| * An alias for <a href="YAHOO.lang.html">YAHOO.lang</a> |
| * @class YAHOO.util.Lang |
| */ |
| YAHOO.util.Lang = L; |
| |
| /** |
| * Same as YAHOO.lang.augmentObject, except it only applies prototype |
| * properties. This is an alias for augmentProto. |
| * @see YAHOO.lang.augmentObject |
| * @method augment |
| * @static |
| * @param {Function} r the object to receive the augmentation |
| * @param {Function} s the object that supplies the properties to augment |
| * @param {String*|boolean} arguments zero or more properties methods to |
| * augment the receiver with. If none specified, everything |
| * in the supplier will be used unless it would |
| * overwrite an existing property in the receiver. if true |
| * is specified as the third parameter, all properties will |
| * be applied and will overwrite an existing property in |
| * the receiver |
| */ |
| L.augment = L.augmentProto; |
| |
| /** |
| * An alias for <a href="YAHOO.lang.html#augment">YAHOO.lang.augment</a> |
| * @for YAHOO |
| * @method augment |
| * @static |
| * @param {Function} r the object to receive the augmentation |
| * @param {Function} s the object that supplies the properties to augment |
| * @param {String*} arguments zero or more properties methods to |
| * augment the receiver with. If none specified, everything |
| * in the supplier will be used unless it would |
| * overwrite an existing property in the receiver |
| */ |
| YAHOO.augment = L.augmentProto; |
| |
| /** |
| * An alias for <a href="YAHOO.lang.html#extend">YAHOO.lang.extend</a> |
| * @method extend |
| * @static |
| * @param {Function} subc the object to modify |
| * @param {Function} superc the object to inherit |
| * @param {Object} overrides additional properties/methods to add to the |
| * subclass prototype. These will override the |
| * matching items obtained from the superclass if present. |
| */ |
| YAHOO.extend = L.extend; |
| |
| })(); |
| YAHOO.register("yahoo", YAHOO, {version: "2.6.0", build: "1321"}); |
| /** |
| * Provides a mechanism to fetch remote resources and |
| * insert them into a document |
| * @module get |
| * @requires yahoo |
| */ |
| |
| /** |
| * Fetches and inserts one or more script or link nodes into the document |
| * @namespace YAHOO.util |
| * @class YAHOO.util.Get |
| */ |
| YAHOO.util.Get = function() { |
| |
| /** |
| * hash of queues to manage multiple requests |
| * @property queues |
| * @private |
| */ |
| var queues={}, |
| |
| /** |
| * queue index used to generate transaction ids |
| * @property qidx |
| * @type int |
| * @private |
| */ |
| qidx=0, |
| |
| /** |
| * node index used to generate unique node ids |
| * @property nidx |
| * @type int |
| * @private |
| */ |
| nidx=0, |
| |
| // ridx=0, |
| |
| // sandboxFrame=null, |
| |
| /** |
| * interal property used to prevent multiple simultaneous purge |
| * processes |
| * @property purging |
| * @type boolean |
| * @private |
| */ |
| purging=false, |
| |
| ua=YAHOO.env.ua, |
| |
| lang=YAHOO.lang; |
| |
| /** |
| * Generates an HTML element, this is not appended to a document |
| * @method _node |
| * @param type {string} the type of element |
| * @param attr {string} the attributes |
| * @param win {Window} optional window to create the element in |
| * @return {HTMLElement} the generated node |
| * @private |
| */ |
| var _node = function(type, attr, win) { |
| var w = win || window, d=w.document, n=d.createElement(type); |
| |
| for (var i in attr) { |
| if (attr[i] && YAHOO.lang.hasOwnProperty(attr, i)) { |
| n.setAttribute(i, attr[i]); |
| } |
| } |
| |
| return n; |
| }; |
| |
| /** |
| * Generates a link node |
| * @method _linkNode |
| * @param url {string} the url for the css file |
| * @param win {Window} optional window to create the node in |
| * @return {HTMLElement} the generated node |
| * @private |
| */ |
| var _linkNode = function(url, win, charset) { |
| var c = charset || "utf-8"; |
| return _node("link", { |
| "id": "yui__dyn_" + (nidx++), |
| "type": "text/css", |
| "charset": c, |
| "rel": "stylesheet", |
| "href": url |
| }, win); |
| }; |
| |
| /** |
| * Generates a script node |
| * @method _scriptNode |
| * @param url {string} the url for the script file |
| * @param win {Window} optional window to create the node in |
| * @return {HTMLElement} the generated node |
| * @private |
| */ |
| var _scriptNode = function(url, win, charset) { |
| var c = charset || "utf-8"; |
| return _node("script", { |
| "id": "yui__dyn_" + (nidx++), |
| "type": "text/javascript", |
| "charset": c, |
| "src": url |
| }, win); |
| }; |
| |
| /** |
| * Returns the data payload for callback functions |
| * @method _returnData |
| * @private |
| */ |
| var _returnData = function(q, msg) { |
| return { |
| tId: q.tId, |
| win: q.win, |
| data: q.data, |
| nodes: q.nodes, |
| msg: msg, |
| purge: function() { |
| _purge(this.tId); |
| } |
| }; |
| }; |
| |
| var _get = function(nId, tId) { |
| var q = queues[tId], |
| n = (lang.isString(nId)) ? q.win.document.getElementById(nId) : nId; |
| if (!n) { |
| _fail(tId, "target node not found: " + nId); |
| } |
| |
| return n; |
| }; |
| |
| /* |
| * The request failed, execute fail handler with whatever |
| * was accomplished. There isn't a failure case at the |
| * moment unless you count aborted transactions |
| * @method _fail |
| * @param id {string} the id of the request |
| * @private |
| */ |
| var _fail = function(id, msg) { |
| var q = queues[id]; |
| // execute failure callback |
| if (q.onFailure) { |
| var sc=q.scope || q.win; |
| q.onFailure.call(sc, _returnData(q, msg)); |
| } |
| }; |
| |
| /** |
| * The request is complete, so executing the requester's callback |
| * @method _finish |
| * @param id {string} the id of the request |
| * @private |
| */ |
| var _finish = function(id) { |
| var q = queues[id]; |
| q.finished = true; |
| |
| if (q.aborted) { |
| var msg = "transaction " + id + " was aborted"; |
| _fail(id, msg); |
| return; |
| } |
| |
| // execute success callback |
| if (q.onSuccess) { |
| var sc=q.scope || q.win; |
| q.onSuccess.call(sc, _returnData(q)); |
| } |
| }; |
| |
| /** |
| * Timeout detected |
| * @method _timeout |
| * @param id {string} the id of the request |
| * @private |
| */ |
| var _timeout = function(id) { |
| var q = queues[id]; |
| if (q.onTimeout) { |
| var sc=q.context || q; |
| q.onTimeout.call(sc, _returnData(q)); |
| } |
| }; |
| |
| /** |
| * Loads the next item for a given request |
| * @method _next |
| * @param id {string} the id of the request |
| * @param loaded {string} the url that was just loaded, if any |
| * @private |
| */ |
| var _next = function(id, loaded) { |
| var q = queues[id]; |
| |
| if (q.timer) { |
| // Y.log('cancel timer'); |
| q.timer.cancel(); |
| } |
| |
| if (q.aborted) { |
| var msg = "transaction " + id + " was aborted"; |
| _fail(id, msg); |
| return; |
| } |
| |
| if (loaded) { |
| q.url.shift(); |
| if (q.varName) { |
| q.varName.shift(); |
| } |
| } else { |
| // This is the first pass: make sure the url is an array |
| q.url = (lang.isString(q.url)) ? [q.url] : q.url; |
| if (q.varName) { |
| q.varName = (lang.isString(q.varName)) ? [q.varName] : q.varName; |
| } |
| } |
| |
| var w=q.win, d=w.document, h=d.getElementsByTagName("head")[0], n; |
| |
| if (q.url.length === 0) { |
| // Safari 2.x workaround - There is no way to know when |
| // a script is ready in versions of Safari prior to 3.x. |
| // Adding an extra node reduces the problem, but doesn't |
| // eliminate it completely because the browser executes |
| // them asynchronously. |
| if (q.type === "script" && ua.webkit && ua.webkit < 420 && |
| !q.finalpass && !q.varName) { |
| // Add another script node. This does not guarantee that the |
| // scripts will execute in order, but it does appear to fix the |
| // problem on fast connections more effectively than using an |
| // arbitrary timeout. It is possible that the browser does |
| // block subsequent script execution in this case for a limited |
| // time. |
| var extra = _scriptNode(null, q.win, q.charset); |
| extra.innerHTML='YAHOO.util.Get._finalize("' + id + '");'; |
| q.nodes.push(extra); h.appendChild(extra); |
| |
| } else { |
| _finish(id); |
| } |
| |
| return; |
| } |
| |
| |
| var url = q.url[0]; |
| |
| // if the url is undefined, this is probably a trailing comma problem in IE |
| if (!url) { |
| q.url.shift(); |
| return _next(id); |
| } |
| |
| |
| if (q.timeout) { |
| // Y.log('create timer'); |
| q.timer = lang.later(q.timeout, q, _timeout, id); |
| } |
| |
| if (q.type === "script") { |
| n = _scriptNode(url, w, q.charset); |
| } else { |
| n = _linkNode(url, w, q.charset); |
| } |
| |
| // track this node's load progress |
| _track(q.type, n, id, url, w, q.url.length); |
| |
| // add the node to the queue so we can return it to the user supplied callback |
| q.nodes.push(n); |
| |
| // add it to the head or insert it before 'insertBefore' |
| if (q.insertBefore) { |
| var s = _get(q.insertBefore, id); |
| if (s) { |
| s.parentNode.insertBefore(n, s); |
| } |
| } else { |
| h.appendChild(n); |
| } |
| |
| |
| // FireFox does not support the onload event for link nodes, so there is |
| // no way to make the css requests synchronous. This means that the css |
| // rules in multiple files could be applied out of order in this browser |
| // if a later request returns before an earlier one. Safari too. |
| if ((ua.webkit || ua.gecko) && q.type === "css") { |
| _next(id, url); |
| } |
| }; |
| |
| /** |
| * Removes processed queues and corresponding nodes |
| * @method _autoPurge |
| * @private |
| */ |
| var _autoPurge = function() { |
| |
| if (purging) { |
| return; |
| } |
| |
| purging = true; |
| for (var i in queues) { |
| var q = queues[i]; |
| if (q.autopurge && q.finished) { |
| _purge(q.tId); |
| delete queues[i]; |
| } |
| } |
| |
| purging = false; |
| }; |
| |
| /** |
| * Removes the nodes for the specified queue |
| * @method _purge |
| * @private |
| */ |
| var _purge = function(tId) { |
| var q=queues[tId]; |
| if (q) { |
| var n=q.nodes, l=n.length, d=q.win.document, |
| h=d.getElementsByTagName("head")[0]; |
| |
| if (q.insertBefore) { |
| var s = _get(q.insertBefore, tId); |
| if (s) { |
| h = s.parentNode; |
| } |
| } |
| |
| for (var i=0; i<l; i=i+1) { |
| h.removeChild(n[i]); |
| } |
| |
| q.nodes = []; |
| } |
| }; |
| |
| /** |
| * Saves the state for the request and begins loading |
| * the requested urls |
| * @method queue |
| * @param type {string} the type of node to insert |
| * @param url {string} the url to load |
| * @param opts the hash of options for this request |
| * @private |
| */ |
| var _queue = function(type, url, opts) { |
| |
| var id = "q" + (qidx++); |
| opts = opts || {}; |
| |
| if (qidx % YAHOO.util.Get.PURGE_THRESH === 0) { |
| _autoPurge(); |
| } |
| |
| queues[id] = lang.merge(opts, { |
| tId: id, |
| type: type, |
| url: url, |
| finished: false, |
| aborted: false, |
| nodes: [] |
| }); |
| |
| var q = queues[id]; |
| q.win = q.win || window; |
| q.scope = q.scope || q.win; |
| q.autopurge = ("autopurge" in q) ? q.autopurge : |
| (type === "script") ? true : false; |
| |
| lang.later(0, q, _next, id); |
| |
| return { |
| tId: id |
| }; |
| }; |
| |
| /** |
| * Detects when a node has been loaded. In the case of |
| * script nodes, this does not guarantee that contained |
| * script is ready to use. |
| * @method _track |
| * @param type {string} the type of node to track |
| * @param n {HTMLElement} the node to track |
| * @param id {string} the id of the request |
| * @param url {string} the url that is being loaded |
| * @param win {Window} the targeted window |
| * @param qlength the number of remaining items in the queue, |
| * including this one |
| * @param trackfn {Function} function to execute when finished |
| * the default is _next |
| * @private |
| */ |
| var _track = function(type, n, id, url, win, qlength, trackfn) { |
| var f = trackfn || _next; |
| |
| // IE supports the readystatechange event for script and css nodes |
| if (ua.ie) { |
| n.onreadystatechange = function() { |
| var rs = this.readyState; |
| if ("loaded" === rs || "complete" === rs) { |
| n.onreadystatechange = null; |
| f(id, url); |
| } |
| }; |
| |
| // webkit prior to 3.x is problemmatic |
| } else if (ua.webkit) { |
| |
| if (type === "script") { |
| |
| // Safari 3.x supports the load event for script nodes (DOM2) |
| if (ua.webkit >= 420) { |
| |
| n.addEventListener("load", function() { |
| f(id, url); |
| }); |
| |
| // Nothing can be done with Safari < 3.x except to pause and hope |
| // for the best, particularly after last script is inserted. The |
| // scripts will always execute in the order they arrive, not |
| // necessarily the order in which they were inserted. To support |
| // script nodes with complete reliability in these browsers, script |
| // nodes either need to invoke a function in the window once they |
| // are loaded or the implementer needs to provide a well-known |
| // property that the utility can poll for. |
| } else { |
| // Poll for the existence of the named variable, if it |
| // was supplied. |
| var q = queues[id]; |
| if (q.varName) { |
| var freq=YAHOO.util.Get.POLL_FREQ; |
| q.maxattempts = YAHOO.util.Get.TIMEOUT/freq; |
| q.attempts = 0; |
| q._cache = q.varName[0].split("."); |
| q.timer = lang.later(freq, q, function(o) { |
| var a=this._cache, l=a.length, w=this.win, i; |
| for (i=0; i<l; i=i+1) { |
| w = w[a[i]]; |
| if (!w) { |
| // if we have exausted our attempts, give up |
| this.attempts++; |
| if (this.attempts++ > this.maxattempts) { |
| var msg = "Over retry limit, giving up"; |
| q.timer.cancel(); |
| _fail(id, msg); |
| } else { |
| } |
| return; |
| } |
| } |
| |
| |
| q.timer.cancel(); |
| f(id, url); |
| |
| }, null, true); |
| } else { |
| lang.later(YAHOO.util.Get.POLL_FREQ, null, f, [id, url]); |
| } |
| } |
| } |
| |
| // FireFox and Opera support onload (but not DOM2 in FF) handlers for |
| // script nodes. Opera, but not FF, supports the onload event for link |
| // nodes. |
| } else { |
| n.onload = function() { |
| f(id, url); |
| }; |
| } |
| }; |
| |
| return { |
| |
| /** |
| * The default poll freqency in ms, when needed |
| * @property POLL_FREQ |
| * @static |
| * @type int |
| * @default 10 |
| */ |
| POLL_FREQ: 10, |
| |
| /** |
| * The number of request required before an automatic purge. |
| * property PURGE_THRESH |
| * @static |
| * @type int |
| * @default 20 |
| */ |
| PURGE_THRESH: 20, |
| |
| /** |
| * The length time to poll for varName when loading a script in |
| * Safari 2.x before the transaction fails. |
| * property TIMEOUT |
| * @static |
| * @type int |
| * @default 2000 |
| */ |
| TIMEOUT: 2000, |
| |
| /** |
| * Called by the the helper for detecting script load in Safari |
| * @method _finalize |
| * @param id {string} the transaction id |
| * @private |
| */ |
| _finalize: function(id) { |
| lang.later(0, null, _finish, id); |
| }, |
| |
| /** |
| * Abort a transaction |
| * @method abort |
| * @param {string|object} either the tId or the object returned from |
| * script() or css() |
| */ |
| abort: function(o) { |
| var id = (lang.isString(o)) ? o : o.tId; |
| var q = queues[id]; |
| if (q) { |
| q.aborted = true; |
| } |
| }, |
| |
| /** |
| * Fetches and inserts one or more script nodes into the head |
| * of the current document or the document in a specified window. |
| * |
| * @method script |
| * @static |
| * @param url {string|string[]} the url or urls to the script(s) |
| * @param opts {object} Options: |
| * <dl> |
| * <dt>onSuccess</dt> |
| * <dd> |
| * callback to execute when the script(s) are finished loading |
| * The callback receives an object back with the following |
| * data: |
| * <dl> |
| * <dt>win</dt> |
| * <dd>the window the script(s) were inserted into</dd> |
| * <dt>data</dt> |
| * <dd>the data object passed in when the request was made</dd> |
| * <dt>nodes</dt> |
| * <dd>An array containing references to the nodes that were |
| * inserted</dd> |
| * <dt>purge</dt> |
| * <dd>A function that, when executed, will remove the nodes |
| * that were inserted</dd> |
| * <dt> |
| * </dl> |
| * </dd> |
| * <dt>onFailure</dt> |
| * <dd> |
| * callback to execute when the script load operation fails |
| * The callback receives an object back with the following |
| * data: |
| * <dl> |
| * <dt>win</dt> |
| * <dd>the window the script(s) were inserted into</dd> |
| * <dt>data</dt> |
| * <dd>the data object passed in when the request was made</dd> |
| * <dt>nodes</dt> |
| * <dd>An array containing references to the nodes that were |
| * inserted successfully</dd> |
| * <dt>purge</dt> |
| * <dd>A function that, when executed, will remove any nodes |
| * that were inserted</dd> |
| * <dt> |
| * </dl> |
| * </dd> |
| * <dt>onTimeout</dt> |
| * <dd> |
| * callback to execute when a timeout occurs. |
| * The callback receives an object back with the following |
| * data: |
| * <dl> |
| * <dt>win</dt> |
| * <dd>the window the script(s) were inserted into</dd> |
| * <dt>data</dt> |
| * <dd>the data object passed in when the request was made</dd> |
| * <dt>nodes</dt> |
| * <dd>An array containing references to the nodes that were |
| * inserted</dd> |
| * <dt>purge</dt> |
| * <dd>A function that, when executed, will remove the nodes |
| * that were inserted</dd> |
| * <dt> |
| * </dl> |
| * </dd> |
| * <dt>scope</dt> |
| * <dd>the execution context for the callbacks</dd> |
| * <dt>win</dt> |
| * <dd>a window other than the one the utility occupies</dd> |
| * <dt>autopurge</dt> |
| * <dd> |
| * setting to true will let the utilities cleanup routine purge |
| * the script once loaded |
| * </dd> |
| * <dt>data</dt> |
| * <dd> |
| * data that is supplied to the callback when the script(s) are |
| * loaded. |
| * </dd> |
| * <dt>varName</dt> |
| * <dd> |
| * variable that should be available when a script is finished |
| * loading. Used to help Safari 2.x and below with script load |
| * detection. The type of this property should match what was |
| * passed into the url parameter: if loading a single url, a |
| * string can be supplied. If loading multiple scripts, you |
| * must supply an array that contains the variable name for |
| * each script. |
| * </dd> |
| * <dt>insertBefore</dt> |
| * <dd>node or node id that will become the new node's nextSibling</dd> |
| * </dl> |
| * <dt>charset</dt> |
| * <dd>Node charset, default utf-8</dd> |
| * <dt>timeout</dt> |
| * <dd>Number of milliseconds to wait before aborting and firing the timeout event</dd> |
| * <pre> |
| * // assumes yahoo, dom, and event are already on the page |
| * YAHOO.util.Get.script( |
| * ["http://yui.yahooapis.com/2.3.1/build/dragdrop/dragdrop-min.js", |
| * "http://yui.yahooapis.com/2.3.1/build/animation/animation-min.js"], { |
| * onSuccess: function(o) { |
| * new YAHOO.util.DDProxy("dd1"); // also new o.reference("dd1"); would work |
| * this.log("won't cause error because YAHOO is the scope"); |
| * this.log(o.nodes.length === 2) // true |
| * // o.purge(); // optionally remove the script nodes immediately |
| * }, |
| * onFailure: function(o) { |
| * }, |
| * data: "foo", |
| * timeout: 10000, // 10 second timeout |
| * scope: YAHOO, |
| * // win: otherframe // target another window/frame |
| * autopurge: true // allow the utility to choose when to remove the nodes |
| * }); |
| * </pre> |
| * @return {tId: string} an object containing info about the transaction |
| */ |
| script: function(url, opts) { return _queue("script", url, opts); }, |
| |
| /** |
| * Fetches and inserts one or more css link nodes into the |
| * head of the current document or the document in a specified |
| * window. |
| * @method css |
| * @static |
| * @param url {string} the url or urls to the css file(s) |
| * @param opts Options: |
| * <dl> |
| * <dt>onSuccess</dt> |
| * <dd> |
| * callback to execute when the css file(s) are finished loading |
| * The callback receives an object back with the following |
| * data: |
| * <dl>win</dl> |
| * <dd>the window the link nodes(s) were inserted into</dd> |
| * <dt>data</dt> |
| * <dd>the data object passed in when the request was made</dd> |
| * <dt>nodes</dt> |
| * <dd>An array containing references to the nodes that were |
| * inserted</dd> |
| * <dt>purge</dt> |
| * <dd>A function that, when executed, will remove the nodes |
| * that were inserted</dd> |
| * <dt> |
| * </dl> |
| * </dd> |
| * <dt>scope</dt> |
| * <dd>the execution context for the callbacks</dd> |
| * <dt>win</dt> |
| * <dd>a window other than the one the utility occupies</dd> |
| * <dt>data</dt> |
| * <dd> |
| * data that is supplied to the callbacks when the nodes(s) are |
| * loaded. |
| * </dd> |
| * <dt>insertBefore</dt> |
| * <dd>node or node id that will become the new node's nextSibling</dd> |
| * <dt>charset</dt> |
| * <dd>Node charset, default utf-8</dd> |
| * </dl> |
| * <pre> |
| * YAHOO.util.Get.css("http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css"); |
| * </pre> |
| * <pre> |
| * YAHOO.util.Get.css(["http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css", |
| * </pre> |
| * @return {tId: string} an object containing info about the transaction |
| */ |
| css: function(url, opts) { |
| return _queue("css", url, opts); |
| } |
| }; |
| }(); |
| |
| YAHOO.register("get", YAHOO.util.Get, {version: "2.6.0", build: "1321"}); |
| /** |
| * Provides dynamic loading for the YUI library. It includes the dependency |
| * info for the library, and will automatically pull in dependencies for |
| * the modules requested. It supports rollup files (such as utilities.js |
| * and yahoo-dom-event.js), and will automatically use these when |
| * appropriate in order to minimize the number of http connections |
| * required to load all of the dependencies. |
| * |
| * @module yuiloader |
| * @namespace YAHOO.util |
| */ |
| |
| /** |
| * YUILoader provides dynamic loading for YUI. |
| * @class YAHOO.util.YUILoader |
| * @todo |
| * version management, automatic sandboxing |
| */ |
| (function() { |
| |
| var Y=YAHOO, util=Y.util, lang=Y.lang, env=Y.env, |
| PROV = "_provides", SUPER = "_supersedes", |
| REQ = "expanded", AFTER = "_after"; |
| |
| var YUI = { |
| |
| dupsAllowed: {'yahoo': true, 'get': true}, |
| |
| /* |
| * The library metadata for the current release The is the default |
| * value for YAHOO.util.YUILoader.moduleInfo |
| * @property YUIInfo |
| * @static |
| */ |
| info: { |
| |
| // 'root': '2.5.2/build/', |
| // 'base': 'http://yui.yahooapis.com/2.5.2/build/', |
| |
| 'root': '2.6.0/build/', |
| 'base': 'http://yui.yahooapis.com/2.6.0/build/', |
| |
| 'comboBase': 'http://yui.yahooapis.com/combo?', |
| |
| 'skin': { |
| 'defaultSkin': 'sam', |
| 'base': 'assets/skins/', |
| 'path': 'skin.css', |
| 'after': ['reset', 'fonts', 'grids', 'base'], |
| 'rollup': 3 |
| }, |
| |
| dupsAllowed: ['yahoo', 'get'], |
| |
| 'moduleInfo': { |
| |
| 'animation': { |
| 'type': 'js', |
| 'path': 'animation/animation-min.js', |
| 'requires': ['dom', 'event'] |
| }, |
| |
| 'autocomplete': { |
| 'type': 'js', |
| 'path': 'autocomplete/autocomplete-min.js', |
| 'requires': ['dom', 'event', 'datasource'], |
| 'optional': ['connection', 'animation'], |
| 'skinnable': true |
| }, |
| |
| 'base': { |
| 'type': 'css', |
| 'path': 'base/base-min.css', |
| 'after': ['reset', 'fonts', 'grids'] |
| }, |
| |
| 'button': { |
| 'type': 'js', |
| 'path': 'button/button-min.js', |
| 'requires': ['element'], |
| 'optional': ['menu'], |
| 'skinnable': true |
| }, |
| |
| 'calendar': { |
| 'type': 'js', |
| 'path': 'calendar/calendar-min.js', |
| 'requires': ['event', 'dom'], |
| 'skinnable': true |
| }, |
| |
| 'carousel': { |
| 'type': 'js', |
| 'path': 'carousel/carousel-beta-min.js', |
| 'requires': ['element'], |
| 'optional': ['animation'], |
| 'skinnable': true |
| }, |
| |
| 'charts': { |
| 'type': 'js', |
| 'path': 'charts/charts-experimental-min.js', |
| 'requires': ['element', 'json', 'datasource'] |
| }, |
| |
| 'colorpicker': { |
| 'type': 'js', |
| 'path': 'colorpicker/colorpicker-min.js', |
| 'requires': ['slider', 'element'], |
| 'optional': ['animation'], |
| 'skinnable': true |
| }, |
| |
| 'connection': { |
| 'type': 'js', |
| 'path': 'connection/connection-min.js', |
| 'requires': ['event'] |
| }, |
| |
| 'container': { |
| 'type': 'js', |
| 'path': 'container/container-min.js', |
| 'requires': ['dom', 'event'], |
| // button is also optional, but this creates a circular |
| // dependency when loadOptional is specified. button |
| // optionally includes menu, menu requires container. |
| 'optional': ['dragdrop', 'animation', 'connection'], |
| 'supersedes': ['containercore'], |
| 'skinnable': true |
| }, |
| |
| 'containercore': { |
| 'type': 'js', |
| 'path': 'container/container_core-min.js', |
| 'requires': ['dom', 'event'], |
| 'pkg': 'container' |
| }, |
| |
| 'cookie': { |
| 'type': 'js', |
| 'path': 'cookie/cookie-min.js', |
| 'requires': ['yahoo'] |
| }, |
| |
| 'datasource': { |
| 'type': 'js', |
| 'path': 'datasource/datasource-min.js', |
| 'requires': ['event'], |
| 'optional': ['connection'] |
| }, |
| |
| 'datatable': { |
| 'type': 'js', |
| 'path': 'datatable/datatable-min.js', |
| 'requires': ['element', 'datasource'], |
| 'optional': ['calendar', 'dragdrop', 'paginator'], |
| 'skinnable': true |
| }, |
| |
| 'dom': { |
| 'type': 'js', |
| 'path': 'dom/dom-min.js', |
| 'requires': ['yahoo'] |
| }, |
| |
| 'dragdrop': { |
| 'type': 'js', |
| 'path': 'dragdrop/dragdrop-min.js', |
| 'requires': ['dom', 'event'] |
| }, |
| |
| 'editor': { |
| 'type': 'js', |
| 'path': 'editor/editor-min.js', |
| 'requires': ['menu', 'element', 'button'], |
| 'optional': ['animation', 'dragdrop'], |
| 'supersedes': ['simpleeditor'], |
| 'skinnable': true |
| }, |
| |
| 'element': { |
| 'type': 'js', |
| 'path': 'element/element-beta-min.js', |
| 'requires': ['dom', 'event'] |
| }, |
| |
| 'event': { |
| 'type': 'js', |
| 'path': 'event/event-min.js', |
| 'requires': ['yahoo'] |
| }, |
| |
| 'fonts': { |
| 'type': 'css', |
| 'path': 'fonts/fonts-min.css' |
| }, |
| |
| 'get': { |
| 'type': 'js', |
| 'path': 'get/get-min.js', |
| 'requires': ['yahoo'] |
| }, |
| |
| 'grids': { |
| 'type': 'css', |
| 'path': 'grids/grids-min.css', |
| 'requires': ['fonts'], |
| 'optional': ['reset'] |
| }, |
| |
| 'history': { |
| 'type': 'js', |
| 'path': 'history/history-min.js', |
| 'requires': ['event'] |
| }, |
| |
| 'imagecropper': { |
| 'type': 'js', |
| 'path': 'imagecropper/imagecropper-beta-min.js', |
| 'requires': ['dom', 'event', 'dragdrop', 'element', 'resize'], |
| 'skinnable': true |
| }, |
| |
| 'imageloader': { |
| 'type': 'js', |
| 'path': 'imageloader/imageloader-min.js', |
| 'requires': ['event', 'dom'] |
| }, |
| |
| 'json': { |
| 'type': 'js', |
| 'path': 'json/json-min.js', |
| 'requires': ['yahoo'] |
| }, |
| |
| 'layout': { |
| 'type': 'js', |
| 'path': 'layout/layout-min.js', |
| 'requires': ['dom', 'event', 'element'], |
| 'optional': ['animation', 'dragdrop', 'resize', 'selector'], |
| 'skinnable': true |
| }, |
| |
| 'logger': { |
| 'type': 'js', |
| 'path': 'logger/logger-min.js', |
| 'requires': ['event', 'dom'], |
| 'optional': ['dragdrop'], |
| 'skinnable': true |
| }, |
| |
| 'menu': { |
| 'type': 'js', |
| 'path': 'menu/menu-min.js', |
| 'requires': ['containercore'], |
| 'skinnable': true |
| }, |
| |
| 'paginator': { |
| 'type': 'js', |
| 'path': 'paginator/paginator-min.js', |
| 'requires': ['element'], |
| 'skinnable': true |
| }, |
| |
| 'profiler': { |
| 'type': 'js', |
| 'path': 'profiler/profiler-min.js', |
| 'requires': ['yahoo'] |
| }, |
| |
| |
| 'profilerviewer': { |
| 'type': 'js', |
| 'path': 'profilerviewer/profilerviewer-beta-min.js', |
| 'requires': ['profiler', 'yuiloader', 'element'], |
| 'skinnable': true |
| }, |
| |
| 'reset': { |
| 'type': 'css', |
| 'path': 'reset/reset-min.css' |
| }, |
| |
| 'reset-fonts-grids': { |
| 'type': 'css', |
| 'path': 'reset-fonts-grids/reset-fonts-grids.css', |
| 'supersedes': ['reset', 'fonts', 'grids', 'reset-fonts'], |
| 'rollup': 4 |
| }, |
| |
| 'reset-fonts': { |
| 'type': 'css', |
| 'path': 'reset-fonts/reset-fonts.css', |
| 'supersedes': ['reset', 'fonts'], |
| 'rollup': 2 |
| }, |
| |
| 'resize': { |
| 'type': 'js', |
| 'path': 'resize/resize-min.js', |
| 'requires': ['dom', 'event', 'dragdrop', 'element'], |
| 'optional': ['animation'], |
| 'skinnable': true |
| }, |
| |
| 'selector': { |
| 'type': 'js', |
| 'path': 'selector/selector-beta-min.js', |
| 'requires': ['yahoo', 'dom'] |
| }, |
| |
| 'simpleeditor': { |
| 'type': 'js', |
| 'path': 'editor/simpleeditor-min.js', |
| 'requires': ['element'], |
| 'optional': ['containercore', 'menu', 'button', 'animation', 'dragdrop'], |
| 'skinnable': true, |
| 'pkg': 'editor' |
| }, |
| |
| 'slider': { |
| 'type': 'js', |
| 'path': 'slider/slider-min.js', |
| 'requires': ['dragdrop'], |
| 'optional': ['animation'], |
| 'skinnable': true |
| }, |
| |
| 'tabview': { |
| 'type': 'js', |
| 'path': 'tabview/tabview-min.js', |
| 'requires': ['element'], |
| 'optional': ['connection'], |
| 'skinnable': true |
| }, |
| |
| 'treeview': { |
| 'type': 'js', |
| 'path': 'treeview/treeview-min.js', |
| 'requires': ['event', 'dom'], |
| 'skinnable': true |
| }, |
| |
| 'uploader': { |
| 'type': 'js', |
| 'path': 'uploader/uploader-experimental.js', |
| 'requires': ['element'] |
| }, |
| |
| 'utilities': { |
| 'type': 'js', |
| 'path': 'utilities/utilities.js', |
| 'supersedes': ['yahoo', 'event', 'dragdrop', 'animation', 'dom', 'connection', 'element', 'yahoo-dom-event', 'get', 'yuiloader', 'yuiloader-dom-event'], |
| 'rollup': 8 |
| }, |
| |
| 'yahoo': { |
| 'type': 'js', |
| 'path': 'yahoo/yahoo-min.js' |
| }, |
| |
| 'yahoo-dom-event': { |
| 'type': 'js', |
| 'path': 'yahoo-dom-event/yahoo-dom-event.js', |
| 'supersedes': ['yahoo', 'event', 'dom'], |
| 'rollup': 3 |
| }, |
| |
| 'yuiloader': { |
| 'type': 'js', |
| 'path': 'yuiloader/yuiloader-min.js', |
| 'supersedes': ['yahoo', 'get'] |
| }, |
| |
| 'yuiloader-dom-event': { |
| 'type': 'js', |
| 'path': 'yuiloader-dom-event/yuiloader-dom-event.js', |
| 'supersedes': ['yahoo', 'dom', 'event', 'get', 'yuiloader', 'yahoo-dom-event'], |
| 'rollup': 5 |
| }, |
| |
| 'yuitest': { |
| 'type': 'js', |
| 'path': 'yuitest/yuitest-min.js', |
| 'requires': ['logger'], |
| 'skinnable': true |
| } |
| } |
| } |
| , |
| |
| ObjectUtil: { |
| appendArray: function(o, a) { |
| if (a) { |
| for (var i=0; i<a.length; i=i+1) { |
| o[a[i]] = true; |
| } |
| } |
| }, |
| |
| keys: function(o, ordered) { |
| var a=[], i; |
| for (i in o) { |
| if (lang.hasOwnProperty(o, i)) { |
| a.push(i); |
| } |
| } |
| |
| return a; |
| } |
| }, |
| |
| ArrayUtil: { |
| |
| appendArray: function(a1, a2) { |
| Array.prototype.push.apply(a1, a2); |
| /* |
| for (var i=0; i<a2.length; i=i+1) { |
| a1.push(a2[i]); |
| } |
| */ |
| }, |
| |
| indexOf: function(a, val) { |
| for (var i=0; i<a.length; i=i+1) { |
| if (a[i] === val) { |
| return i; |
| } |
| } |
| |
| return -1; |
| }, |
| |
| toObject: function(a) { |
| var o = {}; |
| for (var i=0; i<a.length; i=i+1) { |
| o[a[i]] = true; |
| } |
| |
| return o; |
| }, |
| |
| /* |
| * Returns a unique array. Does not maintain order, which is fine |
| * for this application, and performs better than it would if it |
| * did. |
| */ |
| uniq: function(a) { |
| return YUI.ObjectUtil.keys(YUI.ArrayUtil.toObject(a)); |
| } |
| } |
| }; |
| |
| YAHOO.util.YUILoader = function(o) { |
| |
| /** |
| * Internal callback to handle multiple internal insert() calls |
| * so that css is inserted prior to js |
| * @property _internalCallback |
| * @private |
| */ |
| this._internalCallback = null; |
| |
| /** |
| * Use the YAHOO environment listener to detect script load. This |
| * is only switched on for Safari 2.x and below. |
| * @property _useYahooListener |
| * @private |
| */ |
| this._useYahooListener = false; |
| |
| /** |
| * Callback that will be executed when the loader is finished |
| * with an insert |
| * @method onSuccess |
| * @type function |
| */ |
| this.onSuccess = null; |
| |
| /** |
| * Callback that will be executed if there is a failure |
| * @method onFailure |
| * @type function |
| */ |
| this.onFailure = Y.log; |
| |
| /** |
| * Callback that will be executed each time a new module is loaded |
| * @method onProgress |
| * @type function |
| */ |
| this.onProgress = null; |
| |
| /** |
| * Callback that will be executed if a timeout occurs |
| * @method onTimeout |
| * @type function |
| */ |
| this.onTimeout = null; |
| |
| /** |
| * The execution scope for all callbacks |
| * @property scope |
| * @default this |
| */ |
| this.scope = this; |
| |
| /** |
| * Data that is passed to all callbacks |
| * @property data |
| */ |
| this.data = null; |
| |
| /** |
| * Node reference or id where new nodes should be inserted before |
| * @property insertBefore |
| * @type string|HTMLElement |
| */ |
| this.insertBefore = null; |
| |
| /** |
| * The charset attribute for inserted nodes |
| * @property charset |
| * @type string |
| * @default utf-8 |
| */ |
| this.charset = null; |
| |
| /** |
| * The name of the variable in a sandbox or script node |
| * (for external script support in Safari 2.x and earlier) |
| * to reference when the load is complete. If this variable |
| * is not available in the specified scripts, the operation will |
| * fail. |
| * @property varName |
| * @type string |
| */ |
| this.varName = null; |
| |
| /** |
| * The base directory. |
| * @property base |
| * @type string |
| * @default http://yui.yahooapis.com/[YUI VERSION]/build/ |
| */ |
| this.base = YUI.info.base; |
| |
| /** |
| * Base path for the combo service |
| * @property comboBase |
| * @type string |
| * @default http://yui.yahooapis.com/combo? |
| */ |
| this.comboBase = YUI.info.comboBase; |
| |
| /** |
| * If configured, YUI will use the the combo handler on the |
| * Yahoo! CDN to pontentially reduce the number of http requests |
| * required. |
| * @property combine |
| * @type boolean |
| * @default false |
| */ |
| // this.combine = (o && !('base' in o)); |
| this.combine = false; |
| |
| |
| /** |
| * Root path to prepend to module path for the combo |
| * service |
| * @property root |
| * @type string |
| * @default [YUI VERSION]/build/ |
| */ |
| this.root = YUI.info.root; |
| |
| /** |
| * Timeout value in milliseconds. If set, this value will be used by |
| * the get utility. the timeout event will fire if |
| * a timeout occurs. |
| * @property timeout |
| * @type int |
| */ |
| this.timeout = 0; |
| |
| /** |
| * A list of modules that should not be loaded, even if |
| * they turn up in the dependency tree |
| * @property ignore |
| * @type string[] |
| */ |
| this.ignore = null; |
| |
| /** |
| * A list of modules that should always be loaded, even |
| * if they have already been inserted into the page. |
| * @property force |
| * @type string[] |
| */ |
| this.force = null; |
| |
| /** |
| * Should we allow rollups |
| * @property allowRollup |
| * @type boolean |
| * @default true |
| */ |
| this.allowRollup = true; |
| |
| /** |
| * A filter to apply to result urls. This filter will modify the default |
| * path for all modules. The default path for the YUI library is the |
| * minified version of the files (e.g., event-min.js). The filter property |
| * can be a predefined filter or a custom filter. The valid predefined |
| * filters are: |
| * <dl> |
| * <dt>DEBUG</dt> |
| * <dd>Selects the debug versions of the library (e.g., event-debug.js). |
| * This option will automatically include the logger widget</dd> |
| * <dt>RAW</dt> |
| * <dd>Selects the non-minified version of the library (e.g., event.js). |
| * </dl> |
| * You can also define a custom filter, which must be an object literal |
| * containing a search expression and a replace string: |
| * <pre> |
| * myFilter: { |
| * 'searchExp': "-min\\.js", |
| * 'replaceStr': "-debug.js" |
| * } |
| * </pre> |
| * @property filter |
| * @type string|{searchExp: string, replaceStr: string} |
| */ |
| this.filter = null; |
| |
| /** |
| * The list of requested modules |
| * @property required |
| * @type {string: boolean} |
| */ |
| this.required = {}; |
| |
| /** |
| * The library metadata |
| * @property moduleInfo |
| */ |
| this.moduleInfo = lang.merge(YUI.info.moduleInfo); |
| |
| /** |
| * List of rollup files found in the library metadata |
| * @property rollups |
| */ |
| this.rollups = null; |
| |
| /** |
| * Whether or not to load optional dependencies for |
| * the requested modules |
| * @property loadOptional |
| * @type boolean |
| * @default false |
| */ |
| this.loadOptional = false; |
| |
| /** |
| * All of the derived dependencies in sorted order, which |
| * will be populated when either calculate() or insert() |
| * is called |
| * @property sorted |
| * @type string[] |
| */ |
| this.sorted = []; |
| |
| /** |
| * Set when beginning to compute the dependency tree. |
| * Composed of what YAHOO reports to be loaded combined |
| * with what has been loaded by the tool |
| * @propery loaded |
| * @type {string: boolean} |
| */ |
| this.loaded = {}; |
| |
| /** |
| * Flag to indicate the dependency tree needs to be recomputed |
| * if insert is called again. |
| * @property dirty |
| * @type boolean |
| * @default true |
| */ |
| this.dirty = true; |
| |
| /** |
| * List of modules inserted by the utility |
| * @property inserted |
| * @type {string: boolean} |
| */ |
| this.inserted = {}; |
| |
| /** |
| * Provides the information used to skin the skinnable components. |
| * The following skin definition would result in 'skin1' and 'skin2' |
| * being loaded for calendar (if calendar was requested), and |
| * 'sam' for all other skinnable components: |
| * |
| * <code> |
| * skin: { |
| * |
| * // The default skin, which is automatically applied if not |
| * // overriden by a component-specific skin definition. |
| * // Change this in to apply a different skin globally |
| * defaultSkin: 'sam', |
| * |
| * // This is combined with the loader base property to get |
| * // the default root directory for a skin. ex: |
| * // http://yui.yahooapis.com/2.3.0/build/assets/skins/sam/ |
| * base: 'assets/skins/', |
| * |
| * // The name of the rollup css file for the skin |
| * path: 'skin.css', |
| * |
| * // The number of skinnable components requested that are |
| * // required before using the rollup file rather than the |
| * // individual component css files |
| * rollup: 3, |
| * |
| * // Any component-specific overrides can be specified here, |
| * // making it possible to load different skins for different |
| * // components. It is possible to load more than one skin |
| * // for a given component as well. |
| * overrides: { |
| * calendar: ['skin1', 'skin2'] |
| * } |
| * } |
| * </code> |
| * @property skin |
| */ |
| |
| var self = this; |
| |
| env.listeners.push(function(m) { |
| if (self._useYahooListener) { |
| //Y.log("YAHOO listener: " + m.name); |
| self.loadNext(m.name); |
| } |
| }); |
| |
| this.skin = lang.merge(YUI.info.skin); |
| |
| this._config(o); |
| |
| }; |
| |
| Y.util.YUILoader.prototype = { |
| |
| FILTERS: { |
| RAW: { |
| 'searchExp': "-min\\.js", |
| 'replaceStr': ".js" |
| }, |
| DEBUG: { |
| 'searchExp': "-min\\.js", |
| 'replaceStr': "-debug.js" |
| } |
| }, |
| |
| SKIN_PREFIX: "skin-", |
| |
| _config: function(o) { |
| |
| // apply config values |
| if (o) { |
| for (var i in o) { |
| if (lang.hasOwnProperty(o, i)) { |
| if (i == "require") { |
| this.require(o[i]); |
| } else { |
| this[i] = o[i]; |
| } |
| } |
| } |
| } |
| |
| // fix filter |
| var f = this.filter; |
| |
| if (lang.isString(f)) { |
| f = f.toUpperCase(); |
| |
| // the logger must be available in order to use the debug |
| // versions of the library |
| if (f === "DEBUG") { |
| this.require("logger"); |
| } |
| |
| // hack to handle a a bug where LogWriter is being instantiated |
| // at load time, and the loader has no way to sort above it |
| // at the moment. |
| if (!Y.widget.LogWriter) { |
| Y.widget.LogWriter = function() { |
| return Y; |
| }; |
| } |
| |
| this.filter = this.FILTERS[f]; |
| } |
| |
| }, |
| |
| /** Add a new module to the component metadata. |
| * <dl> |
| * <dt>name:</dt> <dd>required, the component name</dd> |
| * <dt>type:</dt> <dd>required, the component type (js or css)</dd> |
| * <dt>path:</dt> <dd>required, the path to the script from "base"</dd> |
| * <dt>requires:</dt> <dd>array of modules required by this component</dd> |
| * <dt>optional:</dt> <dd>array of optional modules for this component</dd> |
| * <dt>supersedes:</dt> <dd>array of the modules this component replaces</dd> |
| * <dt>after:</dt> <dd>array of modules the components which, if present, should be sorted above this one</dd> |
| * <dt>rollup:</dt> <dd>the number of superseded modules required for automatic rollup</dd> |
| * <dt>fullpath:</dt> <dd>If fullpath is specified, this is used instead of the configured base + path</dd> |
| * <dt>skinnable:</dt> <dd>flag to determine if skin assets should automatically be pulled in</dd> |
| * </dl> |
| * @method addModule |
| * @param o An object containing the module data |
| * @return {boolean} true if the module was added, false if |
| * the object passed in did not provide all required attributes |
| */ |
| addModule: function(o) { |
| |
| if (!o || !o.name || !o.type || (!o.path && !o.fullpath)) { |
| return false; |
| } |
| |
| o.ext = ('ext' in o) ? o.ext : true; |
| o.requires = o.requires || []; |
| |
| this.moduleInfo[o.name] = o; |
| this.dirty = true; |
| |
| return true; |
| }, |
| |
| /** |
| * Add a requirement for one or more module |
| * @method require |
| * @param what {string[] | string*} the modules to load |
| */ |
| require: function(what) { |
| var a = (typeof what === "string") ? arguments : what; |
| this.dirty = true; |
| YUI.ObjectUtil.appendArray(this.required, a); |
| }, |
| |
| /** |
| * Adds the skin def to the module info |
| * @method _addSkin |
| * @param skin {string} the name of the skin |
| * @param mod {string} the name of the module |
| * @return {string} the module name for the skin |
| * @private |
| */ |
| _addSkin: function(skin, mod) { |
| |
| // Add a module definition for the skin rollup css |
| var name = this.formatSkin(skin), info = this.moduleInfo, |
| sinf = this.skin, ext = info[mod] && info[mod].ext; |
| |
| // Y.log('ext? ' + mod + ": " + ext); |
| if (!info[name]) { |
| // Y.log('adding skin ' + name); |
| this.addModule({ |
| 'name': name, |
| 'type': 'css', |
| 'path': sinf.base + skin + '/' + sinf.path, |
| //'supersedes': '*', |
| 'after': sinf.after, |
| 'rollup': sinf.rollup, |
| 'ext': ext |
| }); |
| } |
| |
| // Add a module definition for the module-specific skin css |
| if (mod) { |
| name = this.formatSkin(skin, mod); |
| if (!info[name]) { |
| var mdef = info[mod], pkg = mdef.pkg || mod; |
| // Y.log('adding skin ' + name); |
| this.addModule({ |
| 'name': name, |
| 'type': 'css', |
| 'after': sinf.after, |
| 'path': pkg + '/' + sinf.base + skin + '/' + mod + '.css', |
| 'ext': ext |
| }); |
| } |
| } |
| |
| return name; |
| }, |
| |
| /** |
| * Returns an object containing properties for all modules required |
| * in order to load the requested module |
| * @method getRequires |
| * @param mod The module definition from moduleInfo |
| */ |
| getRequires: function(mod) { |
| if (!mod) { |
| return []; |
| } |
| |
| if (!this.dirty && mod.expanded) { |
| return mod.expanded; |
| } |
| |
| mod.requires=mod.requires || []; |
| var i, d=[], r=mod.requires, o=mod.optional, info=this.moduleInfo, m; |
| for (i=0; i<r.length; i=i+1) { |
| d.push(r[i]); |
| m = info[r[i]]; |
| YUI.ArrayUtil.appendArray(d, this.getRequires(m)); |
| |
| // add existing skins for skinnable modules as well. The only |
| // way to do this is go through the list of required items (this |
| // assumes that _skin is called before getRequires is called on |
| // the module. |
| // if (m.skinnable) { |
| // var req=this.required, l=req.length; |
| // for (var j=0; j<l; j=j+1) { |
| // // YAHOO.log('checking ' + r[j]); |
| // if (req[j].indexOf(r[j]) > -1) { |
| // // YAHOO.log('adding ' + r[j]); |
| // d.push(req[j]); |
| // } |
| // } |
| // } |
| } |
| |
| if (o && this.loadOptional) { |
| for (i=0; i<o.length; i=i+1) { |
| d.push(o[i]); |
| YUI.ArrayUtil.appendArray(d, this.getRequires(info[o[i]])); |
| } |
| } |
| |
| mod.expanded = YUI.ArrayUtil.uniq(d); |
| |
| return mod.expanded; |
| }, |
| |
| |
| /** |
| * Returns an object literal of the modules the supplied module satisfies |
| * @method getProvides |
| * @param name{string} The name of the module |
| * @param notMe {string} don't add this module name, only include superseded modules |
| * @return what this module provides |
| */ |
| getProvides: function(name, notMe) { |
| var addMe = !(notMe), ckey = (addMe) ? PROV : SUPER, |
| m = this.moduleInfo[name], o = {}; |
| |
| if (!m) { |
| return o; |
| } |
| |
| if (m[ckey]) { |
| // Y.log('cached: ' + name + ' ' + ckey + ' ' + lang.dump(this.moduleInfo[name][ckey], 0)); |
| return m[ckey]; |
| } |
| |
| var s = m.supersedes, done={}, me = this; |
| |
| // use worker to break cycles |
| var add = function(mm) { |
| if (!done[mm]) { |
| // Y.log(name + ' provides worker trying: ' + mm); |
| done[mm] = true; |
| // we always want the return value normal behavior |
| // (provides) for superseded modules. |
| lang.augmentObject(o, me.getProvides(mm)); |
| } |
| |
| // else { |
| // Y.log(name + ' provides worker skipping done: ' + mm); |
| // } |
| }; |
| |
| // calculate superseded modules |
| if (s) { |
| for (var i=0; i<s.length; i=i+1) { |
| add(s[i]); |
| } |
| } |
| |
| // supersedes cache |
| m[SUPER] = o; |
| // provides cache |
| m[PROV] = lang.merge(o); |
| m[PROV][name] = true; |
| |
| // Y.log(name + " supersedes " + lang.dump(m[SUPER], 0)); |
| // Y.log(name + " provides " + lang.dump(m[PROV], 0)); |
| |
| return m[ckey]; |
| }, |
| |
| |
| /** |
| * Calculates the dependency tree, the result is stored in the sorted |
| * property |
| * @method calculate |
| * @param o optional options object |
| */ |
| calculate: function(o) { |
| if (o || this.dirty) { |
| this._config(o); |
| this._setup(); |
| this._explode(); |
| // this._skin(); // deprecated |
| if (this.allowRollup) { |
| this._rollup(); |
| } |
| this._reduce(); |
| this._sort(); |
| |
| // Y.log("after calculate: " + lang.dump(this.required)); |
| |
| this.dirty = false; |
| } |
| }, |
| |
| /** |
| * Investigates the current YUI configuration on the page. By default, |
| * modules already detected will not be loaded again unless a force |
| * option is encountered. Called by calculate() |
| * @method _setup |
| * @private |
| */ |
| _setup: function() { |
| |
| var info = this.moduleInfo, name, i, j; |
| |
| // Create skin modules |
| for (name in info) { |
| |
| if (lang.hasOwnProperty(info, name)) { |
| var m = info[name]; |
| if (m && m.skinnable) { |
| // Y.log("skinning: " + name); |
| var o=this.skin.overrides, smod; |
| if (o && o[name]) { |
| for (i=0; i<o[name].length; i=i+1) { |
| smod = this._addSkin(o[name][i], name); |
| } |
| } else { |
| smod = this._addSkin(this.skin.defaultSkin, name); |
| } |
| |
| m.requires.push(smod); |
| } |
| } |
| |
| } |
| |
| var l = lang.merge(this.inserted); // shallow clone |
| |
| if (!this._sandbox) { |
| l = lang.merge(l, env.modules); |
| } |
| |
| // Y.log("Already loaded stuff: " + lang.dump(l, 0)); |
| |
| // add the ignore list to the list of loaded packages |
| if (this.ignore) { |
| YUI.ObjectUtil.appendArray(l, this.ignore); |
| } |
| |
| // remove modules on the force list from the loaded list |
| if (this.force) { |
| for (i=0; i<this.force.length; i=i+1) { |
| if (this.force[i] in l) { |
| delete l[this.force[i]]; |
| } |
| } |
| } |
| |
| // expand the list to include superseded modules |
| for (j in l) { |
| // Y.log("expanding: " + j); |
| if (lang.hasOwnProperty(l, j)) { |
| lang.augmentObject(l, this.getProvides(j)); |
| } |
| } |
| |
| // Y.log("loaded expanded: " + lang.dump(l, 0)); |
| |
| this.loaded = l; |
| |
| }, |
| |
| |
| /** |
| * Inspects the required modules list looking for additional |
| * dependencies. Expands the required list to include all |
| * required modules. Called by calculate() |
| * @method _explode |
| * @private |
| */ |
| _explode: function() { |
| |
| var r=this.required, i, mod; |
| |
| for (i in r) { |
| if (lang.hasOwnProperty(r, i)) { |
| mod = this.moduleInfo[i]; |
| if (mod) { |
| |
| var req = this.getRequires(mod); |
| |
| if (req) { |
| YUI.ObjectUtil.appendArray(r, req); |
| } |
| } |
| } |
| } |
| }, |
| |
| /** |
| * Sets up the requirements for the skin assets if any of the |
| * requested modules are skinnable |
| * @method _skin |
| * @private |
| * @deprecated skin modules are generated for all skinnable |
| * components during _setup(), and the components |
| * are configured to require the skin. |
| */ |
| _skin: function() { |
| |
| }, |
| |
| /** |
| * Returns the skin module name for the specified skin name. If a |
| * module name is supplied, the returned skin module name is |
| * specific to the module passed in. |
| * @method formatSkin |
| * @param skin {string} the name of the skin |
| * @param mod {string} optional: the name of a module to skin |
| * @return {string} the full skin module name |
| */ |
| formatSkin: function(skin, mod) { |
| var s = this.SKIN_PREFIX + skin; |
| if (mod) { |
| s = s + "-" + mod; |
| } |
| |
| return s; |
| }, |
| |
| /** |
| * Reverses <code>formatSkin</code>, providing the skin name and |
| * module name if the string matches the pattern for skins. |
| * @method parseSkin |
| * @param mod {string} the module name to parse |
| * @return {skin: string, module: string} the parsed skin name |
| * and module name, or null if the supplied string does not match |
| * the skin pattern |
| */ |
| parseSkin: function(mod) { |
| |
| if (mod.indexOf(this.SKIN_PREFIX) === 0) { |
| var a = mod.split("-"); |
| return {skin: a[1], module: a[2]}; |
| } |
| |
| return null; |
| }, |
| |
| /** |
| * Look for rollup packages to determine if all of the modules a |
| * rollup supersedes are required. If so, include the rollup to |
| * help reduce the total number of connections required. Called |
| * by calculate() |
| * @method _rollup |
| * @private |
| */ |
| _rollup: function() { |
| var i, j, m, s, rollups={}, r=this.required, roll, |
| info = this.moduleInfo; |
| |
| // find and cache rollup modules |
| if (this.dirty || !this.rollups) { |
| for (i in info) { |
| if (lang.hasOwnProperty(info, i)) { |
| m = info[i]; |
| //if (m && m.rollup && m.supersedes) { |
| if (m && m.rollup) { |
| rollups[i] = m; |
| } |
| } |
| } |
| |
| this.rollups = rollups; |
| } |
| |
| // make as many passes as needed to pick up rollup rollups |
| for (;;) { |
| var rolled = false; |
| |
| // go through the rollup candidates |
| for (i in rollups) { |
| |
| // there can be only one |
| if (!r[i] && !this.loaded[i]) { |
| m =info[i]; s = m.supersedes; roll=false; |
| |
| if (!m.rollup) { |
| continue; |
| } |
| |
| var skin = (m.ext) ? false : this.parseSkin(i), c = 0; |
| |
| // Y.log('skin? ' + i + ": " + skin); |
| if (skin) { |
| for (j in r) { |
| if (lang.hasOwnProperty(r, j)) { |
| if (i !== j && this.parseSkin(j)) { |
| c++; |
| roll = (c >= m.rollup); |
| if (roll) { |
| // Y.log("skin rollup " + lang.dump(r)); |
| break; |
| } |
| } |
| } |
| } |
| |
| } else { |
| |
| // check the threshold |
| for (j=0;j<s.length;j=j+1) { |
| |
| // if the superseded module is loaded, we can't load the rollup |
| if (this.loaded[s[j]] && (!YUI.dupsAllowed[s[j]])) { |
| roll = false; |
| break; |
| // increment the counter if this module is required. if we are |
| // beyond the rollup threshold, we will use the rollup module |
| } else if (r[s[j]]) { |
| c++; |
| roll = (c >= m.rollup); |
| if (roll) { |
| // Y.log("over thresh " + c + ", " + lang.dump(r)); |
| break; |
| } |
| } |
| } |
| } |
| |
| if (roll) { |
| // Y.log("rollup: " + i + ", " + lang.dump(this, 1)); |
| // add the rollup |
| r[i] = true; |
| rolled = true; |
| |
| // expand the rollup's dependencies |
| this.getRequires(m); |
| } |
| } |
| } |
| |
| // if we made it here w/o rolling up something, we are done |
| if (!rolled) { |
| break; |
| } |
| } |
| }, |
| |
| /** |
| * Remove superceded modules and loaded modules. Called by |
| * calculate() after we have the mega list of all dependencies |
| * @method _reduce |
| * @private |
| */ |
| _reduce: function() { |
| |
| var i, j, s, m, r=this.required; |
| for (i in r) { |
| |
| // remove if already loaded |
| if (i in this.loaded) { |
| delete r[i]; |
| |
| // remove anything this module supersedes |
| } else { |
| |
| var skinDef = this.parseSkin(i); |
| |
| if (skinDef) { |
| //YAHOO.log("skin found in reduce: " + skinDef.skin + ", " + skinDef.module); |
| // the skin rollup will not have a module name |
| if (!skinDef.module) { |
| var skin_pre = this.SKIN_PREFIX + skinDef.skin; |
| //YAHOO.log("skin_pre: " + skin_pre); |
| for (j in r) { |
| |
| if (lang.hasOwnProperty(r, j)) { |
| m = this.moduleInfo[j]; |
| var ext = m && m.ext; |
| if (!ext && j !== i && j.indexOf(skin_pre) > -1) { |
| // Y.log ("removing component skin: " + j); |
| delete r[j]; |
| } |
| } |
| } |
| } |
| } else { |
| |
| m = this.moduleInfo[i]; |
| s = m && m.supersedes; |
| if (s) { |
| for (j=0; j<s.length; j=j+1) { |
| if (s[j] in r) { |
| delete r[s[j]]; |
| } |
| } |
| } |
| } |
| } |
| } |
| }, |
| |
| _onFailure: function(msg) { |
| YAHOO.log('Failure', 'info', 'loader'); |
| |
| var f = this.onFailure; |
| if (f) { |
| f.call(this.scope, { |
| msg: 'failure: ' + msg, |
| data: this.data, |
| success: false |
| }); |
| } |
| }, |
| |
| _onTimeout: function() { |
| YAHOO.log('Timeout', 'info', 'loader'); |
| var f = this.onTimeout; |
| if (f) { |
| f.call(this.scope, { |
| msg: 'timeout', |
| data: this.data, |
| success: false |
| }); |
| } |
| }, |
| |
| /** |
| * Sorts the dependency tree. The last step of calculate() |
| * @method _sort |
| * @private |
| */ |
| _sort: function() { |
| // create an indexed list |
| var s=[], info=this.moduleInfo, loaded=this.loaded, |
| checkOptional=!this.loadOptional, me = this; |
| |
| // returns true if b is not loaded, and is required |
| // directly or by means of modules it supersedes. |
| var requires = function(aa, bb) { |
| |
| var mm=info[aa]; |
| |
| if (loaded[bb] || !mm) { |
| return false; |
| } |
| |
| var ii, |
| rr = mm.expanded, |
| after = mm.after, |
| other = info[bb], |
| optional = mm.optional; |
| |
| |
| // check if this module requires the other directly |
| if (rr && YUI.ArrayUtil.indexOf(rr, bb) > -1) { |
| return true; |
| } |
| |
| // check if this module should be sorted after the other |
| if (after && YUI.ArrayUtil.indexOf(after, bb) > -1) { |
| return true; |
| } |
| |
| // if loadOptional is not specified, optional dependencies still |
| // must be sorted correctly when present. |
| if (checkOptional && optional && YUI.ArrayUtil.indexOf(optional, bb) > -1) { |
| return true; |
| } |
| |
| // check if this module requires one the other supersedes |
| var ss=info[bb] && info[bb].supersedes; |
| if (ss) { |
| for (ii=0; ii<ss.length; ii=ii+1) { |
| if (requires(aa, ss[ii])) { |
| return true; |
| } |
| } |
| } |
| |
| // var ss=me.getProvides(bb, true); |
| // if (ss) { |
| // for (ii in ss) { |
| // if (requires(aa, ii)) { |
| // return true; |
| // } |
| // } |
| // } |
| |
| // external css files should be sorted below yui css |
| if (mm.ext && mm.type == 'css' && !other.ext && other.type == 'css') { |
| return true; |
| } |
| |
| return false; |
| }; |
| |
| // get the required items out of the obj into an array so we |
| // can sort |
| for (var i in this.required) { |
| if (lang.hasOwnProperty(this.required, i)) { |
| s.push(i); |
| } |
| } |
| |
| // pointer to the first unsorted item |
| var p=0; |
| |
| // keep going until we make a pass without moving anything |
| for (;;) { |
| |
| var l=s.length, a, b, j, k, moved=false; |
| |
| // start the loop after items that are already sorted |
| for (j=p; j<l; j=j+1) { |
| |
| // check the next module on the list to see if its |
| // dependencies have been met |
| a = s[j]; |
| |
| // check everything below current item and move if we |
| // find a requirement for the current item |
| for (k=j+1; k<l; k=k+1) { |
| if (requires(a, s[k])) { |
| |
| // extract the dependency so we can move it up |
| b = s.splice(k, 1); |
| |
| // insert the dependency above the item that |
| // requires it |
| s.splice(j, 0, b[0]); |
| |
| moved = true; |
| break; |
| } |
| } |
| |
| // jump out of loop if we moved something |
| if (moved) { |
| break; |
| // this item is sorted, move our pointer and keep going |
| } else { |
| p = p + 1; |
| } |
| } |
| |
| // when we make it here and moved is false, we are |
| // finished sorting |
| if (!moved) { |
| break; |
| } |
| |
| } |
| |
| this.sorted = s; |
| }, |
| |
| toString: function() { |
| var o = { |
| type: "YUILoader", |
| base: this.base, |
| filter: this.filter, |
| required: this.required, |
| loaded: this.loaded, |
| inserted: this.inserted |
| }; |
| |
| lang.dump(o, 1); |
| }, |
| |
| _combine: function() { |
| |
| this._combining = []; |
| |
| var self = this, |
| s=this.sorted, |
| len = s.length, |
| js = this.comboBase, |
| css = this.comboBase, |
| target, |
| startLen = js.length, |
| i, m, type = this.loadType; |
| |
| YAHOO.log('type ' + type); |
| |
| for (i=0; i<len; i=i+1) { |
| |
| m = this.moduleInfo[s[i]]; |
| |
| if (m && !m.ext && (!type || type === m.type)) { |
| |
| target = this.root + m.path; |
| |
| // if (i < len-1) { |
| target += '&'; |
| // } |
| |
| if (m.type == 'js') { |
| js += target; |
| } else { |
| css += target; |
| } |
| |
| // YAHOO.log(target); |
| this._combining.push(s[i]); |
| } |
| } |
| |
| if (this._combining.length) { |
| |
| YAHOO.log('Attempting to combine: ' + this._combining, "info", "loader"); |
| |
| var callback=function(o) { |
| // YAHOO.log('Combo complete: ' + o.data, "info", "loader"); |
| // this._combineComplete = true; |
| |
| var c=this._combining, len=c.length, i, m; |
| for (i=0; i<len; i=i+1) { |
| this.inserted[c[i]] = true; |
| } |
| |
| this.loadNext(o.data); |
| }, |
| |
| loadScript = function() { |
| // YAHOO.log('combining js: ' + js); |
| if (js.length > startLen) { |
| YAHOO.util.Get.script(self._filter(js), { |
| data: self._loading, |
| onSuccess: callback, |
| onFailure: self._onFailure, |
| onTimeout: self._onTimeout, |
| insertBefore: self.insertBefore, |
| charset: self.charset, |
| timeout: self.timeout, |
| scope: self |
| }); |
| } |
| }; |
| |
| // load the css first |
| // YAHOO.log('combining css: ' + css); |
| if (css.length > startLen) { |
| YAHOO.util.Get.css(this._filter(css), { |
| data: this._loading, |
| onSuccess: loadScript, |
| onFailure: this._onFailure, |
| onTimeout: this._onTimeout, |
| insertBefore: this.insertBefore, |
| charset: this.charset, |
| timeout: this.timeout, |
| scope: self |
| }); |
| } else { |
| loadScript(); |
| } |
| |
| return; |
| |
| } else { |
| // this._combineComplete = true; |
| this.loadNext(this._loading); |
| } |
| }, |
| |
| /** |
| * inserts the requested modules and their dependencies. |
| * <code>type</code> can be "js" or "css". Both script and |
| * css are inserted if type is not provided. |
| * @method insert |
| * @param o optional options object |
| * @param type {string} the type of dependency to insert |
| */ |
| insert: function(o, type) { |
| // if (o) { |
| // Y.log("insert: " + lang.dump(o, 1) + ", " + type); |
| // } else { |
| // Y.log("insert: " + this.toString() + ", " + type); |
| // } |
| |
| // build the dependency list |
| this.calculate(o); |
| |
| |
| // set a flag to indicate the load has started |
| this._loading = true; |
| |
| // flag to indicate we are done with the combo service |
| // and any additional files will need to be loaded |
| // individually |
| // this._combineComplete = false; |
| |
| // keep the loadType (js, css or undefined) cached |
| this.loadType = type; |
| |
| if (this.combine) { |
| return this._combine(); |
| } |
| |
| if (!type) { |
| // Y.log("trying to load css first"); |
| var self = this; |
| this._internalCallback = function() { |
| self._internalCallback = null; |
| self.insert(null, "js"); |
| }; |
| this.insert(null, "css"); |
| return; |
| } |
| |
| |
| // start the load |
| this.loadNext(); |
| |
| }, |
| |
| /** |
| * Interns the script for the requested modules. The callback is |
| * provided a reference to the sandboxed YAHOO object. This only |
| * applies to the script: css can not be sandboxed; css will be |
| * loaded into the page normally if specified. |
| * @method sandbox |
| * @param callback {Function} the callback to exectued when the load is |
| * complete. |
| */ |
| sandbox: function(o, type) { |
| // if (o) { |
| // YAHOO.log("sandbox: " + lang.dump(o, 1) + ", " + type); |
| // } else { |
| // YAHOO.log("sandbox: " + this.toString() + ", " + type); |
| // } |
| |
| this._config(o); |
| |
| if (!this.onSuccess) { |
| throw new Error("You must supply an onSuccess handler for your sandbox"); |
| } |
| |
| this._sandbox = true; |
| |
| var self = this; |
| |
| // take care of any css first (this can't be sandboxed) |
| if (!type || type !== "js") { |
| this._internalCallback = function() { |
| self._internalCallback = null; |
| self.sandbox(null, "js"); |
| }; |
| this.insert(null, "css"); |
| return; |
| } |
| |
| // get the connection manager if not on the page |
| if (!util.Connect) { |
| // get a new loader instance to load connection. |
| var ld = new YAHOO.util.YUILoader(); |
| ld.insert({ |
| base: this.base, |
| filter: this.filter, |
| require: "connection", |
| insertBefore: this.insertBefore, |
| charset: this.charset, |
| onSuccess: function() { |
| this.sandbox(null, "js"); |
| }, |
| scope: this |
| }, "js"); |
| return; |
| } |
| |
| this._scriptText = []; |
| this._loadCount = 0; |
| this._stopCount = this.sorted.length; |
| this._xhr = []; |
| |
| this.calculate(); |
| |
| var s=this.sorted, l=s.length, i, m, url; |
| |
| for (i=0; i<l; i=i+1) { |
| m = this.moduleInfo[s[i]]; |
| |
| // undefined modules cause a failure |
| if (!m) { |
| this._onFailure("undefined module " + m); |
| for (var j=0;j<this._xhr.length;j=j+1) { |
| this._xhr[j].abort(); |
| } |
| return; |
| } |
| |
| // css files should be done |
| if (m.type !== "js") { |
| this._loadCount++; |
| continue; |
| } |
| |
| url = m.fullpath; |
| url = (url) ? this._filter(url) : this._url(m.path); |
| |
| // YAHOO.log("xhr request: " + url + ", " + i); |
| |
| var xhrData = { |
| |
| success: function(o) { |
| |
| var idx=o.argument[0], name=o.argument[2]; |
| |
| // store the response in the position it was requested |
| this._scriptText[idx] = o.responseText; |
| |
| // YAHOO.log("received: " + o.responseText.substr(0, 100) + ", " + idx); |
| |
| if (this.onProgress) { |
| this.onProgress.call(this.scope, { |
| name: name, |
| scriptText: o.responseText, |
| xhrResponse: o, |
| data: this.data |
| }); |
| } |
| |
| // only generate the sandbox once everything is loaded |
| this._loadCount++; |
| |
| if (this._loadCount >= this._stopCount) { |
| |
| // the variable to find |
| var v = this.varName || "YAHOO"; |
| |
| // wrap the contents of the requested modules in an anonymous function |
| var t = "(function() {\n"; |
| |
| // return the locally scoped reference. |
| var b = "\nreturn " + v + ";\n})();"; |
| |
| var ref = eval(t + this._scriptText.join("\n") + b); |
| |
| this._pushEvents(ref); |
| |
| if (ref) { |
| this.onSuccess.call(this.scope, { |
| reference: ref, |
| data: this.data |
| }); |
| } else { |
| this._onFailure.call(this.varName + " reference failure"); |
| } |
| } |
| }, |
| |
| failure: function(o) { |
| this.onFailure.call(this.scope, { |
| msg: "XHR failure", |
| xhrResponse: o, |
| data: this.data |
| }); |
| }, |
| |
| scope: this, |
| |
| // module index, module name, sandbox name |
| argument: [i, url, s[i]] |
| |
| }; |
| |
| this._xhr.push(util.Connect.asyncRequest('GET', url, xhrData)); |
| } |
| }, |
| |
| /** |
| * Executed every time a module is loaded, and if we are in a load |
| * cycle, we attempt to load the next script. Public so that it |
| * is possible to call this if using a method other than |
| * YAHOO.register to determine when scripts are fully loaded |
| * @method loadNext |
| * @param mname {string} optional the name of the module that has |
| * been loaded (which is usually why it is time to load the next |
| * one) |
| */ |
| loadNext: function(mname) { |
| |
| // It is possible that this function is executed due to something |
| // else one the page loading a YUI module. Only react when we |
| // are actively loading something |
| if (!this._loading) { |
| return; |
| } |
| |
| |
| if (mname) { |
| |
| // if the module that was just loaded isn't what we were expecting, |
| // continue to wait |
| if (mname !== this._loading) { |
| return; |
| } |
| |
| // YAHOO.log("loadNext executing, just loaded " + mname); |
| |
| // The global handler that is called when each module is loaded |
| // will pass that module name to this function. Storing this |
| // data to avoid loading the same module multiple times |
| this.inserted[mname] = true; |
| |
| if (this.onProgress) { |
| this.onProgress.call(this.scope, { |
| name: mname, |
| data: this.data |
| }); |
| } |
| //var o = this.getProvides(mname); |
| //this.inserted = lang.merge(this.inserted, o); |
| } |
| |
| var s=this.sorted, len=s.length, i, m; |
| |
| for (i=0; i<len; i=i+1) { |
| |
| // This.inserted keeps track of what the loader has loaded |
| if (s[i] in this.inserted) { |
| // YAHOO.log(s[i] + " alread loaded "); |
| continue; |
| } |
| |
| // Because rollups will cause multiple load notifications |
| // from YAHOO, loadNext may be called multiple times for |
| // the same module when loading a rollup. We can safely |
| // skip the subsequent requests |
| if (s[i] === this._loading) { |
| // YAHOO.log("still loading " + s[i] + ", waiting"); |
| return; |
| } |
| |
| // log("inserting " + s[i]); |
| m = this.moduleInfo[s[i]]; |
| |
| if (!m) { |
| this.onFailure.call(this.scope, { |
| msg: "undefined module " + m, |
| data: this.data |
| }); |
| return; |
| } |
| |
| // The load type is stored to offer the possibility to load |
| // the css separately from the script. |
| if (!this.loadType || this.loadType === m.type) { |
| this._loading = s[i]; |
| //YAHOO.log("attempting to load " + s[i] + ", " + this.base); |
| |
| var fn=(m.type === "css") ? util.Get.css : util.Get.script, |
| url = m.fullpath, |
| self=this, |
| c=function(o) { |
| self.loadNext(o.data); |
| }; |
| |
| url = (url) ? this._filter(url) : this._url(m.path); |
| |
| // safari 2.x or lower, script, and part of YUI |
| if (env.ua.webkit && env.ua.webkit < 420 && m.type === "js" && |
| !m.varName) { |
| //YUI.info.moduleInfo[s[i]]) { |
| //YAHOO.log("using YAHOO env " + s[i] + ", " + m.varName); |
| c = null; |
| this._useYahooListener = true; |
| } |
| |
| fn(url, { |
| data: s[i], |
| onSuccess: c, |
| onFailure: this._onFailure, |
| onTimeout: this._onTimeout, |
| insertBefore: this.insertBefore, |
| charset: this.charset, |
| timeout: this.timeout, |
| varName: m.varName, |
| scope: self |
| }); |
| |
| return; |
| } |
| } |
| |
| // we are finished |
| this._loading = null; |
| |
| // internal callback for loading css first |
| if (this._internalCallback) { |
| var f = this._internalCallback; |
| this._internalCallback = null; |
| f.call(this); |
| } else if (this.onSuccess) { |
| this._pushEvents(); |
| this.onSuccess.call(this.scope, { |
| data: this.data |
| }); |
| } |
| |
| }, |
| |
| /** |
| * In IE, the onAvailable/onDOMReady events need help when Event is |
| * loaded dynamically |
| * @method _pushEvents |
| * @param {Function} optional function reference |
| * @private |
| */ |
| _pushEvents: function(ref) { |
| var r = ref || YAHOO; |
| if (r.util && r.util.Event) { |
| r.util.Event._load(); |
| } |
| }, |
| |
| /** |
| * Applies filter |
| * method _filter |
| * @return {string} the filtered string |
| * @private |
| */ |
| _filter: function(str) { |
| var f = this.filter; |
| return (f) ? str.replace(new RegExp(f.searchExp), f.replaceStr) : str; |
| }, |
| |
| /** |
| * Generates the full url for a module |
| * method _url |
| * @param path {string} the path fragment |
| * @return {string} the full url |
| * @private |
| */ |
| _url: function(path) { |
| |
| var u = this.base || "", f=this.filter; |
| u = u + path; |
| return this._filter(u); |
| } |
| |
| }; |
| |
| })(); |