get.js revision fadfbf43dab13f093121113f8912feff7ae7b949
/**
* Provides a mechanism to fetch remote resources and
* insert them into a document.
* @module get
*/
/**
* Fetches and inserts one or more script or link nodes into the document
* @class Get
* @static
*/
/**
Returns a new object containing a deep merge of the enumerable properties of all
passed objects. Properties in later arguments take precedence over properties
with the same name in earlier arguments. Plain objects and arrays are
deep-cloned rather than copied by reference. All other complex objects (
functions, Dates, RegExps, etc.) are copied by reference.
@method deepMerge
@param {object} obj* One or more objects to merge.
@return {object} New object with merged values from all other objects.
**/
function deepMerge() {
}
/**
Like `deepMerge()`, but modifies the first passed object with a deep merge of
the enumerable properties of all other passed objects, rather than returning a
brand new object.
@method simpleMix
@param {object} target Object to receive mixed-in properties.
@param {object} obj* One or more objects to mix into _target_.
@return {object} Reference to the same _target_ object that was passed in.
**/
function simpleMix() {
// The value.nodeType check above prevents us from trying to
// merge the document object. Ideally we should add a few more
// checks for other non-plain objects as well, but this'll do
// for now.
}
} else {
}
}
}
return target;
}
// -- Public Properties ----------------------------------------------------
/**
Default options for CSS requests.
@property cssOptions
@type Object
@static
**/
cssOptions: {
attributes: {
rel: 'stylesheet'
},
},
/**
Default options for JS requests.
@property jsOptions
@type Object
@static
**/
jsOptions: {
},
/**
Default options for all requests.
@property options
@type Object
@static
**/
options: {
attributes: {
charset: 'utf-8'
}
},
// -- Protected Properties -------------------------------------------------
/**
Regex that matches a CSS URL.
@property REGEX_CSS
@type RegExp
@final
@protected
@static
**/
/**
Regex that matches a JS URL.
@property REGEX_JS
@type RegExp
@final
@protected
@static
**/
/**
Contains information about the current environment, such as whether it's a
browser or a server-side environment, and what script and link injection
features it supports.
This object is created and populated the first time the `_getEnv()` method
is called.
@property _env
@type Object
@protected
@static
**/
/**
Currently pending transaction, if any.
This is actually an object with two properties: `callback`, containing the
optional callback passed to `css()`, `load()`, or `script()`; and
`transaction`, containing the actual transaction instance.
@property _pending
@type Object
@protected
@static
**/
_pending: null,
/**
Queued transactions and associated callbacks.
@property _queue
@type Object[]
@protected
@static
**/
_queue: [],
// -- Public Methods -------------------------------------------------------
abort: function (transaction) {
if (!(typeof transaction === 'object')) {
id = transaction;
transaction = null;
Y.log('Passing an id to `abort()` is deprecated as of 3.5.0. Pass a transaction object instead.', 'warn', 'get');
this._pending = null;
} else {
transaction = item;
break;
}
}
}
}
if (transaction) {
transaction.abort();
}
},
},
},
// Loads both CSS and JS.
},
// -- Protected Methods ----------------------------------------------------
_getEnv: function () {
// Note: some of these checks require browser sniffs since it's not
// feasible to load test files on every pageview just to perform a
// feature test. I'm sorry if this makes you sad.
return this._env = {
// True if this is a browser that supports disabling async mode on
// dynamically created script nodes. See
// https://developer.mozilla.org/En/HTML/Element/Script#Attributes
// True if this browser fires an event when a dynamically injected
// link node finishes loading. This is currently true for IE, Opera,
// and Firefox 9+. Note that IE versions <9 fire the DOM 0 "onload"
// event, but not "load". All versions of IE fire "onload".
// True if this browser fires an event when a dynamically injected
// link node fails to load. Currently, Firefox 9+ is the only
// browser known to support this.
// True if this browser preserves script execution order while
// loading scripts in parallel as long as the script node's `async`
// attribute is set to false to explicitly disable async execution.
};
},
var requests = [],
if (typeof urls === 'string') {
}
// If `url` is a string, we create a URL object for it, then merge
// in global options and request-specific options. If it's an object
// with a "url" property, we assume it's a request object containing
// URL-specific options.
if (typeof url === 'string') {
// URL-specific options override both global defaults and
// request-specific options.
} else {
continue;
}
// If we didn't get an explicit type for this URL either in the
// request options or the URL-specific options, try to determine
// one from the file extension.
} else {
}
}
}
// Mix in type-specific default options, but don't overwrite any
// options that have already been set.
// Give the node an id attribute if it doesn't already have one.
// Backcompat for <3.5.0 behavior.
} else {
}
Y.log('The `charset` option is deprecated as of 3.5.0. Set `attributes.charset` instead.', 'warn', 'get');
}
}
},
var transaction;
if (!this._env) {
this._getEnv();
}
});
this._next();
return transaction;
},
_next: function () {
var item;
if (this._pending) {
return;
}
if (item) {
});
}
}
};
/**
Alias for `js()`. Deprecated as of 3.5.0.
@method js
@deprecated Use `js()` instead.
@static
**/
/**
Represents a Get transaction, which may contain requests for one or more JS or
CSS files.
This class should not be instantiated manually. Instances will be created and
returned as needed by Y.Get's `css()`, `load()`, and `script()` methods.
@class Get.Transaction
@constructor
**/
var self = this;
// Deprecated pre-3.5.0 properties.
};
/**
Id of the most recent transaction.
@property _lastId
@type Number
@protected
@static
**/
Transaction.prototype = {
// -- Public Properties ----------------------------------------------------
// -- Public Methods -------------------------------------------------------
abort: function () {
this._pending = null;
this._queue = [];
this._waiting = 0;
this._finish();
},
if (state === 'done') {
} else {
if (state === 'executing') {
return;
}
}
this._state = 'executing';
// No need to queue CSS or fully async JS.
} else {
}
}
this._next();
},
purge: function () {
if (node.clearAttributes) {
// IE.
} else {
// Everyone else.
}
}
}
}
},
// -- Protected Methods ----------------------------------------------------
attr;
}
}
return node;
},
_finish: function () {
if (this._state === 'done') {
return;
}
this._state = 'done';
this._callbacks[i](errors, this);
}
data = this._getEventData();
if (errors) {
}
}
}
}
},
_getEventData: function (req) {
if (req) {
// This merge is necessary for backcompat. I hate it.
return Y.merge(this, {
});
} else {
return this;
}
},
_getInsertBefore: function (req) {
// Inserting before a <base> tag apparently works around an IE bug
// (according to a comment from pre-3.5.0 Y.Get), but I'm not sure what
// bug that is, exactly. Better safe than sorry?
if (el) {
}
// Barring an explicit insertBefore config or a <base> element, we'll
// try to insert before the first child of <head>. If <head> doesn't
// exist, we'll throw our hands in the air and insert before the first
// <script>, which we know must exist because *something* put Y.Get on
// the page.
},
self = this,
if (!node) {
}
function onError(e) {
// TODO: What useful info is on `e`, if any?
}
function onLoad() {
}
// Deal with script asynchronicity.
if (isScript) {
// Explicitly indicate that we want the browser to execute this
// script asynchronously. This is necessary for older browsers
// like Firefox <4.
// This browser treats injected scripts as async by default
// (standard HTML5 behavior) but asynchronous loading isn't
// desired, so tell the browser not to mark this script as
// async.
// If this browser doesn't preserve script execution order based
// on insertion order, we'll need to avoid inserting other
// scripts until this one finishes loading.
if (!env.preservesScriptOrder) {
Y.log("This browser doesn't preserve script execution order, so scripts will be loaded synchronously (which is slower).", 'info', 'get');
}
}
} else {
}
// Inject the node.
// Script on IE6, 7, and 8.
node.onreadystatechange = function () {
node.onreadystatechange = null;
onLoad();
}
};
// CSS on Firefox <9 or WebKit.
// TODO
} else {
// Script or CSS on everything else.
}
this._waiting += 1;
},
_next: function () {
if (this._pending) {
return;
}
// If there are requests in the queue, insert the next queued request.
// Otherwise, if we're waiting on already-inserted requests to finish,
// wait longer. If there are no queued requests and we're not waiting
// for anything to load, then we're done!
} else if (!this._waiting) {
this._finish();
}
},
if (err) {
});
}
if (options.onProgress) {
this._getEventData(req));
}
this._pending = null;
this._waiting -= 1;
this._next();
}
};
/*
Public functions:
- abort(o) void
- o: transaction object or tId string
- css(urls, options) String (transaction object)
- script(urls, options) String (transaction object)
Public callbacks:
- onEnd
- Executes after the transaction finishes, regardless of success or failure.
- onFailure
- Same payload as onSuccess.
- onProgress(e)
- Same payload as onSuccess, but with an additional e.url property
containing the URL of the loaded file.
- onSuccess(e)
- e.win: Window the nodes were inserted into.
- e.data: Arbitrary data object provided at request time.
- e.nodes: Array of inserted nodes.
- e.purge: Function that will purge the inserted nodes.
- onTimeout(e)
- Same payload as onSuccess.
Options:
- async: When true, an array of files will be loaded in parallel rather than
in serial.
- attributes: Object literal containing additional attributes to add to nodes.
- autopurge: Whether or not nodes should be automatically purged.
- charset: Charset for inserted nodes (deprecated -- use the `attributes` config
instead).
- context: Execution context (`this` object) for callback functions.
- data: Arbitrary data object to supply to callbacks.
inserted.
- purgethreshold: Number of transactions before autopurge should occur.
- timeout: Number of milliseconds to wait before aborting and firing onTimeout.
- win: Window into which nodes should be inserted. Defaults to current window.
Features:
- charset="utf-8" by default
- autopurge after 20 nodes inserted
- node id is a Y.guid()
- log a warning on failure
- clear a node's attributes before purging it (why? to help GC?)
- insertBefore option defaults to the first "base" element, if any
Transaction objects:
{
tId: 'transaction id string'
}
Callback data payload:
{
tId: q.tId,
win: q.win,
data: q.data,
nodes: q.nodes,
msg: msg,
statusText: result,
url: url,
purge: function() {
_purge(this.tId);
}
}
*/