src/cm/media/js/lib/yui/yui_3.10.3/docs/promise/plugin-example.html
changeset 525 89ef5ed3c48b
equal deleted inserted replaced
524:322d0feea350 525:89ef5ed3c48b
       
     1 <!DOCTYPE html>
       
     2 <html lang="en">
       
     3 <head>
       
     4     <meta charset="utf-8">
       
     5     <title>Example: Creating a Node Plugin that chains transitions</title>
       
     6     <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=PT+Sans:400,700,400italic,700italic">
       
     7     <link rel="stylesheet" href="../../build/cssgrids/cssgrids-min.css">
       
     8     <link rel="stylesheet" href="../assets/css/main.css">
       
     9     <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
       
    10     <link rel="shortcut icon" type="image/png" href="../assets/favicon.png">
       
    11     <script src="../../build/yui/yui-min.js"></script>
       
    12     
       
    13 </head>
       
    14 <body>
       
    15 <!--
       
    16 <a href="https://github.com/yui/yui3"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a>
       
    17 -->
       
    18 <div id="doc">
       
    19     <div id="hd">
       
    20         <h1><img src="http://yuilibrary.com/img/yui-logo.png"></h1>
       
    21     </div>
       
    22     
       
    23         <a href="#toc" class="jump">Jump to Table of Contents</a>
       
    24     
       
    25 
       
    26             <h1>Example: Creating a Node Plugin that chains transitions</h1>
       
    27     <div class="yui3-g">
       
    28         <div class="yui3-u-3-4">
       
    29             <div id="main">
       
    30                 <div class="content"><style scoped>
       
    31     #square {
       
    32         width: 100px;
       
    33         height: 100px;
       
    34         background: gray;
       
    35         position: relative;
       
    36         margin: 20px;
       
    37     }
       
    38 </style>
       
    39 
       
    40 
       
    41 <div class="intro">
       
    42     <p>
       
    43         In order to run transitions sequentially, you would normally have to use the callback provided by <code>node.transition()</code>. This example shows how to create your own Node plugin based on promises that lets you chain CSS transitions.
       
    44     </p>
       
    45 </div>
       
    46 
       
    47 <div class="example yui3-skin-sam">
       
    48     <button id="without-plugin">Without Plugin</button>
       
    49 <button id="with-plugin">With Plugin</button>
       
    50 <div id="square"></div>
       
    51 
       
    52     <script>
       
    53 YUI().use('promise', 'transition', 'node-pluginhost', function (Y) {
       
    54 
       
    55 // NodePromise will represent a YUI Node
       
    56 function NodePromise() {
       
    57     NodePromise.superclass.constructor.apply(this, arguments);
       
    58 }
       
    59 Y.extend(NodePromise, Y.Promise);
       
    60 
       
    61 // This method takes the same "config" parameter as Node's transition method
       
    62 // but returns a NodePromise instead
       
    63 NodePromise.prototype.transition = function (config) {
       
    64     // We call this.then to ensure the promise is fulfilled.
       
    65     // Since we will be creating a chain of transitions this means we will be
       
    66     // waiting for the previous transition to end
       
    67     return this.then(function (node) {
       
    68         // As noted in the user guide, returning a promise inside the then()
       
    69         // callback causes the promise returned by then() to be synced with this
       
    70         // new promise. This is a way to control when the returned promise is
       
    71         // fulfilled
       
    72         return new Y.Promise(function (fulfill, reject) {
       
    73             node.transition(config, function () {
       
    74                 // The transition is done, signal the promise that all is ready
       
    75                 // by fulfilling it with the same node
       
    76                 fulfill(node);
       
    77             });
       
    78         });
       
    79     });
       
    80 };
       
    81 
       
    82 function PromisePlugin(config) {
       
    83     // Create a private NodePromise instance that points to the plugin host
       
    84     this._promise = new NodePromise(function (fulfill) {
       
    85         // Since this is a Node plugin, config.host will be an instance of Node
       
    86         fulfill(config.host);
       
    87     });
       
    88 }
       
    89 
       
    90 // Set up the plugin's namespace
       
    91 PromisePlugin.NS = 'promise';
       
    92 
       
    93 PromisePlugin.prototype.transition = function (config) {
       
    94     // Simply point to the private promise's transition method
       
    95     return this._promise.transition(config);
       
    96 };
       
    97 
       
    98 
       
    99 var square = Y.one('#square');
       
   100 square.plug(PromisePlugin);
       
   101 
       
   102 function resetStyles() {
       
   103     square.setStyles({
       
   104         width: '100px',
       
   105         height: '100px',
       
   106         left: '0'
       
   107     });
       
   108 }
       
   109 
       
   110 Y.one('#without-plugin').on('click', function () {
       
   111     resetStyles();
       
   112     square
       
   113         .transition({width: '300px'})
       
   114         .transition({height: '300px'})
       
   115         .transition({left: '200px'});
       
   116 });
       
   117 Y.one('#with-plugin').on('click', function () {
       
   118     resetStyles();
       
   119     square.promise
       
   120         .transition({width: '300px'})
       
   121         .transition({height: '300px'})
       
   122         .transition({left: '200px'});
       
   123 });
       
   124 
       
   125 });
       
   126 </script>
       
   127 
       
   128 </div>
       
   129 
       
   130 <h2 id="using-promises-to-chain-css-transitions">Using Promises to Chain CSS Transitions</h2>
       
   131 
       
   132 <h3 id="the-plan">The plan</h3>
       
   133 
       
   134 <p>Plugins are a way to add functionality to Node without modifying its existing methods. They also are usually subclasses of Plugin.Base that contain various methods to interact with in a different way with a node. In our case we will skip the use of Plugin.Base to focus on returning promises from a plugin method.</p>
       
   135 
       
   136 <p>The plan is to create a Promise subclass that represents a Node and store one of these promises in the plugin instance. Then the plugin's <code>transition</code> method will return a new promise based on the one already stored.</p>
       
   137 
       
   138 <h3 id="creating-a-promise-subclass">Creating a Promise Subclass</h3>
       
   139 
       
   140 <p>Promises represent a value. Since we want to chain transitions on a Node we need to create a Promise sublcass that represents a Node. Promises can be extended the same way as any other YUI class by using <a href="http://yuilibrary.com/yui/docs/api//classes/YUI.html#method_extend"><code>Y.extend</code></a>.</p>
       
   141 
       
   142 <pre class="code prettyprint">&#x2F;&#x2F; NodePromise will represent a YUI Node
       
   143 function NodePromise() {
       
   144     NodePromise.superclass.constructor.apply(this, arguments);
       
   145 }
       
   146 Y.extend(NodePromise, Y.Promise);</pre>
       
   147 
       
   148 
       
   149 <p>The next step is to add the <code>transition()</code> method to this promise and have it return a promise that is fulfilled when the transition is completed.</p>
       
   150 
       
   151 <pre class="code prettyprint">&#x2F;&#x2F; This method takes the same &quot;config&quot; parameter as Node&#x27;s transition method
       
   152 &#x2F;&#x2F; but returns a NodePromise instead
       
   153 NodePromise.prototype.transition = function (config) {
       
   154     &#x2F;&#x2F; We call this.then to ensure the promise is fulfilled.
       
   155     &#x2F;&#x2F; Since we will be creating a chain of transitions this means we will be
       
   156     &#x2F;&#x2F; waiting for the previous transition to end
       
   157     return this.then(function (node) {
       
   158         &#x2F;&#x2F; As noted in the user guide, returning a promise inside the then()
       
   159         &#x2F;&#x2F; callback causes the promise returned by then() to be synced with this
       
   160         &#x2F;&#x2F; new promise. This is a way to control when the returned promise is
       
   161         &#x2F;&#x2F; fulfilled
       
   162         return new Y.Promise(function (fulfill, reject) {
       
   163             node.transition(config, function () {
       
   164                 &#x2F;&#x2F; The transition is done, signal the promise that all is ready
       
   165                 &#x2F;&#x2F; by fulfilling it with the same node
       
   166                 fulfill(node);
       
   167             });
       
   168         });
       
   169     });
       
   170 };</pre>
       
   171 
       
   172 
       
   173 <h3 id="creating-the-plugin">Creating the Plugin</h3>
       
   174 
       
   175 <p>Our plugin is a very simple class that contains a NodePromise. In order for it to let us write chains of transitions like <code>node.promise.transition(config1).transition(config2)</code> we will add a <code>transition</code> method to it that simply points to the NodePromise's same method.</p>
       
   176 
       
   177 <pre class="code prettyprint">function PromisePlugin(config) {
       
   178     &#x2F;&#x2F; Create a private NodePromise instance that points to the plugin host
       
   179     this._promise = new NodePromise(function (fulfill) {
       
   180         &#x2F;&#x2F; Since this is a Node plugin, config.host will be an instance of Node
       
   181         fulfill(config.host);
       
   182     });
       
   183 }
       
   184 
       
   185 &#x2F;&#x2F; Set up the plugin&#x27;s namespace
       
   186 PromisePlugin.NS = &#x27;promise&#x27;;
       
   187 
       
   188 PromisePlugin.prototype.transition = function (config) {
       
   189     &#x2F;&#x2F; Simply point to the private promise&#x27;s transition method
       
   190     return this._promise.transition(config);
       
   191 };</pre>
       
   192 
       
   193 
       
   194 <h3 id="using-the-plugin">Using the Plugin</h3>
       
   195 
       
   196 <p>Now that we have the plugin ready, we can easily chain transitions from the plugin instance:</p>
       
   197 
       
   198 <pre class="code prettyprint">var square = Y.one(&#x27;#square&#x27;);
       
   199 square.plug(PromisePlugin);
       
   200 
       
   201 &#x2F;&#x2F; run a sequence of transitions
       
   202 square.promise
       
   203     .transition({width: &#x27;300px&#x27;})
       
   204     .transition({height: &#x27;300px&#x27;})
       
   205     .transition({left: &#x27;200px&#x27;});</pre>
       
   206 
       
   207 
       
   208 <h3 id="fullcode">Full Code Listing</h3>
       
   209 <h4 id="html">HTML</h4>
       
   210 <pre class="code prettyprint">&lt;button id=&quot;without-plugin&quot;&gt;Without Plugin&lt;&#x2F;button&gt;
       
   211 &lt;button id=&quot;with-plugin&quot;&gt;With Plugin&lt;&#x2F;button&gt;
       
   212 &lt;div id=&quot;square&quot;&gt;&lt;&#x2F;div&gt;</pre>
       
   213 
       
   214 
       
   215 <h4 id="css">CSS</h4>
       
   216 <pre class="code prettyprint">&lt;style scoped&gt;
       
   217     #square {
       
   218         width: 100px;
       
   219         height: 100px;
       
   220         background: gray;
       
   221         position: relative;
       
   222         margin: 20px;
       
   223     }
       
   224 &lt;&#x2F;style&gt;</pre>
       
   225 
       
   226 
       
   227 <h4 id="javascript">JavaScript</h4>
       
   228 <pre class="code prettyprint">&lt;script&gt;
       
   229 YUI().use(&#x27;promise&#x27;, &#x27;transition&#x27;, &#x27;node-pluginhost&#x27;, function (Y) {
       
   230 
       
   231 &#x2F;&#x2F; NodePromise will represent a YUI Node
       
   232 function NodePromise() {
       
   233     NodePromise.superclass.constructor.apply(this, arguments);
       
   234 }
       
   235 Y.extend(NodePromise, Y.Promise);
       
   236 
       
   237 &#x2F;&#x2F; This method takes the same &quot;config&quot; parameter as Node&#x27;s transition method
       
   238 &#x2F;&#x2F; but returns a NodePromise instead
       
   239 NodePromise.prototype.transition = function (config) {
       
   240     &#x2F;&#x2F; We call this.then to ensure the promise is fulfilled.
       
   241     &#x2F;&#x2F; Since we will be creating a chain of transitions this means we will be
       
   242     &#x2F;&#x2F; waiting for the previous transition to end
       
   243     return this.then(function (node) {
       
   244         &#x2F;&#x2F; As noted in the user guide, returning a promise inside the then()
       
   245         &#x2F;&#x2F; callback causes the promise returned by then() to be synced with this
       
   246         &#x2F;&#x2F; new promise. This is a way to control when the returned promise is
       
   247         &#x2F;&#x2F; fulfilled
       
   248         return new Y.Promise(function (fulfill, reject) {
       
   249             node.transition(config, function () {
       
   250                 &#x2F;&#x2F; The transition is done, signal the promise that all is ready
       
   251                 &#x2F;&#x2F; by fulfilling it with the same node
       
   252                 fulfill(node);
       
   253             });
       
   254         });
       
   255     });
       
   256 };
       
   257 
       
   258 function PromisePlugin(config) {
       
   259     &#x2F;&#x2F; Create a private NodePromise instance that points to the plugin host
       
   260     this._promise = new NodePromise(function (fulfill) {
       
   261         &#x2F;&#x2F; Since this is a Node plugin, config.host will be an instance of Node
       
   262         fulfill(config.host);
       
   263     });
       
   264 }
       
   265 
       
   266 &#x2F;&#x2F; Set up the plugin&#x27;s namespace
       
   267 PromisePlugin.NS = &#x27;promise&#x27;;
       
   268 
       
   269 PromisePlugin.prototype.transition = function (config) {
       
   270     &#x2F;&#x2F; Simply point to the private promise&#x27;s transition method
       
   271     return this._promise.transition(config);
       
   272 };
       
   273 
       
   274 
       
   275 var square = Y.one(&#x27;#square&#x27;);
       
   276 square.plug(PromisePlugin);
       
   277 
       
   278 function resetStyles() {
       
   279     square.setStyles({
       
   280         width: &#x27;100px&#x27;,
       
   281         height: &#x27;100px&#x27;,
       
   282         left: &#x27;0&#x27;
       
   283     });
       
   284 }
       
   285 
       
   286 Y.one(&#x27;#without-plugin&#x27;).on(&#x27;click&#x27;, function () {
       
   287     resetStyles();
       
   288     square
       
   289         .transition({width: &#x27;300px&#x27;})
       
   290         .transition({height: &#x27;300px&#x27;})
       
   291         .transition({left: &#x27;200px&#x27;});
       
   292 });
       
   293 Y.one(&#x27;#with-plugin&#x27;).on(&#x27;click&#x27;, function () {
       
   294     resetStyles();
       
   295     square.promise
       
   296         .transition({width: &#x27;300px&#x27;})
       
   297         .transition({height: &#x27;300px&#x27;})
       
   298         .transition({left: &#x27;200px&#x27;});
       
   299 });
       
   300 
       
   301 });
       
   302 &lt;&#x2F;script&gt;</pre>
       
   303 
       
   304 </div>
       
   305             </div>
       
   306         </div>
       
   307 
       
   308         <div class="yui3-u-1-4">
       
   309             <div class="sidebar">
       
   310                 
       
   311                     <div id="toc" class="sidebox">
       
   312                         <div class="hd">
       
   313                             <h2 class="no-toc">Table of Contents</h2>
       
   314                         </div>
       
   315 
       
   316                         <div class="bd">
       
   317                             <ul class="toc">
       
   318 <li>
       
   319 <a href="#using-promises-to-chain-css-transitions">Using Promises to Chain CSS Transitions</a>
       
   320 <ul class="toc">
       
   321 <li>
       
   322 <a href="#the-plan">The plan</a>
       
   323 </li>
       
   324 <li>
       
   325 <a href="#creating-a-promise-subclass">Creating a Promise Subclass</a>
       
   326 </li>
       
   327 <li>
       
   328 <a href="#creating-the-plugin">Creating the Plugin</a>
       
   329 </li>
       
   330 <li>
       
   331 <a href="#using-the-plugin">Using the Plugin</a>
       
   332 </li>
       
   333 <li>
       
   334 <a href="#fullcode">Full Code Listing</a>
       
   335 <ul class="toc">
       
   336 <li>
       
   337 <a href="#html">HTML</a>
       
   338 </li>
       
   339 <li>
       
   340 <a href="#css">CSS</a>
       
   341 </li>
       
   342 <li>
       
   343 <a href="#javascript">JavaScript</a>
       
   344 </li>
       
   345 </ul>
       
   346 </li>
       
   347 </ul>
       
   348 </li>
       
   349 </ul>
       
   350                         </div>
       
   351                     </div>
       
   352                 
       
   353 
       
   354                 
       
   355                     <div class="sidebox">
       
   356                         <div class="hd">
       
   357                             <h2 class="no-toc">Examples</h2>
       
   358                         </div>
       
   359 
       
   360                         <div class="bd">
       
   361                             <ul class="examples">
       
   362                                 
       
   363                                     
       
   364                                         <li data-description="Wrapping async transactions with promises">
       
   365                                             <a href="basic-example.html">Wrapping async transactions with promises</a>
       
   366                                         </li>
       
   367                                     
       
   368                                 
       
   369                                     
       
   370                                         <li data-description="Extend Y.Promise to create classes that encapsulate standard transaction logic in descriptive method names">
       
   371                                             <a href="subclass-example.html">Subclassing Y.Promise</a>
       
   372                                         </li>
       
   373                                     
       
   374                                 
       
   375                                     
       
   376                                         <li data-description="Extend the Promise class to create your own Node plugin that chains transitions">
       
   377                                             <a href="plugin-example.html">Creating a Node Plugin that chains transitions</a>
       
   378                                         </li>
       
   379                                     
       
   380                                 
       
   381                             </ul>
       
   382                         </div>
       
   383                     </div>
       
   384                 
       
   385 
       
   386                 
       
   387             </div>
       
   388         </div>
       
   389     </div>
       
   390 </div>
       
   391 
       
   392 <script src="../assets/vendor/prettify/prettify-min.js"></script>
       
   393 <script>prettyPrint();</script>
       
   394 
       
   395 <script>
       
   396 YUI.Env.Tests = {
       
   397     examples: [],
       
   398     project: '../assets',
       
   399     assets: '../assets/promise',
       
   400     name: 'plugin-example',
       
   401     title: 'Creating a Node Plugin that chains transitions',
       
   402     newWindow: '',
       
   403     auto:  false 
       
   404 };
       
   405 YUI.Env.Tests.examples.push('basic-example');
       
   406 YUI.Env.Tests.examples.push('subclass-example');
       
   407 YUI.Env.Tests.examples.push('plugin-example');
       
   408 
       
   409 </script>
       
   410 <script src="../assets/yui/test-runner.js"></script>
       
   411 
       
   412 
       
   413 
       
   414 </body>
       
   415 </html>