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