    /** * Provides for repetitive polling of the server at distinct {@link #interval intervals}. * The initial request for data originates from the client, and then is responded to by the * server. *  * Configuration for the PollingProvider can be generated by the server-side * API portion of the Ext Direct stack. * * An instance of PollingProvider may be created directly via the new keyword or by simply * specifying `type = 'polling'`. For example: * *      var pollA = new Ext.direct.PollingProvider({ *          type:'polling', *          url: 'php/pollA.php', *      }); *      Ext.direct.Manager.addProvider(pollA); *      pollA.disconnect(); *       *      Ext.direct.Manager.addProvider({ *          type:'polling', *          url: 'php/pollB.php', *          id: 'pollB-provider' *      }); *      var pollB = Ext.direct.Manager.getProvider('pollB-provider'); * */Ext.define('Ext.direct.PollingProvider', {    extend: 'Ext.direct.JsonProvider',    alias:  'direct.pollingprovider',        requires: [        'Ext.Ajax',        'Ext.util.TaskRunner',        'Ext.direct.ExceptionEvent'    ],        type: 'polling',        /**     * @cfg {Number} [interval=3000]     * How often to poll the server-side in milliseconds. Defaults to every 3 seconds.     */    interval: 3000,     /**     * @cfg {Object} [baseParams]     * An object containing properties which are to be sent as parameters on every     * polling request. Note that if baseParams are set and {@link #url} parameter     * is an URL string, poll requests will use POST method instead of default GET.     */        /**     * @cfg {String/Function} url     * The url which the PollingProvider should contact with each request. This can also be     * an imported Ext Direct method which will be passed baseParams as named arguments.     *     * *Note* that using Function `url` is deprecated, use {@link #pollFn} instead.     * @deprecated 5.1.0     */        /**     * @cfg {String/Function} pollFn     *     * Ext Direct method to use for polling. If a method name is provided as a string,     * the actual function will not be resolved until the first time this provider     * is connected.     *     * The method should accept named arguments and will be passed {@link #baseParams}     * if set.     */        /**     * @cfg {Number} [timeout]     *     * The timeout to use for each request.     */        /**     * @event beforepoll     * @preventable     * Fired immediately before a poll takes place.     *     * @param {Ext.direct.PollingProvider} this     */     /**     * @event poll     * Fired immediately after a poll takes place.     *     * @param {Ext.direct.PollingProvider} this     */        constructor: function(config) {        var me = this;                me.callParent([config]);                me.pollTask = Ext.TaskManager.newTask({            run: me.runPoll,            interval: me.interval,            scope: me        });    },        destroy: function() {        this.pollTask = null;                this.callParent();    },        doConnect: function() {        var me = this,            url = me.url,            pollFn = me.pollFn;                // It is important that pollFn resolution happens at the time when         // Provider is first connected, and not at construction time. If         // pollFn is configured as a string, the API stub may not exist yet         // when PollingProvider is constructed.         if (pollFn && Ext.isString(pollFn)) {            //<debug>             var fnName = pollFn;            //</debug>                         me.pollFn = pollFn = Ext.direct.Manager.parseMethod(pollFn);                        //<debug>             if (!Ext.isFunction(pollFn)) {                Ext.raise("Cannot resolve Ext Direct API method " + fnName +                                " for PollingProvider");            }            //</debug>         }        else if (Ext.isFunction(url)) {            //<debug>             Ext.log.warn('Using a function for url is deprecated, use pollFn instead.');            //</debug>                         me.pollFn = pollFn = url;            me.url = url = null;        }                if (url || pollFn) {            me.setInterval(me.interval);                        me.pollTask.start();        }    },     doDisconnect: function() {        if (this.pollTask) {            this.pollTask.stop();        }    },        getInterval: function() {        return this.pollTask && this.pollTask.interval;    },        setInterval: function(interval) {        var me = this,            pollTask = me.pollTask;                //<debug>         if (interval < 100) {            Ext.raise("Attempting to configure PollProvider " + me.id +                            " with interval that is less than 100ms.");                                    }        //</debug>                 me.interval = pollTask.interval = interval;                if (me.isConnected()) {            pollTask.restart(interval);        }    },        /**     * @private     */    runPoll: function() {        var me = this,            url = me.url,            pollFn = me.pollFn,            baseParams = me.baseParams,            args, request;                if (me.fireEvent('beforepoll', me) !== false) {            if (pollFn) {                args = pollFn.directCfg.method.getArgs({                    params: baseParams !== undefined ? baseParams : {},                    callback: me.onPollFn,                    scope: me                });                                pollFn.apply(window, args);            }            else {                request = {                    url: url,                    callback: me.onData,                    scope: me,                    params: baseParams,                    headers: me.getHeaders()                };                                if (me.timeout != null) {                    request.timeout = me.timeout;                }                                me.sendAjaxRequest(request);            }                        me.fireEvent('poll', me);        }    },     /**     * @private     */    onData: function(opt, success, response) {        var me = this,             i, len, events, event;                if (success) {            events = me.createEvents(response);                        for (i = 0, len = events.length; i < len; ++i) {                event = events[i];                                me.fireEvent('data', me, event);                                if (!event.status) {                    me.fireEvent('exception', me, event);                }            }        }        else {            event = new Ext.direct.ExceptionEvent({                data: null,                code: Ext.direct.Manager.exceptions.TRANSPORT,                message: 'Unable to connect to the server.',                xhr: response            });                        me.fireEvent('data', me, event);            me.fireEvent('exception', me, event);        }                me.callParent([opt, success, response]);    },        /**     * @private     */    onPollFn: function(result, event, success, options) {        this.onData(null, success, { responseText: result });    },        inheritableStatics: {        /**         * @private         * @static         * @inheritable         */        checkConfig: function(config) {            // Polling provider needs either URI or pollFn             return config && config.type === 'polling' &&                   (config.url || config.pollFn);        }    }});