]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/datasource/datasource.js
Release 6.5.0
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / datasource / datasource.js
1 /*
2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
5 version: 3.3.0
6 build: 3167
7 */
8 YUI.add('datasource-local', function(Y) {
9
10 /**
11  * The DataSource utility provides a common configurable interface for widgets to
12  * access a variety of data, from JavaScript arrays to online database servers.
13  *
14  * @module datasource
15  */
16     
17 /**
18  * Provides the base DataSource implementation, which can be extended to
19  * create DataSources for specific data protocols, such as the IO Utility, the
20  * Get Utility, or custom functions.
21  *
22  * @module datasource
23  * @submodule datasource-local
24  */
25
26 /**
27  * Base class for the DataSource Utility.
28  * @class DataSource.Local
29  * @extends Base
30  * @constructor
31  */    
32 var LANG = Y.Lang,
33
34 DSLocal = function() {
35     DSLocal.superclass.constructor.apply(this, arguments);
36 };
37     
38     /////////////////////////////////////////////////////////////////////////////
39     //
40     // DataSource static properties
41     //
42     /////////////////////////////////////////////////////////////////////////////
43 Y.mix(DSLocal, {
44     /**
45      * Class name.
46      *
47      * @property NAME
48      * @type String
49      * @static     
50      * @final
51      * @value "dataSourceLocal"
52      */
53     NAME: "dataSourceLocal",
54
55     /////////////////////////////////////////////////////////////////////////////
56     //
57     // DataSource Attributes
58     //
59     /////////////////////////////////////////////////////////////////////////////
60
61     ATTRS: {
62         /**
63         * @attribute source
64         * @description Pointer to live data.
65         * @type MIXED
66         * @default null        
67         */
68         source: {
69             value: null
70         }
71     },
72
73     /**
74      * Global transaction counter.
75      *
76      * @property DataSource._tId
77      * @type Number
78      * @static
79      * @private
80      * @default 0
81      */
82     _tId: 0,
83
84     /**
85      * Global in-progress transaction objects.
86      *
87      * @property DataSource.transactions
88      * @type Object
89      * @static
90      */
91     transactions: {},
92
93     /**
94      * Returns data to callback.
95      *
96      * @method DataSource.issueCallback
97      * @param e {EventFacade} Event Facade.
98      * @param caller {DataSource} Calling DataSource instance.
99      * @static
100      */
101     issueCallback: function (e, caller) {
102         var error = (e.error || e.response.error);
103         if(error) {
104             e.error = e.error || e.response.error;
105             caller.fire("error", e);
106         }
107         if(e.callback) {
108             var callbackFunc = (error && e.callback.failure) || e.callback.success;
109             if (callbackFunc) {
110                 callbackFunc(e);
111             }
112         }
113     }
114 });
115     
116 Y.extend(DSLocal, Y.Base, {
117     /**
118     * Internal init() handler.
119     *
120     * @method initializer
121     * @param config {Object} Config object.
122     * @private        
123     */
124     initializer: function(config) {
125         this._initEvents();
126     },
127
128     /**
129     * This method creates all the events for this module.
130     * @method _initEvents
131     * @private        
132     */
133     _initEvents: function() {
134         /**
135          * Fired when a data request is received.
136          *
137          * @event request
138          * @param e {Event.Facade} Event Facade with the following properties:
139          * <dl>                          
140          * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
141          * <dt>request (Object)</dt> <dd>The request.</dd>
142          * <dt>callback (Object)</dt> <dd>The callback object.</dd>
143          * <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
144          * </dl>
145          * @preventable _defRequestFn
146          */
147         this.publish("request", {defaultFn: Y.bind("_defRequestFn", this), queuable:true});
148          
149         /**
150          * Fired when raw data is received.
151          *
152          * @event data
153          * @param e {Event.Facade} Event Facade with the following properties:
154          * <dl>
155          * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
156          * <dt>request (Object)</dt> <dd>The request.</dd>
157          * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
158          *     <dl>
159          *         <dt>success (Function)</dt> <dd>Success handler.</dd>
160          *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
161          *     </dl>
162          * </dd>
163          * <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
164          * <dt>data (Object)</dt> <dd>Raw data.</dd>
165          * </dl>
166          * @preventable _defDataFn
167          */
168         this.publish("data", {defaultFn: Y.bind("_defDataFn", this), queuable:true});
169
170         /**
171          * Fired when response is returned.
172          *
173          * @event response
174          * @param e {Event.Facade} Event Facade with the following properties:
175          * <dl>
176          * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
177          * <dt>request (Object)</dt> <dd>The request.</dd>
178          * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
179          *     <dl>
180          *         <dt>success (Function)</dt> <dd>Success handler.</dd>
181          *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
182          *     </dl>
183          * </dd>
184          * <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
185          * <dt>data (Object)</dt> <dd>Raw data.</dd>
186          * <dt>response (Object)</dt> <dd>Normalized response object with the following properties:
187          *     <dl>
188          *         <dt>results (Object)</dt> <dd>Parsed results.</dd>
189          *         <dt>meta (Object)</dt> <dd>Parsed meta data.</dd>
190          *         <dt>error (Boolean)</dt> <dd>Error flag.</dd>
191          *     </dl>
192          * </dd>
193          * </dl>
194          * @preventable _defResponseFn
195          */
196          this.publish("response", {defaultFn: Y.bind("_defResponseFn", this), queuable:true});
197
198         /**
199          * Fired when an error is encountered.
200          *
201          * @event error
202          * @param e {Event.Facade} Event Facade with the following properties:
203          * <dl>
204          * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
205          * <dt>request (Object)</dt> <dd>The request.</dd>
206          * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
207          *     <dl>
208          *         <dt>success (Function)</dt> <dd>Success handler.</dd>
209          *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
210          *     </dl>
211          * </dd>
212          * <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
213          * <dt>data (Object)</dt> <dd>Raw data.</dd>
214          * <dt>response (Object)</dt> <dd>Normalized response object with the following properties:
215          *     <dl>
216          *         <dt>results (Object)</dt> <dd>Parsed results.</dd>
217          *         <dt>meta (Object)</dt> <dd>Parsed meta data.</dd>
218          *         <dt>error (Object)</dt> <dd>Error object.</dd>
219          *     </dl>
220          * </dd>
221          * </dl>
222          */
223
224     },
225
226     /**
227      * Manages request/response transaction. Must fire <code>response</code>
228      * event when response is received. This method should be implemented by
229      * subclasses to achieve more complex behavior such as accessing remote data.
230      *
231      * @method _defRequestFn
232      * @param e {Event.Facade} Event Facadewith the following properties:
233      * <dl>
234      * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
235      * <dt>request (Object)</dt> <dd>The request.</dd>
236      * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
237      *     <dl>
238      *         <dt>success (Function)</dt> <dd>Success handler.</dd>
239      *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
240      *     </dl>
241      * </dd>
242      * <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
243      * </dl>
244      * @protected
245      */
246     _defRequestFn: function(e) {
247         var data = this.get("source");
248         
249         // Problematic data
250         if(LANG.isUndefined(data)) {
251             e.error = new Error("Local source undefined");
252         }
253
254         this.fire("data", Y.mix({data:data}, e));
255     },
256
257     /**
258      * Normalizes raw data into a response that includes results and meta properties.
259      *
260      * @method _defDataFn
261      * @param e {Event.Facade} Event Facade with the following properties:
262      * <dl>
263      * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
264      * <dt>request (Object)</dt> <dd>The request.</dd>
265      * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
266      *     <dl>
267      *         <dt>success (Function)</dt> <dd>Success handler.</dd>
268      *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
269      *     </dl>
270      * </dd>
271      * <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
272      * <dt>data (Object)</dt> <dd>Raw data.</dd>
273      * </dl>
274      * @protected
275      */
276     _defDataFn: function(e) {
277         var data = e.data,
278             meta = e.meta,
279             response = {
280                 results: (LANG.isArray(data)) ? data : [data],
281                 meta: (meta) ? meta : {}
282             };
283
284         this.fire("response", Y.mix({response: response}, e));
285     },
286
287     /**
288      * Sends data as a normalized response to callback.
289      *
290      * @method _defResponseFn
291      * @param e {Event.Facade} Event Facade with the following properties:
292      * <dl>
293      * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
294      * <dt>request (Object)</dt> <dd>The request.</dd>
295      * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
296      *     <dl>
297      *         <dt>success (Function)</dt> <dd>Success handler.</dd>
298      *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
299      *     </dl>
300      * </dd>
301      * <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
302      * <dt>data (Object)</dt> <dd>Raw data.</dd>
303      * <dt>response (Object)</dt> <dd>Normalized response object with the following properties:
304      *     <dl>
305      *         <dt>results (Object)</dt> <dd>Parsed results.</dd>
306      *         <dt>meta (Object)</dt> <dd>Parsed meta data.</dd>
307      *         <dt>error (Boolean)</dt> <dd>Error flag.</dd>
308      *     </dl>
309      * </dd>
310      * </dl>
311      * @protected
312      */
313     _defResponseFn: function(e) {
314         // Send the response back to the callback
315         DSLocal.issueCallback(e, this);
316     },
317     
318     /**
319      * Generates a unique transaction ID and fires <code>request</code> event.
320      *
321      * @method sendRequest
322      * @param request {Object} An object literal with the following properties:
323      *     <dl>
324      *     <dt><code>request</code></dt>
325      *     <dd>The request to send to the live data source, if any.</dd>
326      *     <dt><code>callback</code></dt>
327      *     <dd>An object literal with the following properties:
328      *         <dl>
329      *         <dt><code>success</code></dt>
330      *         <dd>The function to call when the data is ready.</dd>
331      *         <dt><code>failure</code></dt>
332      *         <dd>The function to call upon a response failure condition.</dd>
333      *         <dt><code>argument</code></dt>
334      *         <dd>Arbitrary data payload that will be passed back to the success and failure handlers.</dd>
335      *         </dl>
336      *     </dd>
337      *     <dt><code>cfg</code></dt>
338      *     <dd>Configuration object, if any.</dd>
339      *     </dl>
340      * @return {Number} Transaction ID.
341      */
342     sendRequest: function(request) {
343         request = request || {};
344         var tId = DSLocal._tId++;
345         this.fire("request", {tId:tId, request:request.request, callback:request.callback, cfg:request.cfg || {}});
346         return tId;
347     }
348 });
349     
350 Y.namespace("DataSource").Local = DSLocal;
351
352
353
354 }, '3.3.0' ,{requires:['base']});
355
356 YUI.add('datasource-io', function(Y) {
357
358 /**
359  * Provides a DataSource implementation which can be used to retrieve data via the IO Utility.
360  *
361  * @module datasource
362  * @submodule datasource-io
363  */
364
365 /**
366  * IO subclass for the DataSource Utility.
367  * @class DataSource.IO
368  * @extends DataSource.Local
369  * @constructor
370  */    
371 var DSIO = function() {
372     DSIO.superclass.constructor.apply(this, arguments);
373 };
374     
375
376     /////////////////////////////////////////////////////////////////////////////
377     //
378     // DataSource.IO static properties
379     //
380     /////////////////////////////////////////////////////////////////////////////
381 Y.mix(DSIO, {
382     /**
383      * Class name.
384      *
385      * @property NAME
386      * @type String
387      * @static     
388      * @final
389      * @value "dataSourceIO"
390      */
391     NAME: "dataSourceIO",
392
393
394     /////////////////////////////////////////////////////////////////////////////
395     //
396     // DataSource.IO Attributes
397     //
398     /////////////////////////////////////////////////////////////////////////////
399
400     ATTRS: {
401         /**
402          * Pointer to IO Utility.
403          *
404          * @attribute io
405          * @type Y.io
406          * @default Y.io
407          */
408         io: {
409             value: Y.io,
410             cloneDefaultValue: false
411         },
412         
413         /**
414          * Default IO Config.
415          *
416          * @attribute ioConfig
417          * @type Object
418          * @default null
419          */
420          ioConfig: {
421                 value: null
422          }
423     }
424 });
425     
426 Y.extend(DSIO, Y.DataSource.Local, {
427     /**
428     * Internal init() handler.
429     *
430     * @method initializer
431     * @param config {Object} Config object.
432     * @private
433     */
434     initializer: function(config) {
435         this._queue = {interval:null, conn:null, requests:[]};
436     },
437
438     /**
439     * IO success callback.
440     *
441     * @method successHandler
442     * @param id {String} Transaction ID.
443     * @param response {String} Response.
444     * @param e {Event.Facade} Event facade.
445     * @private
446     */
447     successHandler: function (id, response, e) {
448         var defIOConfig = this.get("ioConfig");
449
450         delete Y.DataSource.Local.transactions[e.tId];
451
452         this.fire("data", Y.mix({data:response}, e));
453         if (defIOConfig && defIOConfig.on && defIOConfig.on.success) {
454                 defIOConfig.on.success.apply(defIOConfig.context || Y, arguments);
455         }
456     },
457
458     /**
459     * IO failure callback.
460     *
461     * @method failureHandler
462     * @param id {String} Transaction ID.
463     * @param response {String} Response.
464     * @param e {Event.Facade} Event facade.
465     * @private
466     */
467     failureHandler: function (id, response, e) {
468         var defIOConfig = this.get("ioConfig");
469         
470         delete Y.DataSource.Local.transactions[e.tId];
471
472         e.error = new Error("IO data failure");
473         this.fire("data", Y.mix({data:response}, e));
474         if (defIOConfig && defIOConfig.on && defIOConfig.on.failure) {
475                 defIOConfig.on.failure.apply(defIOConfig.context || Y, arguments);
476         }
477     },
478     
479     /**
480     * @property _queue
481     * @description Object literal to manage asynchronous request/response
482     * cycles enabled if queue needs to be managed (asyncMode/ioConnMode):
483     * <dl>
484     *     <dt>interval {Number}</dt>
485     *         <dd>Interval ID of in-progress queue.</dd>
486     *     <dt>conn</dt>
487     *         <dd>In-progress connection identifier (if applicable).</dd>
488     *     <dt>requests {Object[]}</dt>
489     *         <dd>Array of queued request objects: {request:request, callback:callback}.</dd>
490     * </dl>
491     * @type Object
492     * @default {interval:null, conn:null, requests:[]}
493     * @private
494     */
495     _queue: null,
496
497     /**
498      * Passes query string to IO. Fires <code>response</code> event when
499      * response is received asynchronously.
500      *
501      * @method _defRequestFn
502      * @param e {Event.Facade} Event Facade with the following properties:
503      * <dl>
504      * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
505      * <dt>request (Object)</dt> <dd>The request.</dd>
506      * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
507      *     <dl>
508      *         <dt>success (Function)</dt> <dd>Success handler.</dd>
509      *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
510      *     </dl>
511      * </dd>
512      * <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
513      * </dl>
514      * @protected
515      */
516     _defRequestFn: function(e) {
517         var uri = this.get("source"),
518             io = this.get("io"),
519             defIOConfig = this.get("ioConfig"),
520             request = e.request,
521             cfg = Y.merge(defIOConfig, e.cfg, {
522                 on: Y.merge(defIOConfig, {
523                     success: this.successHandler,
524                     failure: this.failureHandler
525                 }),
526                 context: this,
527                 "arguments": e
528             });
529         
530         // Support for POST transactions
531         if(Y.Lang.isString(request)) {
532             if(cfg.method && (cfg.method.toUpperCase() === "POST")) {
533                 cfg.data = cfg.data ? cfg.data+request : request;
534             }
535             else {
536                 uri += request;
537             }
538         }
539         Y.DataSource.Local.transactions[e.tId] = io(uri, cfg);
540         return e.tId;
541     }
542 });
543   
544 Y.DataSource.IO = DSIO;
545
546
547
548 }, '3.3.0' ,{requires:['datasource-local', 'io-base']});
549
550 YUI.add('datasource-get', function(Y) {
551
552 /**
553  * Provides a DataSource implementation which can be used to retrieve data via the Get Utility.
554  *
555  * @module datasource
556  * @submodule datasource-get
557  */
558
559 /**
560  * Get Utility subclass for the DataSource Utility.
561  * @class DataSource.Get
562  * @extends DataSource.Local
563  * @constructor
564  */    
565 var DSGet = function() {
566     DSGet.superclass.constructor.apply(this, arguments);
567 };
568     
569     
570 Y.DataSource.Get = Y.extend(DSGet, Y.DataSource.Local, {
571     /**
572      * Passes query string to Get Utility. Fires <code>response</code> event when
573      * response is received asynchronously.
574      *
575      * @method _defRequestFn
576      * @param e {Event.Facade} Event Facade with the following properties:
577      * <dl>
578      * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
579      * <dt>request (Object)</dt> <dd>The request.</dd>
580      * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
581      *     <dl>
582      *         <dt>success (Function)</dt> <dd>Success handler.</dd>
583      *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
584      *     </dl>
585      * </dd>
586      * <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
587      * </dl>
588      * @protected
589      */
590     _defRequestFn: function(e) {
591         var uri  = this.get("source"),
592             get  = this.get("get"),
593             guid = Y.guid().replace(/\-/g, '_'),
594             generateRequest = this.get( "generateRequestCallback" ),
595             o;
596
597         /**
598          * Stores the most recent request id for validation against stale
599          * response handling.
600          *
601          * @property _last
602          * @type {String}
603          * @protected
604          */
605         this._last = guid;
606
607         // Dynamically add handler function with a closure to the callback stack
608         // for access to guid
609         YUI.Env.DataSource.callbacks[guid] = Y.bind(function(response) {
610             delete YUI.Env.DataSource.callbacks[guid];
611             delete Y.DataSource.Local.transactions[e.tId];
612
613             var process = this.get('asyncMode') !== "ignoreStaleResponses" ||
614                           this._last === guid;
615
616             if (process) {
617                 this.fire("data", Y.mix({ data: response }, e));
618             } else {
619             }
620
621         }, this);
622
623         // Add the callback param to the request url
624         uri += e.request + generateRequest.call( this, guid );
625
626
627         Y.DataSource.Local.transactions[e.tId] = get.script(uri, {
628             autopurge: true,
629             // Works in Firefox only....
630             onFailure: Y.bind(function(e, o) {
631                 delete YUI.Env.DataSource.callbacks[guid];
632                 delete Y.DataSource.Local.transactions[e.tId];
633
634                 e.error = new Error(o.msg || "Script node data failure");
635                 this.fire("data", e);
636             }, this, e),
637             onTimeout: Y.bind(function(e, o) {
638                 delete YUI.Env.DataSource.callbacks[guid];
639                 delete Y.DataSource.Local.transactions[e.tId];
640
641                 e.error = new Error(o.msg || "Script node data timeout");
642                 this.fire("data", e);
643             }, this, e)
644         });
645
646         return e.tId;
647     },
648
649
650     /**
651      * Default method for adding callback param to url.  See
652      * generateRequestCallback attribute.
653      *
654      * @method _generateRequest
655      * @param guid {String} unique identifier for callback function wrapper
656      * @protected
657      */
658      _generateRequest: function (guid) {
659         return "&" + this.get("scriptCallbackParam") +
660                 "=YUI.Env.DataSource.callbacks." + guid;
661     }
662
663 }, {
664
665     /**
666      * Class name.
667      *
668      * @property NAME
669      * @type String
670      * @static     
671      * @final
672      * @value "dataSourceGet"
673      */
674     NAME: "dataSourceGet",
675
676
677     ////////////////////////////////////////////////////////////////////////////
678     //
679     // DataSource.Get Attributes
680     //
681     ////////////////////////////////////////////////////////////////////////////
682     ATTRS: {
683         /**
684          * Pointer to Get Utility.
685          *
686          * @attribute get
687          * @type Y.Get
688          * @default Y.Get
689          */
690         get: {
691             value: Y.Get,
692             cloneDefaultValue: false
693         },
694
695         /**
696          * Defines request/response management in the following manner:
697          * <dl>
698          *     <!--<dt>queueRequests</dt>
699          *     <dd>If a request is already in progress, wait until response is
700          *     returned before sending the next request.</dd>
701          *     <dt>cancelStaleRequests</dt>
702          *     <dd>If a request is already in progress, cancel it before
703          *     sending the next request.</dd>-->
704          *     <dt>ignoreStaleResponses</dt>
705          *     <dd>Send all requests, but handle only the response for the most
706          *     recently sent request.</dd>
707          *     <dt>allowAll</dt>
708          *     <dd>Send all requests and handle all responses.</dd>
709          * </dl>
710          *
711          * @attribute asyncMode
712          * @type String
713          * @default "allowAll"
714          */
715         asyncMode: {
716             value: "allowAll"
717         },
718
719         /**
720          * Callback string parameter name sent to the remote script. By default,
721          * requests are sent to
722          * &#60;URI&#62;?&#60;scriptCallbackParam&#62;=callbackFunction
723          *
724          * @attribute scriptCallbackParam
725          * @type String
726          * @default "callback"
727          */
728         scriptCallbackParam : {
729             value: "callback"
730         },
731
732         /**
733          * Accepts the DataSource instance and a callback ID, and returns a callback
734          * param/value string that gets appended to the script URI. Implementers
735          * can customize this string to match their server's query syntax.
736          *
737          * @attribute generateRequestCallback
738          * @type Function
739          */
740         generateRequestCallback : {
741             value: function () {
742                 return this._generateRequest.apply(this, arguments);
743             }
744         }
745     }
746 });
747   
748 YUI.namespace("Env.DataSource.callbacks");
749
750
751
752 }, '3.3.0' ,{requires:['datasource-local', 'get']});
753
754 YUI.add('datasource-function', function(Y) {
755
756 /**
757  * Provides a DataSource implementation which can be used to retrieve data from a custom function.
758  *
759  * @module datasource
760  * @submodule datasource-function
761  */
762
763 /**
764  * Function subclass for the DataSource Utility.
765  * @class DataSource.Function
766  * @extends DataSource.Local
767  * @constructor
768  */    
769 var LANG = Y.Lang,
770
771     DSFn = function() {
772         DSFn.superclass.constructor.apply(this, arguments);
773     };
774     
775
776     /////////////////////////////////////////////////////////////////////////////
777     //
778     // DataSource.Function static properties
779     //
780     /////////////////////////////////////////////////////////////////////////////
781 Y.mix(DSFn, {
782     /**
783      * Class name.
784      *
785      * @property NAME
786      * @type String
787      * @static     
788      * @final
789      * @value "dataSourceFunction"
790      */
791     NAME: "dataSourceFunction",
792
793
794     /////////////////////////////////////////////////////////////////////////////
795     //
796     // DataSource.Function Attributes
797     //
798     /////////////////////////////////////////////////////////////////////////////
799
800     ATTRS: {
801         /**
802         * @attribute source
803         * @description Pointer to live data.
804         * @type MIXED
805         * @default null
806         */
807         source: {
808             validator: LANG.isFunction
809         }
810     }
811 });
812     
813 Y.extend(DSFn, Y.DataSource.Local, {
814     /**
815      * Passes query string to IO. Fires <code>response</code> event when
816      * response is received asynchronously.
817      *
818      * @method _defRequestFn
819      * @param e {Event.Facade} Event Facade with the following properties:
820      * <dl>
821      * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
822      * <dt>request (Object)</dt> <dd>The request.</dd>
823      * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
824      *     <dl>
825      *         <dt>success (Function)</dt> <dd>Success handler.</dd>
826      *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
827      *     </dl>
828      * </dd>
829      * <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
830      * </dl>
831      * @protected
832      */
833     _defRequestFn: function(e) {
834         var fn = this.get("source"),
835             response;
836             
837             if(fn) {
838                 try {
839                     response = fn(e.request, this, e);
840                     this.fire("data", Y.mix({data:response}, e));
841                 }
842                 catch(error) {
843                     e.error = error;
844                     this.fire("data", e);
845                 }
846             }
847             else {
848                 e.error = new Error("Function data failure");
849                 this.fire("data", e);
850             }
851             
852         return e.tId;
853     }
854 });
855   
856 Y.DataSource.Function = DSFn;
857     
858
859
860
861 }, '3.3.0' ,{requires:['datasource-local']});
862
863 YUI.add('datasource-cache', function(Y) {
864
865 /**
866  * Plugs DataSource with caching functionality.
867  *
868  * @module datasource
869  * @submodule datasource-cache
870  */
871
872 /**
873  * DataSourceCache extension binds Cache to DataSource.
874  * @class DataSourceCacheExtension
875  */
876 var DataSourceCacheExtension = function() {
877 };
878
879 Y.mix(DataSourceCacheExtension, {
880     /**
881      * The namespace for the plugin. This will be the property on the host which
882      * references the plugin instance.
883      *
884      * @property NS
885      * @type String
886      * @static
887      * @final
888      * @value "cache"
889      */
890     NS: "cache",
891
892     /**
893      * Class name.
894      *
895      * @property NAME
896      * @type String
897      * @static
898      * @final
899      * @value "dataSourceCacheExtension"
900      */
901     NAME: "dataSourceCacheExtension"
902 });
903
904 DataSourceCacheExtension.prototype = {
905     /**
906     * Internal init() handler.
907     *
908     * @method initializer
909     * @param config {Object} Config object.
910     * @private
911     */
912     initializer: function(config) {
913         this.doBefore("_defRequestFn", this._beforeDefRequestFn);
914         this.doBefore("_defResponseFn", this._beforeDefResponseFn);
915     },
916
917     /**
918      * First look for cached response, then send request to live data.
919      *
920      * @method _beforeDefRequestFn
921      * @param e {Event.Facade} Event Facade with the following properties:
922      * <dl>
923      * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
924      * <dt>request (Object)</dt> <dd>The request.</dd>
925      * <dt>callback (Object)</dt> <dd>The callback object.</dd>
926      * <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
927      * </dl>
928      * @protected
929      */
930     _beforeDefRequestFn: function(e) {
931         // Is response already in the Cache?
932         var entry = (this.retrieve(e.request)) || null;
933         if(entry && entry.response) {
934             this.get("host").fire("response", Y.mix(entry, e));
935             return new Y.Do.Halt("DataSourceCache extension halted _defRequestFn");
936         }
937     },
938
939     /**
940      * Adds data to cache before returning data.
941      *
942      * @method _beforeDefResponseFn
943      * @param e {Event.Facade} Event Facade with the following properties:
944      * <dl>
945      * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
946      * <dt>request (Object)</dt> <dd>The request.</dd>
947      * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
948      *     <dl>
949      *         <dt>success (Function)</dt> <dd>Success handler.</dd>
950      *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
951      *     </dl>
952      * </dd>
953      * <dt>data (Object)</dt> <dd>Raw data.</dd>
954      * <dt>response (Object)</dt> <dd>Normalized response object with the following properties:
955      *     <dl>
956      *         <dt>cached (Object)</dt> <dd>True when response is cached.</dd>
957      *         <dt>results (Object)</dt> <dd>Parsed results.</dd>
958      *         <dt>meta (Object)</dt> <dd>Parsed meta data.</dd>
959      *         <dt>error (Object)</dt> <dd>Error object.</dd>
960      *     </dl>
961      * </dd>
962      * <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
963      * </dl>
964      * @protected
965      */
966      _beforeDefResponseFn: function(e) {
967         // Add to Cache before returning
968         if(e.response && !e.cached) {
969             this.add(e.request, e.response);
970         }
971      }
972 };
973
974 Y.namespace("Plugin").DataSourceCacheExtension = DataSourceCacheExtension;
975
976
977
978 /**
979  * DataSource plugin adds cache functionality.
980  * @class DataSourceCache
981  * @extends Cache
982  * @uses Plugin.Base, DataSourceCachePlugin
983  */
984 function DataSourceCache(config) {
985     var cache = config && config.cache ? config.cache : Y.Cache,
986         tmpclass = Y.Base.create("dataSourceCache", cache, [Y.Plugin.Base, Y.Plugin.DataSourceCacheExtension]),
987         tmpinstance = new tmpclass(config);
988     tmpclass.NS = "tmpClass";
989     return tmpinstance;
990 }
991
992 Y.mix(DataSourceCache, {
993     /**
994      * The namespace for the plugin. This will be the property on the host which
995      * references the plugin instance.
996      *
997      * @property NS
998      * @type String
999      * @static
1000      * @final
1001      * @value "cache"
1002      */
1003     NS: "cache",
1004
1005     /**
1006      * Class name.
1007      *
1008      * @property NAME
1009      * @type String
1010      * @static
1011      * @final
1012      * @value "dataSourceCache"
1013      */
1014     NAME: "dataSourceCache"
1015 });
1016
1017
1018 Y.namespace("Plugin").DataSourceCache = DataSourceCache;
1019
1020
1021
1022 }, '3.3.0' ,{requires:['datasource-local', 'cache-base']});
1023
1024 YUI.add('datasource-jsonschema', function(Y) {
1025
1026 /**
1027  * Extends DataSource with schema-parsing on JSON data.
1028  *
1029  * @module datasource
1030  * @submodule datasource-jsonschema
1031  */
1032
1033 /**
1034  * Adds schema-parsing to the DataSource Utility.
1035  * @class DataSourceJSONSchema
1036  * @extends Plugin.Base
1037  */    
1038 var DataSourceJSONSchema = function() {
1039     DataSourceJSONSchema.superclass.constructor.apply(this, arguments);
1040 };
1041
1042 Y.mix(DataSourceJSONSchema, {
1043     /**
1044      * The namespace for the plugin. This will be the property on the host which
1045      * references the plugin instance.
1046      *
1047      * @property NS
1048      * @type String
1049      * @static
1050      * @final
1051      * @value "schema"
1052      */
1053     NS: "schema",
1054
1055     /**
1056      * Class name.
1057      *
1058      * @property NAME
1059      * @type String
1060      * @static
1061      * @final
1062      * @value "dataSourceJSONSchema"
1063      */
1064     NAME: "dataSourceJSONSchema",
1065
1066     /////////////////////////////////////////////////////////////////////////////
1067     //
1068     // DataSourceJSONSchema Attributes
1069     //
1070     /////////////////////////////////////////////////////////////////////////////
1071
1072     ATTRS: {
1073         schema: {
1074             //value: {}
1075         }
1076     }
1077 });
1078
1079 Y.extend(DataSourceJSONSchema, Y.Plugin.Base, {
1080     /**
1081     * Internal init() handler.
1082     *
1083     * @method initializer
1084     * @param config {Object} Config object.
1085     * @private
1086     */
1087     initializer: function(config) {
1088         this.doBefore("_defDataFn", this._beforeDefDataFn);
1089     },
1090
1091     /**
1092      * Parses raw data into a normalized response. To accommodate XHR responses,
1093      * will first look for data in data.responseText. Otherwise will just work
1094      * with data.
1095      *
1096      * @method _beforeDefDataFn
1097      * <dl>
1098      * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
1099      * <dt>request (Object)</dt> <dd>The request.</dd>
1100      * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
1101      *     <dl>
1102      *         <dt>success (Function)</dt> <dd>Success handler.</dd>
1103      *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
1104      *     </dl>
1105      * </dd>
1106      * <dt>data (Object)</dt> <dd>Raw data.</dd>
1107      * </dl>
1108      * @protected
1109      */
1110     _beforeDefDataFn: function(e) {
1111         var data = e.data ? (e.data.responseText ?  e.data.responseText : e.data) : e.data,
1112             response = Y.DataSchema.JSON.apply.call(this, this.get("schema"), data);
1113             
1114         // Default
1115         if(!response) {
1116             response = {
1117                 meta: {},
1118                 results: data
1119             };
1120         }
1121         
1122         this.get("host").fire("response", Y.mix({response:response}, e));
1123         return new Y.Do.Halt("DataSourceJSONSchema plugin halted _defDataFn");
1124     }
1125 });
1126     
1127 Y.namespace('Plugin').DataSourceJSONSchema = DataSourceJSONSchema;
1128
1129
1130
1131 }, '3.3.0' ,{requires:['datasource-local', 'plugin', 'dataschema-json']});
1132
1133 YUI.add('datasource-xmlschema', function(Y) {
1134
1135 /**
1136  * Extends DataSource with schema-parsing on XML data.
1137  *
1138  * @module datasource
1139  * @submodule datasource-xmlschema
1140  */
1141
1142 /**
1143  * Adds schema-parsing to the DataSource Utility.
1144  * @class DataSourceXMLSchema
1145  * @extends Plugin.Base
1146  */    
1147 var DataSourceXMLSchema = function() {
1148     DataSourceXMLSchema.superclass.constructor.apply(this, arguments);
1149 };
1150
1151 Y.mix(DataSourceXMLSchema, {
1152     /**
1153      * The namespace for the plugin. This will be the property on the host which
1154      * references the plugin instance.
1155      *
1156      * @property NS
1157      * @type String
1158      * @static
1159      * @final
1160      * @value "schema"
1161      */
1162     NS: "schema",
1163
1164     /**
1165      * Class name.
1166      *
1167      * @property NAME
1168      * @type String
1169      * @static
1170      * @final
1171      * @value "dataSourceXMLSchema"
1172      */
1173     NAME: "dataSourceXMLSchema",
1174
1175     /////////////////////////////////////////////////////////////////////////////
1176     //
1177     // DataSourceXMLSchema Attributes
1178     //
1179     /////////////////////////////////////////////////////////////////////////////
1180
1181     ATTRS: {
1182         schema: {
1183             //value: {}
1184         }
1185     }
1186 });
1187
1188 Y.extend(DataSourceXMLSchema, Y.Plugin.Base, {
1189     /**
1190     * Internal init() handler.
1191     *
1192     * @method initializer
1193     * @param config {Object} Config object.
1194     * @private
1195     */
1196     initializer: function(config) {
1197         this.doBefore("_defDataFn", this._beforeDefDataFn);
1198     },
1199
1200     /**
1201      * Parses raw data into a normalized response.
1202      *
1203      * @method _beforeDefDataFn
1204      * <dl>
1205      * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
1206      * <dt>request (Object)</dt> <dd>The request.</dd>
1207      * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
1208      *     <dl>
1209      *         <dt>success (Function)</dt> <dd>Success handler.</dd>
1210      *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
1211      *     </dl>
1212      * </dd>
1213      * <dt>data (Object)</dt> <dd>Raw data.</dd>
1214      * </dl>
1215      * @protected
1216      */
1217     _beforeDefDataFn: function(e) {
1218         var data = (Y.DataSource.IO && (this.get("host") instanceof Y.DataSource.IO) && e.data.responseXML && (e.data.responseXML.nodeType === 9)) ? e.data.responseXML : e.data,
1219             response = Y.DataSchema.XML.apply.call(this, this.get("schema"), data);
1220             
1221         // Default
1222         if(!response) {
1223             response = {
1224                 meta: {},
1225                 results: data
1226             };
1227         }
1228         
1229         this.get("host").fire("response", Y.mix({response:response}, e));
1230         return new Y.Do.Halt("DataSourceXMLSchema plugin halted _defDataFn");
1231     }
1232 });
1233     
1234 Y.namespace('Plugin').DataSourceXMLSchema = DataSourceXMLSchema;
1235
1236
1237
1238 }, '3.3.0' ,{requires:['datasource-local', 'plugin', 'dataschema-xml']});
1239
1240 YUI.add('datasource-arrayschema', function(Y) {
1241
1242 /**
1243  * Extends DataSource with schema-parsing on array data.
1244  *
1245  * @module datasource
1246  * @submodule datasource-arrayschema
1247  */
1248
1249 /**
1250  * Adds schema-parsing to the DataSource Utility.
1251  * @class DataSourceArraySchema
1252  * @extends Plugin.Base
1253  */    
1254 var DataSourceArraySchema = function() {
1255     DataSourceArraySchema.superclass.constructor.apply(this, arguments);
1256 };
1257
1258 Y.mix(DataSourceArraySchema, {
1259     /**
1260      * The namespace for the plugin. This will be the property on the host which
1261      * references the plugin instance.
1262      *
1263      * @property NS
1264      * @type String
1265      * @static
1266      * @final
1267      * @value "schema"
1268      */
1269     NS: "schema",
1270
1271     /**
1272      * Class name.
1273      *
1274      * @property NAME
1275      * @type String
1276      * @static
1277      * @final
1278      * @value "dataSourceArraySchema"
1279      */
1280     NAME: "dataSourceArraySchema",
1281
1282     /////////////////////////////////////////////////////////////////////////////
1283     //
1284     // DataSourceArraySchema Attributes
1285     //
1286     /////////////////////////////////////////////////////////////////////////////
1287
1288     ATTRS: {
1289         schema: {
1290             //value: {}
1291         }
1292     }
1293 });
1294
1295 Y.extend(DataSourceArraySchema, Y.Plugin.Base, {
1296     /**
1297     * Internal init() handler.
1298     *
1299     * @method initializer
1300     * @param config {Object} Config object.
1301     * @private
1302     */
1303     initializer: function(config) {
1304         this.doBefore("_defDataFn", this._beforeDefDataFn);
1305     },
1306
1307     /**
1308      * Parses raw data into a normalized response.
1309      *
1310      * @method _beforeDefDataFn
1311      * <dl>
1312      * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
1313      * <dt>request (Object)</dt> <dd>The request.</dd>
1314      * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
1315      *     <dl>
1316      *         <dt>success (Function)</dt> <dd>Success handler.</dd>
1317      *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
1318      *     </dl>
1319      * </dd>
1320      * <dt>data (Object)</dt> <dd>Raw data.</dd>
1321      * </dl>
1322      * @protected
1323      */
1324     _beforeDefDataFn: function(e) {
1325         var data = (Y.DataSource.IO && (this.get("host") instanceof Y.DataSource.IO) && Y.Lang.isString(e.data.responseText)) ? e.data.responseText : e.data,
1326             response = Y.DataSchema.Array.apply.call(this, this.get("schema"), data);
1327             
1328         // Default
1329         if(!response) {
1330             response = {
1331                 meta: {},
1332                 results: data
1333             };
1334         }
1335         
1336         this.get("host").fire("response", Y.mix({response:response}, e));
1337         return new Y.Do.Halt("DataSourceArraySchema plugin halted _defDataFn");
1338     }
1339 });
1340     
1341 Y.namespace('Plugin').DataSourceArraySchema = DataSourceArraySchema;
1342
1343
1344
1345 }, '3.3.0' ,{requires:['datasource-local', 'plugin', 'dataschema-array']});
1346
1347 YUI.add('datasource-textschema', function(Y) {
1348
1349 /**
1350  * Extends DataSource with schema-parsing on text data.
1351  *
1352  * @module datasource
1353  * @submodule datasource-textschema
1354  */
1355
1356 /**
1357  * Adds schema-parsing to the DataSource Utility.
1358  * @class DataSourceTextSchema
1359  * @extends Plugin.Base
1360  */    
1361 var DataSourceTextSchema = function() {
1362     DataSourceTextSchema.superclass.constructor.apply(this, arguments);
1363 };
1364
1365 Y.mix(DataSourceTextSchema, {
1366     /**
1367      * The namespace for the plugin. This will be the property on the host which
1368      * references the plugin instance.
1369      *
1370      * @property NS
1371      * @type String
1372      * @static
1373      * @final
1374      * @value "schema"
1375      */
1376     NS: "schema",
1377
1378     /**
1379      * Class name.
1380      *
1381      * @property NAME
1382      * @type String
1383      * @static
1384      * @final
1385      * @value "dataSourceTextSchema"
1386      */
1387     NAME: "dataSourceTextSchema",
1388
1389     /////////////////////////////////////////////////////////////////////////////
1390     //
1391     // DataSourceTextSchema Attributes
1392     //
1393     /////////////////////////////////////////////////////////////////////////////
1394
1395     ATTRS: {
1396         schema: {
1397             //value: {}
1398         }
1399     }
1400 });
1401
1402 Y.extend(DataSourceTextSchema, Y.Plugin.Base, {
1403     /**
1404     * Internal init() handler.
1405     *
1406     * @method initializer
1407     * @param config {Object} Config object.
1408     * @private
1409     */
1410     initializer: function(config) {
1411         this.doBefore("_defDataFn", this._beforeDefDataFn);
1412     },
1413
1414     /**
1415      * Parses raw data into a normalized response.
1416      *
1417      * @method _beforeDefDataFn
1418      * <dl>
1419      * <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
1420      * <dt>request (Object)</dt> <dd>The request.</dd>
1421      * <dt>callback (Object)</dt> <dd>The callback object with the following properties:
1422      *     <dl>
1423      *         <dt>success (Function)</dt> <dd>Success handler.</dd>
1424      *         <dt>failure (Function)</dt> <dd>Failure handler.</dd>
1425      *     </dl>
1426      * </dd>
1427      * <dt>data (Object)</dt> <dd>Raw data.</dd>
1428      * </dl>
1429      * @protected
1430      */
1431     _beforeDefDataFn: function(e) {
1432         var data = (Y.DataSource.IO && (this.get("host") instanceof Y.DataSource.IO) && Y.Lang.isString(e.data.responseText)) ? e.data.responseText : e.data,
1433             response = Y.DataSchema.Text.apply.call(this, this.get("schema"), data);
1434             
1435         // Default
1436         if(!response) {
1437             response = {
1438                 meta: {},
1439                 results: data
1440             };
1441         }
1442         
1443         this.get("host").fire("response", Y.mix({response:response}, e));
1444         return new Y.Do.Halt("DataSourceTextSchema plugin halted _defDataFn");
1445     }
1446 });
1447     
1448 Y.namespace('Plugin').DataSourceTextSchema = DataSourceTextSchema;
1449
1450
1451
1452 }, '3.3.0' ,{requires:['datasource-local', 'plugin', 'dataschema-text']});
1453
1454 YUI.add('datasource-polling', function(Y) {
1455
1456 /**
1457  * Extends DataSource with polling functionality.
1458  *
1459  * @module datasource
1460  * @submodule datasource-polling
1461  */
1462     
1463 /**
1464  * Adds polling to the DataSource Utility.
1465  * @class Pollable
1466  * @extends DataSource.Local
1467  */    
1468 function Pollable() {
1469     this._intervals = {};
1470 }
1471
1472 Pollable.prototype = {
1473
1474     /**
1475     * @property _intervals
1476     * @description Hash of polling interval IDs that have been enabled,
1477     * stored here to be able to clear all intervals.
1478     * @private
1479     */
1480     _intervals: null,
1481
1482     /**
1483      * Sets up a polling mechanism to send requests at set intervals and
1484      * forward responses to given callback.
1485      *
1486      * @method setInterval
1487      * @param msec {Number} Length of interval in milliseconds.
1488      * @param request {Object} An object literal with the following properties:
1489      *     <dl>
1490      *     <dt><code>request</code></dt>
1491      *     <dd>The request to send to the live data source, if any.</dd>
1492      *     <dt><code>callback</code></dt>
1493      *     <dd>An object literal with the following properties:
1494      *         <dl>
1495      *         <dt><code>success</code></dt>
1496      *         <dd>The function to call when the data is ready.</dd>
1497      *         <dt><code>failure</code></dt>
1498      *         <dd>The function to call upon a response failure condition.</dd>
1499      *         <dt><code>argument</code></dt>
1500      *         <dd>Arbitrary data payload that will be passed back to the success and failure handlers.</dd>
1501      *         </dl>
1502      *     </dd>
1503      *     <dt><code>cfg</code></dt>
1504      *     <dd>Configuration object, if any.</dd>
1505      *     </dl>
1506      * @return {Number} Interval ID.
1507      */
1508     setInterval: function(msec, callback) {
1509         var x = Y.later(msec, this, this.sendRequest, [ callback ], true);
1510         this._intervals[x.id] = x;
1511         return x.id;
1512     },
1513
1514     /**
1515      * Disables polling mechanism associated with the given interval ID.
1516      *
1517      * @method clearInterval
1518      * @param id {Number} Interval ID.
1519      */
1520     clearInterval: function(id, key) {
1521         // In case of being called by clearAllIntervals()
1522         id = key || id;
1523         if(this._intervals[id]) {
1524             // Clear the interval
1525             this._intervals[id].cancel();
1526             // Clear from tracker
1527             delete this._intervals[id];
1528         }
1529     },
1530
1531     /**
1532      * Clears all intervals.
1533      *
1534      * @method clearAllIntervals
1535      */
1536     clearAllIntervals: function() {
1537         Y.each(this._intervals, this.clearInterval, this);
1538     }
1539 };
1540     
1541 Y.augment(Y.DataSource.Local, Pollable);
1542
1543
1544
1545 }, '3.3.0' ,{requires:['datasource-local']});
1546
1547
1548
1549 YUI.add('datasource', function(Y){}, '3.3.0' ,{use:['datasource-local','datasource-io','datasource-get','datasource-function','datasource-cache','datasource-jsonschema','datasource-xmlschema','datasource-arrayschema','datasource-textschema','datasource-polling']});
1550