src/cm/media/js/lib/yui/yui3-3.15.0/build/jsonp/jsonp.js
changeset 602 e16a97fb364a
equal deleted inserted replaced
601:d334a616c023 602:e16a97fb364a
       
     1 YUI.add('jsonp', function (Y, NAME) {
       
     2 
       
     3 var isFunction = Y.Lang.isFunction;
       
     4 
       
     5 /**
       
     6  * <p>Provides a JSONPRequest class for repeated JSONP calls, and a convenience
       
     7  * method Y.jsonp(url, callback) to instantiate and send a JSONP request.</p>
       
     8  *
       
     9  * <p>Both the constructor as well as the convenience function take two
       
    10  * parameters: a url string and a callback.</p>
       
    11  *
       
    12  * <p>The url provided must include the placeholder string
       
    13  * &quot;{callback}&quot; which will be replaced by a dynamically
       
    14  * generated routing function to pass the data to your callback function.
       
    15  * An example url might look like
       
    16  * &quot;http://example.com/service?callback={callback}&quot;.</p>
       
    17  *
       
    18  * <p>The second parameter can be a callback function that accepts the JSON
       
    19  * payload as its argument, or a configuration object supporting the keys:</p>
       
    20  * <ul>
       
    21  *   <li>on - map of callback subscribers
       
    22  *      <ul>
       
    23  *         <li>success - function handler for successful transmission</li>
       
    24  *         <li>failure - function handler for failed transmission</li>
       
    25  *         <li>timeout - function handler for transactions that timeout</li>
       
    26  *      </ul>
       
    27  *  </li>
       
    28  *  <li>format  - override function for inserting the proxy name in the url</li>
       
    29  *  <li>timeout - the number of milliseconds to wait before giving up</li>
       
    30  *  <li>context - becomes <code>this</code> in the callbacks</li>
       
    31  *  <li>args    - array of subsequent parameters to pass to the callbacks</li>
       
    32  *  <li>allowCache - use the same proxy name for all requests? (boolean)</li>
       
    33  * </ul>
       
    34  *
       
    35  * @module jsonp
       
    36  * @class JSONPRequest
       
    37  * @constructor
       
    38  * @param url {String} the url of the JSONP service
       
    39  * @param callback {Object|Function} the default callback configuration or
       
    40  *                                   success handler
       
    41  */
       
    42 function JSONPRequest() {
       
    43     this._init.apply(this, arguments);
       
    44 }
       
    45 
       
    46 JSONPRequest.prototype = {
       
    47     /**
       
    48      * Set up the success and failure handlers and the regex pattern used
       
    49      * to insert the temporary callback name in the url.
       
    50      *
       
    51      * @method _init
       
    52      * @param url {String} the url of the JSONP service
       
    53      * @param callback {Object|Function} Optional success callback or config
       
    54      *                  object containing success and failure functions and
       
    55      *                  the url regex.
       
    56      * @protected
       
    57      */
       
    58     _init : function (url, callback) {
       
    59         this.url = url;
       
    60 
       
    61         /**
       
    62          * Map of the number of requests currently pending responses per
       
    63          * generated proxy.  Used to ensure the proxy is not flushed if the
       
    64          * request times out and there is a timeout handler and success
       
    65          * handler, and used by connections configured to allowCache to make
       
    66          * sure the proxy isn't deleted until the last response has returned.
       
    67          *
       
    68          * @property _requests
       
    69          * @private
       
    70          * @type {Object}
       
    71          */
       
    72         this._requests = {};
       
    73 
       
    74         /**
       
    75          * Map of the number of timeouts received from the destination url
       
    76          * by generated proxy.  Used to ensure the proxy is not flushed if the
       
    77          * request times out and there is a timeout handler and success
       
    78          * handler, and used by connections configured to allowCache to make
       
    79          * sure the proxy isn't deleted until the last response has returned.
       
    80          *
       
    81          * @property _timeouts
       
    82          * @private
       
    83          * @type {Object}
       
    84          */
       
    85         this._timeouts = {};
       
    86 
       
    87         // Accept a function, an object, or nothing
       
    88         callback = (isFunction(callback)) ?
       
    89             { on: { success: callback } } :
       
    90             callback || {};
       
    91 
       
    92         var subs = callback.on || {};
       
    93 
       
    94         if (!subs.success) {
       
    95             subs.success = this._defaultCallback(url, callback);
       
    96         }
       
    97 
       
    98         // Apply defaults and store
       
    99         this._config = Y.merge({
       
   100                 context: this,
       
   101                 args   : [],
       
   102                 format : this._format,
       
   103                 allowCache: false
       
   104             }, callback, { on: subs });
       
   105     },
       
   106 
       
   107     /**
       
   108      * Override this method to provide logic to default the success callback if
       
   109      * it is not provided at construction.  This is overridden by jsonp-url to
       
   110      * parse the callback from the url string.
       
   111      *
       
   112      * @method _defaultCallback
       
   113      * @param url {String} the url passed at construction
       
   114      * @param config {Object} (optional) the config object passed at
       
   115      *                        construction
       
   116      * @return {Function}
       
   117      */
       
   118     _defaultCallback: function () {},
       
   119 
       
   120     /**
       
   121      * Issues the JSONP request.
       
   122      *
       
   123      * @method send
       
   124      * @param args* {any} any additional arguments to pass to the url formatter
       
   125      *              beyond the base url and the proxy function name
       
   126      * @chainable
       
   127      */
       
   128     send : function () {
       
   129         var self   = this,
       
   130             args   = Y.Array(arguments, 0, true),
       
   131             config = self._config,
       
   132             proxy  = self._proxy || Y.guid(),
       
   133             url;
       
   134 
       
   135         // TODO: support allowCache as time value
       
   136         if (config.allowCache) {
       
   137             self._proxy = proxy;
       
   138         }
       
   139 
       
   140         if (self._requests[proxy] === undefined) {
       
   141             self._requests[proxy] = 0;
       
   142         }
       
   143         if (self._timeouts[proxy] === undefined) {
       
   144             self._timeouts[proxy] = 0;
       
   145         }
       
   146         self._requests[proxy]++;
       
   147 
       
   148 
       
   149         args.unshift(self.url, 'YUI.Env.JSONP.' + proxy);
       
   150         url = config.format.apply(self, args);
       
   151 
       
   152         if (!config.on.success) {
       
   153             return self;
       
   154         }
       
   155 
       
   156         function wrap(fn, isTimeout) {
       
   157             return (isFunction(fn)) ?
       
   158                 function (data) {
       
   159                     var execute = true,
       
   160                         counter = '_requests';
       
   161 
       
   162                     //if (config.allowCache) {
       
   163                         // A lot of wrangling to make sure timeouts result in
       
   164                         // fewer success callbacks, but the proxy is properly
       
   165                         // cleaned up.
       
   166                         if (isTimeout) {
       
   167                             ++self._timeouts[proxy];
       
   168                             --self._requests[proxy];
       
   169                         } else {
       
   170                             if (!self._requests[proxy]) {
       
   171                                 execute = false;
       
   172                                 counter = '_timeouts';
       
   173                             }
       
   174                             --self[counter][proxy];
       
   175                         }
       
   176                     //}
       
   177 
       
   178                     if (!self._requests[proxy] && !self._timeouts[proxy]) {
       
   179                         delete YUI.Env.JSONP[proxy];
       
   180                     }
       
   181 
       
   182                     if (execute) {
       
   183                         fn.apply(config.context, [data].concat(config.args));
       
   184                     }
       
   185                 } :
       
   186                 null;
       
   187         }
       
   188 
       
   189         // Temporary un-sandboxed function alias
       
   190         // TODO: queuing
       
   191         YUI.Env.JSONP[proxy] = wrap(config.on.success);
       
   192 
       
   193         // Y.Get transactions block each other by design, but can easily
       
   194         //  be made non-blocking by just calling execute() on the transaction.
       
   195         // https://github.com/yui/yui3/pull/393#issuecomment-11961608
       
   196         Y.Get.js(url, {
       
   197             onFailure : wrap(config.on.failure),
       
   198             onTimeout : wrap(config.on.timeout, true),
       
   199             timeout   : config.timeout,
       
   200             charset   : config.charset,
       
   201             attributes: config.attributes,
       
   202             async     : config.async
       
   203         }).execute();
       
   204 
       
   205         return self;
       
   206     },
       
   207 
       
   208     /**
       
   209      * Default url formatter.  Looks for callback= in the url and appends it
       
   210      * if not present.  The supplied proxy name will be assigned to the query
       
   211      * param.  Override this method by passing a function as the
       
   212      * &quot;format&quot; property in the config object to the constructor.
       
   213      *
       
   214      * @method _format
       
   215      * @param url { String } the original url
       
   216      * @param proxy {String} the function name that will be used as a proxy to
       
   217      *      the configured callback methods.
       
   218      * @param args* {any} additional args passed to send()
       
   219      * @return {String} fully qualified JSONP url
       
   220      * @protected
       
   221      */
       
   222     _format: function (url, proxy) {
       
   223         return url.replace(/\{callback\}/, proxy);
       
   224     }
       
   225 };
       
   226 
       
   227 Y.JSONPRequest = JSONPRequest;
       
   228 
       
   229 /**
       
   230  *
       
   231  * @method jsonp
       
   232  * @param url {String} the url of the JSONP service with the {callback}
       
   233  *          placeholder where the callback function name typically goes.
       
   234  * @param c {Function|Object} Callback function accepting the JSON payload
       
   235  *          as its argument, or a configuration object (see above).
       
   236  * @param args* {any} additional arguments to pass to send()
       
   237  * @return {JSONPRequest}
       
   238  * @static
       
   239  * @for YUI
       
   240  */
       
   241 Y.jsonp = function (url,c) {
       
   242     var req = new Y.JSONPRequest(url,c);
       
   243     return req.send.apply(req, Y.Array(arguments, 2, true));
       
   244 };
       
   245 
       
   246 if (!YUI.Env.JSONP) {
       
   247     YUI.Env.JSONP = {};
       
   248 }
       
   249 
       
   250 
       
   251 }, '@VERSION@', {"requires": ["get", "oop"]});