-<!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre><span id='Ext-direct.Manager'>/**
-</span> * @class Ext.direct.Manager
- * <p><b><u>Overview</u></b></p>
- *
- * <p>Ext.Direct aims to streamline communication between the client and server
- * by providing a single interface that reduces the amount of common code
- * typically required to validate data and handle returned data packets
- * (reading data, error conditions, etc).</p>
- *
- * <p>The Ext.direct namespace includes several classes for a closer integration
- * with the server-side. The Ext.data namespace also includes classes for working
- * with Ext.data.Stores which are backed by data from an Ext.Direct method.</p>
- *
- * <p><b><u>Specification</u></b></p>
- *
- * <p>For additional information consult the
- * <a href="http://sencha.com/products/extjs/extdirect">Ext.Direct Specification</a>.</p>
- *
- * <p><b><u>Providers</u></b></p>
- *
- * <p>Ext.Direct uses a provider architecture, where one or more providers are
- * used to transport data to and from the server. There are several providers
- * that exist in the core at the moment:</p><div class="mdetail-params"><ul>
- *
- * <li>{@link Ext.direct.JsonProvider JsonProvider} for simple JSON operations</li>
- * <li>{@link Ext.direct.PollingProvider PollingProvider} for repeated requests</li>
- * <li>{@link Ext.direct.RemotingProvider RemotingProvider} exposes server side
- * on the client.</li>
- * </ul></div>
- *
- * <p>A provider does not need to be invoked directly, providers are added via
- * {@link Ext.direct.Manager}.{@link Ext.direct.Manager#add add}.</p>
- *
- * <p><b><u>Router</u></b></p>
- *
- * <p>Ext.Direct utilizes a "router" on the server to direct requests from the client
- * to the appropriate server-side method. Because the Ext.Direct API is completely
- * platform-agnostic, you could completely swap out a Java based server solution
- * and replace it with one that uses C# without changing the client side JavaScript
- * at all.</p>
- *
- * <p><b><u>Server side events</u></b></p>
- *
- * <p>Custom events from the server may be handled by the client by adding
- * listeners, for example:</p>
- * <pre><code>
-{"type":"event","name":"message","data":"Successfully polled at: 11:19:30 am"}
-
-// add a handler for a 'message' event sent by the server
-Ext.direct.Manager.on('message', function(e){
- out.append(String.format('&lt;p>&lt;i>{0}&lt;/i>&lt;/p>', e.data));
- out.el.scrollTo('t', 100000, true);
-});
- * </code></pre>
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>The source code</title>
+ <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../prettify/prettify.js"></script>
+ <style type="text/css">
+ .highlight { display: block; background-color: #ddd; }
+ </style>
+ <script type="text/javascript">
+ function highlight() {
+ document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
+ }
+ </script>
+</head>
+<body onload="prettyPrint(); highlight();">
+ <pre class="prettyprint lang-js"><span id='Ext-fx-Manager'>/**
+</span> * @class Ext.fx.Manager
+ * Animation Manager which keeps track of all current animations and manages them on a frame by frame basis.
+ * @private
* @singleton
*/
-Ext.define('Ext.direct.Manager', {
-
+Ext.define('Ext.fx.Manager', {
+
/* Begin Definitions */
+
singleton: true,
-
+
+ requires: ['Ext.util.MixedCollection',
+ 'Ext.fx.target.Element',
+ 'Ext.fx.target.CompositeElement',
+ 'Ext.fx.target.Sprite',
+ 'Ext.fx.target.CompositeSprite',
+ 'Ext.fx.target.Component'],
+
mixins: {
- observable: 'Ext.util.Observable'
- },
-
- requires: ['Ext.util.MixedCollection'],
-
- statics: {
- exceptions: {
- TRANSPORT: 'xhr',
- PARSE: 'parse',
- LOGIN: 'login',
- SERVER: 'exception'
- }
+ queue: 'Ext.fx.Queue'
},
-
+
/* End Definitions */
-
- constructor: function(){
- var me = this;
-
- me.addEvents(
-<span id='Ext-direct.Manager-event-event'> /**
-</span> * @event event
- * Fires after an event.
- * @param {event} e The Ext.direct.Event type that occurred.
- * @param {Ext.direct.Provider} provider The {@link Ext.direct.Provider Provider}.
- */
- 'event',
-<span id='Ext-direct.Manager-event-exception'> /**
-</span> * @event exception
- * Fires after an event exception.
- * @param {event} e The Ext.direct.Event type that occurred.
- */
- 'exception'
- );
- me.transactions = Ext.create('Ext.util.MixedCollection');
- me.providers = Ext.create('Ext.util.MixedCollection');
-
- me.mixins.observable.constructor.call(me);
- },
-
-<span id='Ext-direct.Manager-method-addProvider'> /**
-</span> * Adds an Ext.Direct Provider and creates the proxy or stub methods to execute server-side methods.
- * If the provider is not already connected, it will auto-connect.
- * <pre><code>
-var pollProv = new Ext.direct.PollingProvider({
- url: 'php/poll2.php'
-});
-Ext.direct.Manager.addProvider({
- "type":"remoting", // create a {@link Ext.direct.RemotingProvider}
- "url":"php\/router.php", // url to connect to the Ext.Direct server-side router.
- "actions":{ // each property within the actions object represents a Class
- "TestAction":[ // array of methods within each server side Class
- {
- "name":"doEcho", // name of method
- "len":1
- },{
- "name":"multiply",
- "len":1
- },{
- "name":"doForm",
- "formHandler":true, // handle form on server with Ext.Direct.Transaction
- "len":1
- }]
+ constructor: function() {
+ this.items = Ext.create('Ext.util.MixedCollection');
+ this.mixins.queue.constructor.call(this);
+
+ // this.requestAnimFrame = (function() {
+ // var raf = window.requestAnimationFrame ||
+ // window.webkitRequestAnimationFrame ||
+ // window.mozRequestAnimationFrame ||
+ // window.oRequestAnimationFrame ||
+ // window.msRequestAnimationFrame;
+ // if (raf) {
+ // return function(callback, element) {
+ // raf(callback);
+ // };
+ // }
+ // else {
+ // return function(callback, element) {
+ // window.setTimeout(callback, Ext.fx.Manager.interval);
+ // };
+ // }
+ // })();
},
- "namespace":"myApplication",// namespace to create the Remoting Provider in
-},{
- type: 'polling', // create a {@link Ext.direct.PollingProvider}
- url: 'php/poll.php'
-}, pollProv); // reference to previously created instance
- * </code></pre>
- * @param {Object/Array} provider Accepts either an Array of Provider descriptions (an instance
- * or config object for a Provider) or any number of Provider descriptions as arguments. Each
- * Provider description instructs Ext.Direct how to create client-side stub methods.
+
+<span id='Ext-fx-Manager-cfg-interval'> /**
+</span> * @cfg {Number} interval Default interval in miliseconds to calculate each frame. Defaults to 16ms (~60fps)
+ */
+ interval: 16,
+
+<span id='Ext-fx-Manager-cfg-forceJS'> /**
+</span> * @cfg {Boolean} forceJS Turn off to not use CSS3 transitions when they are available
*/
- addProvider : function(provider){
+ forceJS: true,
+
+ // @private Target factory
+ createTarget: function(target) {
var me = this,
- args = arguments,
- i = 0,
- len;
-
- if (args.length > 1) {
- for (len = args.length; i < len; ++i) {
- me.addProvider(args[i]);
+ useCSS3 = !me.forceJS && Ext.supports.Transitions,
+ targetObj;
+
+ me.useCSS3 = useCSS3;
+
+ // dom id
+ if (Ext.isString(target)) {
+ target = Ext.get(target);
+ }
+ // dom element
+ if (target && target.tagName) {
+ target = Ext.get(target);
+ targetObj = Ext.create('Ext.fx.target.' + 'Element' + (useCSS3 ? 'CSS' : ''), target);
+ me.targets.add(targetObj);
+ return targetObj;
+ }
+ if (Ext.isObject(target)) {
+ // Element
+ if (target.dom) {
+ targetObj = Ext.create('Ext.fx.target.' + 'Element' + (useCSS3 ? 'CSS' : ''), target);
}
- return;
+ // Element Composite
+ else if (target.isComposite) {
+ targetObj = Ext.create('Ext.fx.target.' + 'CompositeElement' + (useCSS3 ? 'CSS' : ''), target);
+ }
+ // Draw Sprite
+ else if (target.isSprite) {
+ targetObj = Ext.create('Ext.fx.target.Sprite', target);
+ }
+ // Draw Sprite Composite
+ else if (target.isCompositeSprite) {
+ targetObj = Ext.create('Ext.fx.target.CompositeSprite', target);
+ }
+ // Component
+ else if (target.isComponent) {
+ targetObj = Ext.create('Ext.fx.target.Component', target);
+ }
+ else if (target.isAnimTarget) {
+ return target;
+ }
+ else {
+ return null;
+ }
+ me.targets.add(targetObj);
+ return targetObj;
}
-
- // if provider has not already been instantiated
- if (!provider.isProvider) {
- provider = Ext.create('direct.' + provider.type + 'provider', provider);
+ else {
+ return null;
}
- me.providers.add(provider);
- provider.on('data', me.onProviderData, me);
+ },
+
+<span id='Ext-fx-Manager-method-addAnim'> /**
+</span> * Add an Anim to the manager. This is done automatically when an Anim instance is created.
+ * @param {Ext.fx.Anim} anim
+ */
+ addAnim: function(anim) {
+ var items = this.items,
+ task = this.task;
+ // var me = this,
+ // items = me.items,
+ // cb = function() {
+ // if (items.length) {
+ // me.task = true;
+ // me.runner();
+ // me.requestAnimFrame(cb);
+ // }
+ // else {
+ // me.task = false;
+ // }
+ // };
+ items.add(anim);
- if (!provider.isConnected()) {
- provider.connect();
+ // Start the timer if not already running
+ if (!task && items.length) {
+ task = this.task = {
+ run: this.runner,
+ interval: this.interval,
+ scope: this
+ };
+ Ext.TaskManager.start(task);
}
- return provider;
+ // //Start the timer if not already running
+ // if (!me.task && items.length) {
+ // me.requestAnimFrame(cb);
+ // }
},
-
-<span id='Ext-direct.Manager-method-getProvider'> /**
-</span> * Retrieve a {@link Ext.direct.Provider provider} by the
- * <b><tt>{@link Ext.direct.Provider#id id}</tt></b> specified when the provider is
- * {@link #addProvider added}.
- * @param {String/Ext.data.Provider} id The id of the provider, or the provider instance.
+
+<span id='Ext-fx-Manager-method-removeAnim'> /**
+</span> * Remove an Anim from the manager. This is done automatically when an Anim ends.
+ * @param {Ext.fx.Anim} anim
*/
- getProvider : function(id){
- return id.isProvider ? id : this.providers.get(id);
+ removeAnim: function(anim) {
+ // this.items.remove(anim);
+ var items = this.items,
+ task = this.task;
+ items.remove(anim);
+ // Stop the timer if there are no more managed Anims
+ if (task && !items.length) {
+ Ext.TaskManager.stop(task);
+ delete this.task;
+ }
},
-
-<span id='Ext-direct.Manager-method-removeProvider'> /**
-</span> * Removes the provider.
- * @param {String/Ext.direct.Provider} provider The provider instance or the id of the provider.
- * @return {Ext.direct.Provider} The provider, null if not found.
+
+<span id='Ext-fx-Manager-method-startingFilter'> /**
+</span> * @private
+ * Filter function to determine which animations need to be started
*/
- removeProvider : function(provider){
- var me = this,
- providers = me.providers,
- provider = provider.isProvider ? provider : providers.get(provider);
-
- if (provider) {
- provider.un('data', me.onProviderData, me);
- providers.remove(provider);
- return provider;
- }
- return null;
+ startingFilter: function(o) {
+ return o.paused === false && o.running === false && o.iterations > 0;
},
-
-<span id='Ext-direct.Manager-method-addTransaction'> /**
-</span> * Add a transaction to the manager.
- * @private
- * @param {Ext.direct.Transaction} transaction The transaction to add
- * @return {Ext.direct.Transaction} transaction
+
+<span id='Ext-fx-Manager-method-runningFilter'> /**
+</span> * @private
+ * Filter function to determine which animations are still running
*/
- addTransaction: function(transaction){
- this.transactions.add(transaction);
- return transaction;
+ runningFilter: function(o) {
+ return o.paused === false && o.running === true && o.isAnimator !== true;
},
-<span id='Ext-direct.Manager-method-removeTransaction'> /**
-</span> * Remove a transaction from the manager.
- * @private
- * @param {String/Ext.direct.Transaction} transaction The transaction/id of transaction to remove
- * @return {Ext.direct.Transaction} transaction
+<span id='Ext-fx-Manager-method-runner'> /**
+</span> * @private
+ * Runner function being called each frame
*/
- removeTransaction: function(transaction){
- transaction = this.getTransaction(transaction);
- this.transactions.remove(transaction);
- return transaction;
+ runner: function() {
+ var me = this,
+ items = me.items;
+
+ me.targetData = {};
+ me.targetArr = {};
+
+ // Single timestamp for all animations this interval
+ me.timestamp = new Date();
+
+ // Start any items not current running
+ items.filterBy(me.startingFilter).each(me.startAnim, me);
+
+ // Build the new attributes to be applied for all targets in this frame
+ items.filterBy(me.runningFilter).each(me.runAnim, me);
+
+ // Apply all the pending changes to their targets
+ me.applyPendingAttrs();
},
-<span id='Ext-direct.Manager-method-getTransaction'> /**
-</span> * Gets a transaction
- * @private
- * @param {String/Ext.direct.Transaction} transaction The transaction/id of transaction to get
- * @return {Ext.direct.Transaction}
+<span id='Ext-fx-Manager-method-startAnim'> /**
+</span> * @private
+ * Start the individual animation (initialization)
*/
- getTransaction: function(transaction){
- return transaction.isTransaction ? transaction : this.transactions.get(transaction);
+ startAnim: function(anim) {
+ anim.start(this.timestamp);
},
-
- onProviderData : function(provider, event){
+
+<span id='Ext-fx-Manager-method-runAnim'> /**
+</span> * @private
+ * Run the individual animation for this frame
+ */
+ runAnim: function(anim) {
+ if (!anim) {
+ return;
+ }
var me = this,
- i = 0,
- len;
-
- if (Ext.isArray(event)) {
- for (len = event.length; i < len; ++i) {
- me.onProviderData(provider, event[i]);
+ targetId = anim.target.getId(),
+ useCSS3 = me.useCSS3 && anim.target.type == 'element',
+ elapsedTime = me.timestamp - anim.startTime,
+ target, o;
+
+ this.collectTargetData(anim, elapsedTime, useCSS3);
+
+ // For CSS3 animation, we need to immediately set the first frame's attributes without any transition
+ // to get a good initial state, then add the transition properties and set the final attributes.
+ if (useCSS3) {
+ // Flush the collected attributes, without transition
+ anim.target.setAttr(me.targetData[targetId], true);
+
+ // Add the end frame data
+ me.targetData[targetId] = [];
+ me.collectTargetData(anim, anim.duration, useCSS3);
+
+ // Pause the animation so runAnim doesn't keep getting called
+ anim.paused = true;
+
+ target = anim.target.target;
+ // We only want to attach an event on the last element in a composite
+ if (anim.target.isComposite) {
+ target = anim.target.target.last();
}
- return;
+
+ // Listen for the transitionend event
+ o = {};
+ o[Ext.supports.CSS3TransitionEnd] = anim.lastFrame;
+ o.scope = anim;
+ o.single = true;
+ target.on(o);
+ }
+ // For JS animation, trigger the lastFrame handler if this is the final frame
+ else if (elapsedTime >= anim.duration) {
+ me.applyPendingAttrs(true);
+ delete me.targetData[targetId];
+ delete me.targetArr[targetId];
+ anim.lastFrame();
+ }
+ },
+
+<span id='Ext-fx-Manager-method-collectTargetData'> /**
+</span> * Collect target attributes for the given Anim object at the given timestamp
+ * @param {Ext.fx.Anim} anim The Anim instance
+ * @param {Number} timestamp Time after the anim's start time
+ */
+ collectTargetData: function(anim, elapsedTime, useCSS3) {
+ var targetId = anim.target.getId(),
+ targetData = this.targetData[targetId],
+ data;
+
+ if (!targetData) {
+ targetData = this.targetData[targetId] = [];
+ this.targetArr[targetId] = anim.target;
}
- if (event.name && event.name != 'event' && event.name != 'exception') {
- me.fireEvent(event.name, event);
- } else if (event.type == 'exception') {
- me.fireEvent('exception', event);
+
+ data = {
+ duration: anim.duration,
+ easing: (useCSS3 && anim.reverse) ? anim.easingFn.reverse().toCSS3() : anim.easing,
+ attrs: {}
+ };
+ Ext.apply(data.attrs, anim.runAnim(elapsedTime));
+ targetData.push(data);
+ },
+
+<span id='Ext-fx-Manager-method-applyPendingAttrs'> /**
+</span> * @private
+ * Apply all pending attribute changes to their targets
+ */
+ applyPendingAttrs: function(isLastFrame) {
+ var targetData = this.targetData,
+ targetArr = this.targetArr,
+ targetId;
+ for (targetId in targetData) {
+ if (targetData.hasOwnProperty(targetId)) {
+ targetArr[targetId].setAttr(targetData[targetId], false, isLastFrame);
+ }
}
- me.fireEvent('event', event, provider);
}
-}, function(){
- // Backwards compatibility
- Ext.Direct = Ext.direct.Manager;
});
-</pre></pre></body></html>
\ No newline at end of file
+</pre>
+</body>
+</html>