/** * @author Don Griffin * * This singleton manages simulated Ajax responses. This allows application logic to be * written unaware that its Ajax calls are being handled by simulations ("simlets"). This * is currently done by hooking {@link Ext.data.Connection} methods, so all users of that * class (and {@link Ext.Ajax} since it is a derived class) qualify for simulation. * * The requires hooks are inserted when either the {@link #init} method is called or the * first {@link Ext.ux.ajax.Simlet} is registered. For example: * * Ext.onReady(function () { * initAjaxSim(); * * // normal stuff * }); * * function initAjaxSim () { * Ext.ux.ajax.SimManager.init({ * delay: 300 * }).register({ * '/app/data/url': { * stype: 'json', // use JsonSimlet (stype is like xtype for components) * data: [ * { foo: 42, bar: 'abc' }, * ... * ] * } * }); * } * * As many URL's as desired can be registered and associated with a {@link Ext.ux.ajax.Simlet}. To make * non-simulated Ajax requests once this singleton is initialized, add a `nosim:true` option * to the Ajax options: * * Ext.Ajax.request({ * url: 'page.php', * nosim: true, // ignored by normal Ajax request * params: { * id: 1 * }, * success: function(response){ * var text = response.responseText; * // process server response here * } * }); */ Ext.define('Ext.ux.ajax.SimManager', { singleton: true, requires: [ 'Ext.data.Connection', 'Ext.ux.ajax.SimXhr', 'Ext.ux.ajax.Simlet', 'Ext.ux.ajax.JsonSimlet' ], /** * @cfg {Ext.ux.ajax.Simlet} defaultSimlet * The {@link Ext.ux.ajax.Simlet} instance to use for non-matching URL's. By default, this will * return 404. Set this to null to use real Ajax calls for non-matching URL's. */ /** * @cfg {String} defaultType * The default `stype` to apply to generic {@link Ext.ux.ajax.Simlet} configuration objects. The * default is 'basic'. */ defaultType: 'basic', /** * @cfg {Number} delay * The number of milliseconds to delay before delivering a response to an async request. */ delay: 150, /** * @prop {Boolean} ready * True once this singleton has initialized and applied its Ajax hooks. * @private */ ready: false, constructor: function () { this.simlets = {}; }, getSimlet: function (url) { // Strip down to base URL (no query parameters or hash): var me = this, index = url.indexOf('?'); if (index < 0) { index = url.indexOf('#'); } if (index > 0) { url = url.substring(0, index); } return me.simlets[url] || me.defaultSimlet; }, getXhr: function (method, url, options, async) { var simlet = this.getSimlet(url); if (simlet) { return simlet.openRequest(method, url, options, async); } return null; }, /** * Initializes this singleton and applies configuration options. * @param {Object} config An optional object with configuration properties to apply. * @return {Ext.ux.ajax.SimManager} this * @markdown */ init: function (config) { var me = this; Ext.apply(me, config); if (!me.ready) { me.ready = true; if (!('defaultSimlet' in me)) { me.defaultSimlet = new Ext.ux.ajax.Simlet({ status: 404, statusText: 'Not Found' }); } me._openRequest = Ext.data.Connection.prototype.openRequest; Ext.data.Connection.override({ openRequest: function (options, requestOptions, async) { var xhr = !options.nosim && me.getXhr(requestOptions.method, requestOptions.url, options, async); if (!xhr) { xhr = this.callParent(arguments); } return xhr; } }); if (Ext.data.JsonP) { Ext.data.JsonP.self.override({ createScript: function (url, params, options) { var fullUrl = Ext.urlAppend(url, Ext.Object.toQueryString(params)), script = !options.nosim && me.getXhr('GET', fullUrl, options, true); if (!script) { script = this.callParent(arguments); } return script; }, loadScript: function (request) { var script = request.script; if (script.simlet) { script.jsonpCallback = request.params[request.callbackKey]; script.send(null); } else { this.callParent(arguments); } } }); } } return me; }, openRequest: function (method, url, async) { var opt = { method: method, url: url }; return this._openRequest.call(Ext.data.Connection.prototype, {}, opt, async); }, /** * Registeres one or more {@link Ext.ux.ajax.Simlet} instances. * @param {Array/Object} simlet Either a {@link Ext.ux.ajax.Simlet} instance or config, an Array * of such elements or an Object keyed by URL with values that are {@link Ext.ux.ajax.Simlet} * instances or configs. * @markdown */ register: function (simlet) { var me = this; me.init(); function reg (one) { var simlet = one; if (!simlet.isSimlet) { simlet = Ext.create('simlet.' + (simlet.stype || me.defaultType), one); } me.simlets[one.url] = simlet; simlet.manager = me; } if (Ext.isArray(simlet)) { Ext.each(simlet, reg); } else if (simlet.isSimlet || simlet.url) { reg(simlet); } else { Ext.Object.each(simlet, function (url, s) { s.url = url; reg(s); }); } return me; } });