├── .gitignore ├── FutureJS.pdf ├── LICENSE ├── README.md └── demos ├── alphabetinvasion ├── alphabetinvasion.html ├── alphabetinvasion.js └── main.css ├── assets ├── bootstrap │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ └── bootstrap.min.css │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ └── js │ │ ├── bootstrap.js │ │ └── bootstrap.min.js ├── jquery │ └── jquery-1.11.1.min.js ├── respond │ └── respond.min.js └── rx │ ├── rx.aggregates.js │ ├── rx.aggregates.min.js │ ├── rx.async.compat.js │ ├── rx.async.compat.min.js │ ├── rx.async.js │ ├── rx.async.min.js │ ├── rx.backpressure.js │ ├── rx.backpressure.min.js │ ├── rx.binding.js │ ├── rx.binding.min.js │ ├── rx.coincidence.js │ ├── rx.coincidence.min.js │ ├── rx.compat.js │ ├── rx.compat.min.js │ ├── rx.experimental.js │ ├── rx.experimental.min.js │ ├── rx.joinpatterns.js │ ├── rx.joinpatterns.min.js │ ├── rx.js │ ├── rx.lite.compat.js │ ├── rx.lite.compat.min.js │ ├── rx.lite.js │ ├── rx.lite.min.js │ ├── rx.min.js │ ├── rx.node.js │ ├── rx.testing.js │ ├── rx.testing.min.js │ ├── rx.time.js │ ├── rx.time.min.js │ ├── rx.virtualtime.js │ └── rx.virtualtime.min.js ├── dragndrop ├── dragndrop.css ├── dragndrop.html ├── dragndrop.js └── logo.png ├── letterrcount ├── lettercount.css ├── lettercount.html └── lettercount.js ├── mouse1 ├── main.css ├── mouse1.html └── mouse1.js ├── mouse2 ├── main.css ├── mouse2.html └── mouse2.js └── mouse3 ├── main.css ├── mouse3.html └── mouse3.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Deployed apps should consider commenting this line out: 24 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 25 | node_modules 26 | -------------------------------------------------------------------------------- /FutureJS.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Reactive-Extensions/FutureJS/8cc4e1cf907ce0a61ddf5aa66dd35cf6889ae61c/FutureJS.pdf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | FutureJS 2014 2 | ============= 3 | 4 | This is the presentation given by Rx Team member [Matthew Podwysocki](http://twitter.com/mattpodwysocki) at [FutureJS](http://futurejs.org). 5 | 6 | ## Demos ## 7 | - Alphabet Invasion [Code](https://github.com/reactive-extensions/FutureJS/tree/master/demos/alphabetinvasion) 8 | - Drag and Drop [Code](https://github.com/reactive-extensions/FutureJS/tree/master/demos/dragndrop) 9 | - Follow the Mouse 1 [Code](https://github.com/reactive-extensions/FutureJS/tree/master/demos/mouse1) 10 | - Follow the Mouse 2 [Code](https://github.com/reactive-extensions/FutureJS/tree/master/demos/mouse2) 11 | - Follow the Mouse 3 [Code](https://github.com/reactive-extensions/FutureJS/tree/master/demos/mouse3) 12 | - React RxJS Autocomplete [Code](https://github.com/eliseumds/react-autocomplete) 13 | - React RxJS TODO MVC [Code](https://github.com/fdecampredon/react-rxjs-todomvc) 14 | - Ninya.io [Code](https://github.com/PascalPrecht/StackWho) | [Site](http://stackwho.herokuapp.com/) 15 | - Reactive Trader [Code](https://github.com/AdaptiveConsulting/ReactiveTrader) | [Site](https://github.com/AdaptiveConsulting/ReactiveTrader) 16 | 17 | ## Resources ## 18 | 19 | - [RxJS Main Site](http://github.com/reactive-extensions/RxJS) 20 | - [RxJS Bindings for Angular](http://github.com/reactive-extensions/rx.angular.js) 21 | - [Twitter - ReactiveX](http://twitter.com/ReactiveX) 22 | - [Reactive Manifesto](http://reactivemanifesto.org) 23 | - Reactive Streams [Repository](http://www.reactive-streams.org/) | [Site](http://reactive-streams.org) 24 | - [WHATWG Streams](https://github.com/whatwg/streams) 25 | - [Reactive-Dart](https://github.com/financeCoding/Reactive-Dart) 26 | - [Dart - Introducing the new Streams API](http://news.dartlang.org/2012/11/introducing-new-streams-api.html) 27 | - [Dart Streams](https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart-async) -------------------------------------------------------------------------------- /demos/alphabetinvasion/alphabetinvasion.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Alphabet Invasion! 4 | 5 | 6 | 7 |
Alphabet Invasion!
8 |
9 |
SCORE:
10 |
0
11 |
LEVEL:
12 |
13 |
ENEMIES REMAINING:
14 |
15 |
HIGH SCORE
16 |
0
17 |
18 |
19 |
20 |
21 |
22 |
23 |
As the letters fall, type the letter that is lowest to the ground to keep your planet safe from these alphabetical invaders!
24 |
Score higher by zapping the invaders as early as possible.
25 |
Remember, these sneaky invaders are CaSe-SeNsItIvE!
26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /demos/alphabetinvasion/alphabetinvasion.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | // Non-standard custom operator 4 | Rx.Observable.random = function (low, high, intervalLow, intervalHigh, howMany, scheduler) { 5 | scheduler || (scheduler = Rx.Scheduler.timeout); 6 | if (howMany == null) { 7 | howMany = -1; 8 | } 9 | if (intervalLow == null) { 10 | intervalLow = 1; 11 | } 12 | if (intervalHigh == null) { 13 | intervalHigh = 1; 14 | } 15 | return Rx.Observable.create(function (observer) { 16 | var delta = high - low 17 | intervalDelta = intervalHigh - intervalLow, 18 | ticks = 0, 19 | iFunc = (intervalDelta === 0) 20 | ? function () { return intervalLow; } 21 | : function () { return Math.floor((Math.random() * intervalDelta) + intervalLow); }; 22 | return scheduler.scheduleRecursiveWithRelative(iFunc(), function (self) { 23 | if (++ticks <= howMany) { 24 | observer.onNext(Math.floor((Math.random() * delta) + low)); 25 | self(iFunc()); 26 | } else { 27 | observer.onCompleted(); 28 | } 29 | }); 30 | }); 31 | }; 32 | 33 | var GameState = { 34 | playing: 'playing', 35 | paused: 'paused', 36 | stopped: 'stopped' 37 | }; 38 | 39 | var AlphabetInvasion = (function () { 40 | function AlphabetInvasion() { 41 | this.enemies = []; 42 | 43 | // get references to our needed DOM elements 44 | this.modalBox = document.querySelector('#modalmessages'); 45 | this.message = document.querySelector('#message'); 46 | this.score = document.querySelector('#score'); 47 | this.playfield = document.querySelector('#playfield'); 48 | this.level = document.querySelector("#level"); 49 | this.remainingEnemies = document.querySelector("#remaining"); 50 | this.highScore = document.querySelector("#highscore"); 51 | } 52 | 53 | var CURRENT_SPEED = 0; 54 | var LAUNCH_RATE = 1; 55 | var HIGH_SCORE_STORAGE_KEY = '_alphabet_attack_high_score_'; 56 | 57 | var playfieldheight = 0; 58 | var lookup = "abcdefghijklmnopqrstuvwxyz"; 59 | var levels = { 60 | "Level 1 - Rookies": [60, 1300], 61 | "Level 2 - Tenderfoots": [55, 1200], 62 | "Level 3 - Militia": [50, 1100], 63 | "Level 4 - Privates": [50, 1000], 64 | "Level 5 - Corporals": [45, 800], 65 | "Level 6 - Sergeants": [40, 650], 66 | "Level 7 - Master Sergeants": [35, 500], 67 | "Level 8 - Lieutenants": [30, 450], 68 | "Level 9 - Captains": [25, 400], 69 | "Level 10 - Majors": [20, 400], 70 | "Level 11 - Colonels": [15, 350], 71 | "Level 12 - Generals": [11, 350], 72 | "Level 13 - Special Forces": [9, 350], 73 | "Level 14 - Black Ops": [7, 350], 74 | "Level 15 - Ninjas": [5, 350] 75 | }; 76 | 77 | AlphabetInvasion.prototype.run = function () { 78 | this.resetGame(); 79 | this.keyboardObservable = Rx.Observable.fromEvent(document, 'keyup'); 80 | 81 | // If paused cause game to start 82 | var self = this; 83 | this.keyboardObservable.subscribe(function () { 84 | if (self.gameState === GameState.paused) { 85 | self.hideMessage(); 86 | self.playLevel(); 87 | } 88 | }); 89 | 90 | var hs = window.localStorage.getItem(HIGH_SCORE_STORAGE_KEY); 91 | if (hs !== null) { 92 | this.highScore.innerText = hs; 93 | } 94 | }; 95 | 96 | AlphabetInvasion.prototype.playLevel = function () { 97 | if (this.generator) { 98 | this.generator.dispose(); 99 | } 100 | var title, found = false; 101 | for (var level in levels) { 102 | if (level.indexOf(this.currentLevel) !== -1) { 103 | found = true; 104 | } 105 | if (found) { 106 | title = level; 107 | break; 108 | } 109 | } 110 | 111 | var config = levels[level]; 112 | 113 | this.gameState = GameState.playing; 114 | this.level.innerText = this.currentLevel; 115 | this.showMessage(title); 116 | 117 | // nested method to handle the actual gameplay loop 118 | var self = this; 119 | var play = function () { 120 | self.hideMessage(); 121 | var enemiesThisLevel = self.currentLevel * 2 + 13; 122 | self.remainingEnemies.innerText = enemiesThisLevel; 123 | 124 | var capitalLetterProbability = 1 - ((self.currentLevel * 2.5) / 100); 125 | var killed = 0; 126 | var allEnemiesLaunched = false; 127 | 128 | // Start the game loop, which updates the enemies. 129 | self.gameloop = Rx.Observable.interval(config[CURRENT_SPEED]).subscribe(function () { 130 | self.updatePlayfield(); 131 | }); 132 | 133 | // set another subscriber to the keyboardObservable 134 | // which handles play input during each level 135 | self.keyboard = self.keyboardObservable.subscribe(function (e) { 136 | if (self.enemies.length === 0 && !allEnemiesLaunched) { 137 | return; 138 | } 139 | 140 | if (self.enemies.length === 0 && allEnemiesLaunched) { 141 | self.nextLevel(); 142 | return; 143 | } 144 | var key = e.shiftKey ? String.fromCharCode(e.keyCode) : String.fromCharCode(e.keyCode).toLowerCase(); 145 | console.log('key pressed: ' + key + ' enemy text: ' + self.enemies[0].innerText); 146 | if (key === self.enemies[0].innerText) { 147 | var enemy = self.enemies.shift(); 148 | self.killEnemy(enemy); 149 | self.remainingEnemies.innerText = enemiesThisLevel - ++killed; 150 | 151 | if (self.enemies.length === 0 && allEnemiesLaunched) { 152 | self.nextLevel(); 153 | } 154 | } 155 | }); 156 | 157 | // Generate enemies for this Level. 158 | // 10% chance for uppercase enemy 159 | self.generator = Rx.Observable.random(0, 25, config[LAUNCH_RATE], config[LAUNCH_RATE], enemiesThisLevel).select(function (v) { 160 | return Math.random() <= capitalLetterProbability ? lookup.charAt(v) : lookup.charAt(v).toUpperCase(); 161 | }).subscribe(function (v) { 162 | self.launchNewEnemy(v); 163 | }, function (e) { 164 | throw e; 165 | }, function () { 166 | allEnemiesLaunched = true; 167 | }); 168 | }; 169 | 170 | // This observable sets a delay for showing the level title, 171 | // after which we call the nested play() method to start 172 | // the level. 173 | Rx.Observable.timer(2500).subscribe(function () { play(); }); 174 | }; 175 | 176 | AlphabetInvasion.prototype.nextLevel = function () { 177 | if (this.currentLevel === 15) { 178 | this.youWin(); 179 | } 180 | 181 | this.gameState = GameState.stopped; 182 | this.gameloop.dispose(); 183 | this.generator.dispose(); 184 | this.keyboard.dispose(); 185 | 186 | this.showMessage('Level ' + this.currentLevel + ' Complete'); 187 | this.currentLevel++; 188 | 189 | var self = this; 190 | Rx.Observable.timer(4000).subscribe(function () { self.playLevel(); }); 191 | }; 192 | 193 | AlphabetInvasion.prototype.youWin = function () { 194 | if (this.gameState === GameState.stopped) { 195 | return; 196 | } 197 | 198 | // change game state and dispose of our 199 | // game loop observables 200 | this.gameState = GameState.stopped; 201 | this.gameloop.dispose(); 202 | this.generator.dispose(); 203 | this.keyboard.dispose(); 204 | 205 | this.showMessage("You win this time Earthling! We'll be back!"); 206 | 207 | // reset the game after 5.5 seconds 208 | var self = this; 209 | Rx.Observable.timer(5500).subscribe(function () { 210 | self.resetGame(); 211 | }); 212 | }; 213 | 214 | AlphabetInvasion.prototype.youLose = function () { 215 | if (this.gameState === GameState.stopped) { 216 | return; 217 | } 218 | 219 | // change game state and dispose of our 220 | // game loop observables 221 | this.gameState = GameState.Stopped; 222 | this.gameloop.dispose(); 223 | this.generator.dispose(); 224 | this.keyboard.dispose(); 225 | 226 | // adjust all enemies except the one that landed 227 | // to look like :P 228 | for (var i = 0, len = this.enemies.length; i < len; i++) { 229 | var enemy = this.enemies[i]; 230 | if (enemy !== this.enemies[0]) { 231 | enemy.innerText = ':P'; 232 | enemy.className += ' rotate'; 233 | enemy.style.fontSize = '72px'; 234 | } 235 | } 236 | 237 | this.showMessage("You Lose Earthling. Prepare to be alphabetized!"); 238 | 239 | // reset the game after 4.5 seconds 240 | var self = this; 241 | Rx.Observable.timer(5500).subscribe(function () { 242 | self.resetGame(); 243 | }); 244 | }; 245 | 246 | AlphabetInvasion.prototype.killEnemy = function (enemy) { 247 | // adjust the enemy visual 248 | enemy.style.color = 'red'; 249 | enemy.style.fontSize = '48px'; 250 | enemy.innerText = '@'; 251 | 252 | // calculate a score 253 | var v = enemy.offsetTop; 254 | this.addToScore((this.playfield.clientHeight - v) * this.currentLevel); 255 | 256 | // remove the enemy from the DOM after 750ms 257 | var self = this; 258 | Rx.Observable.timer(750).subscribe(function () { 259 | self.playfield.removeChild(enemy); 260 | }); 261 | }; 262 | 263 | // Updates positions of all enemies and calculates if an enemy has landed. 264 | AlphabetInvasion.prototype.updatePlayfield = function () { 265 | // adjusting enemy speed based on playfield height 266 | 267 | playfieldheight = this.playfield.clientTop + this.playfield.clientHeight; 268 | var factor = playfieldheight / 200; 269 | 270 | var self = this; 271 | Rx.Observable.fromArray(this.enemies).subscribe(function (enemy) { 272 | 273 | var newPos = enemy.offsetTop + factor; 274 | enemy.style.top = newPos + 'px'; 275 | if (newPos >= playfieldheight + 44) { 276 | self.youLose(); 277 | } 278 | }); 279 | 280 | }; 281 | 282 | AlphabetInvasion.prototype.launchNewEnemy = function (v) { 283 | //randomize a color, not too dark 284 | var r = Math.floor(Math.random() * 100 + 155) 285 | , g = Math.floor(Math.random() * 100 + 155) 286 | , b = Math.floor(Math.random() * 100 + 155); 287 | 288 | // build the enemy and set it's initial position 289 | var enemy = document.createElement('div'); 290 | enemy.style.color = 'rgb(' + r + ',' + g + ',' + b + ')'; 291 | enemy.style.position = 'absolute'; 292 | enemy.style.top = this.playfield.offsetTop + 'px'; 293 | enemy.style.left = (Math.random() * (this.playfield.clientWidth - 25)) + 'px'; 294 | enemy.className = 'enemy'; 295 | enemy.innerText = v; 296 | 297 | // update the tracking queue and add the enemy to the DOM 298 | this.enemies.push(enemy); 299 | this.playfield.appendChild(enemy); 300 | }; 301 | 302 | AlphabetInvasion.prototype.addToScore = function (amount) { 303 | var newScore = parseInt(this.score.innerText) + amount; 304 | this.score.innerText = newScore; 305 | 306 | if (newScore > parseInt(this.highScore.innerText)) { 307 | this.highScore.innerText = newScore; 308 | window.localStorage.setItem(HIGH_SCORE_STORAGE_KEY, newScore); 309 | } 310 | }; 311 | 312 | AlphabetInvasion.prototype.resetGame = function () { 313 | this.gameState = GameState.paused; 314 | this.showMessage(''); 315 | 316 | this.currentLevel = 1; 317 | 318 | this.score.innerText = '0'; 319 | this.level.innerText = '1'; 320 | this.remainingEnemies.innerText = '-'; 321 | 322 | this.clearPlayfield(); 323 | 324 | if (this.windowHeight) this.windowHeight.dispose(); 325 | if (this.generator) this.generator.dispose(); 326 | if (this.matcher) this.matcher.dispose(); 327 | if (this.gameloop) this.gameloop.dispose(); 328 | if (this.keyboard) this.keyboard.dispose(); 329 | 330 | this.showMessage('PRESS ANY KEY TO START'); 331 | }; 332 | 333 | AlphabetInvasion.prototype.clearPlayfield = function () { 334 | for (var i = 0, len = this.enemies.length; i < len; i++) { 335 | this.playfield.removeChild(this.enemies[i]); 336 | } 337 | this.enemies = []; 338 | }; 339 | 340 | // Displays a model message one letter at a time. 341 | AlphabetInvasion.prototype.showMessage = function (msg) { 342 | if (msg && msg.length === 0) { 343 | this.message.text = ''; 344 | return; 345 | } 346 | 347 | this.modalBox.style.opacity = 1; 348 | 349 | var self = this; 350 | for (var i = 0, len = msg.length; i < len; i++) { 351 | (function (i) { 352 | Rx.Observable.returnValue(i).delay(30 * i).subscribe(function (x) { 353 | self.message.innerText = msg.substring(0, x + 1); 354 | }); 355 | })(i); 356 | } 357 | }; 358 | 359 | AlphabetInvasion.prototype.hideMessage = function () { 360 | this.modalBox.style.opacity = 0; 361 | }; 362 | 363 | return AlphabetInvasion; 364 | 365 | })(); 366 | 367 | var game = new AlphabetInvasion(); 368 | game.run(); 369 | })(); 370 | -------------------------------------------------------------------------------- /demos/alphabetinvasion/main.css: -------------------------------------------------------------------------------- 1 | html{ 2 | margin:0px; 3 | padding:0px; 4 | } 5 | 6 | body{ 7 | background: black; 8 | font-family: consolas, courier; 9 | color: WhiteSmoke; 10 | margin:0px; 11 | padding:0px; 12 | overflow:hidden; 13 | } 14 | 15 | 16 | #title{ 17 | text-align:center; 18 | font-size:38px; 19 | color: Yellow; 20 | } 21 | 22 | #updatefield{ 23 | font-size: 24px; 24 | display: -webkit-box; 25 | display: -moz-box; 26 | display: box; 27 | } 28 | 29 | .infotitle{ 30 | padding-left: 1.5em; 31 | color: LightGreen; 32 | } 33 | 34 | .info{ 35 | padding-left: .5em; 36 | width:4em; 37 | } 38 | 39 | .enemy{ 40 | position: absolute; 41 | margin: 0px; 42 | font-size: 30px; 43 | -webkit-transition: font-size 1s linear; 44 | -moz-transition: font-size 1s linear; 45 | transition: font-size 1s linear; 46 | } 47 | 48 | #playfield{ 49 | height: 75%; 50 | border: solid 1px #a8a8a8; 51 | border-bottom: solid 5px Green; 52 | background-image: linear-gradient(bottom, rgb(39,54,105) 17%, rgb(1,5,54) 46%); 53 | background-image: -o-linear-gradient(bottom, rgb(39,54,105) 17%, rgb(1,5,54) 46%); 54 | background-image: -moz-linear-gradient(bottom, rgb(39,54,105) 17%, rgb(1,5,54) 46%); 55 | background-image: -webkit-linear-gradient(bottom, rgb(39,54,105) 17%, rgb(1,5,54) 46%); 56 | background-image: -ms-linear-gradient(bottom, rgb(39,54,105) 17%, rgb(1,5,54) 46%); 57 | } 58 | 59 | .rotate{ 60 | -webkit-transform: rotate(90deg); 61 | -moz-transform: rotate(90deg); 62 | -o-transform: rotate(90deg); 63 | rotate(90deg); 64 | } 65 | 66 | .instructions{ 67 | text-align:center; 68 | font-size: 18px; 69 | } 70 | 71 | #modalmessages{ 72 | opacity: 0; 73 | height: 100%; 74 | width: 100%; 75 | background: #333377; 76 | display: -webkit-box; 77 | display: -moz-box; 78 | display: box; 79 | -webkit-box-pack: center; 80 | -moz-box-pack: center; 81 | box-pack:center; 82 | -webkit-box-align: center; 83 | -moz-box-align: center; 84 | box-align: center; 85 | -webkit-transition: opacity .5s linear; 86 | -moz-transition: opacity .5s linear; 87 | transition: opacity .5s linear; 88 | 89 | } 90 | 91 | #message{ 92 | font-size: 45px; 93 | } 94 | -------------------------------------------------------------------------------- /demos/assets/bootstrap/css/bootstrap-theme.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.1.1 (http://getbootstrap.com) 3 | * Copyright 2011-2014 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | .btn-default, 8 | .btn-primary, 9 | .btn-success, 10 | .btn-info, 11 | .btn-warning, 12 | .btn-danger { 13 | text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); 14 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); 15 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); 16 | } 17 | .btn-default:active, 18 | .btn-primary:active, 19 | .btn-success:active, 20 | .btn-info:active, 21 | .btn-warning:active, 22 | .btn-danger:active, 23 | .btn-default.active, 24 | .btn-primary.active, 25 | .btn-success.active, 26 | .btn-info.active, 27 | .btn-warning.active, 28 | .btn-danger.active { 29 | -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); 30 | box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); 31 | } 32 | .btn:active, 33 | .btn.active { 34 | background-image: none; 35 | } 36 | .btn-default { 37 | text-shadow: 0 1px 0 #fff; 38 | background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); 39 | background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); 40 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); 41 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 42 | background-repeat: repeat-x; 43 | border-color: #dbdbdb; 44 | border-color: #ccc; 45 | } 46 | .btn-default:hover, 47 | .btn-default:focus { 48 | background-color: #e0e0e0; 49 | background-position: 0 -15px; 50 | } 51 | .btn-default:active, 52 | .btn-default.active { 53 | background-color: #e0e0e0; 54 | border-color: #dbdbdb; 55 | } 56 | .btn-primary { 57 | background-image: -webkit-linear-gradient(top, #428bca 0%, #2d6ca2 100%); 58 | background-image: linear-gradient(to bottom, #428bca 0%, #2d6ca2 100%); 59 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0); 60 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 61 | background-repeat: repeat-x; 62 | border-color: #2b669a; 63 | } 64 | .btn-primary:hover, 65 | .btn-primary:focus { 66 | background-color: #2d6ca2; 67 | background-position: 0 -15px; 68 | } 69 | .btn-primary:active, 70 | .btn-primary.active { 71 | background-color: #2d6ca2; 72 | border-color: #2b669a; 73 | } 74 | .btn-success { 75 | background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); 76 | background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); 77 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); 78 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 79 | background-repeat: repeat-x; 80 | border-color: #3e8f3e; 81 | } 82 | .btn-success:hover, 83 | .btn-success:focus { 84 | background-color: #419641; 85 | background-position: 0 -15px; 86 | } 87 | .btn-success:active, 88 | .btn-success.active { 89 | background-color: #419641; 90 | border-color: #3e8f3e; 91 | } 92 | .btn-info { 93 | background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); 94 | background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); 95 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); 96 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 97 | background-repeat: repeat-x; 98 | border-color: #28a4c9; 99 | } 100 | .btn-info:hover, 101 | .btn-info:focus { 102 | background-color: #2aabd2; 103 | background-position: 0 -15px; 104 | } 105 | .btn-info:active, 106 | .btn-info.active { 107 | background-color: #2aabd2; 108 | border-color: #28a4c9; 109 | } 110 | .btn-warning { 111 | background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); 112 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); 113 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); 114 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 115 | background-repeat: repeat-x; 116 | border-color: #e38d13; 117 | } 118 | .btn-warning:hover, 119 | .btn-warning:focus { 120 | background-color: #eb9316; 121 | background-position: 0 -15px; 122 | } 123 | .btn-warning:active, 124 | .btn-warning.active { 125 | background-color: #eb9316; 126 | border-color: #e38d13; 127 | } 128 | .btn-danger { 129 | background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); 130 | background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); 131 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); 132 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 133 | background-repeat: repeat-x; 134 | border-color: #b92c28; 135 | } 136 | .btn-danger:hover, 137 | .btn-danger:focus { 138 | background-color: #c12e2a; 139 | background-position: 0 -15px; 140 | } 141 | .btn-danger:active, 142 | .btn-danger.active { 143 | background-color: #c12e2a; 144 | border-color: #b92c28; 145 | } 146 | .thumbnail, 147 | .img-thumbnail { 148 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 149 | box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 150 | } 151 | .dropdown-menu > li > a:hover, 152 | .dropdown-menu > li > a:focus { 153 | background-color: #e8e8e8; 154 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 155 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); 156 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); 157 | background-repeat: repeat-x; 158 | } 159 | .dropdown-menu > .active > a, 160 | .dropdown-menu > .active > a:hover, 161 | .dropdown-menu > .active > a:focus { 162 | background-color: #357ebd; 163 | background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%); 164 | background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); 165 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); 166 | background-repeat: repeat-x; 167 | } 168 | .navbar-default { 169 | background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); 170 | background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); 171 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); 172 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 173 | background-repeat: repeat-x; 174 | border-radius: 4px; 175 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); 176 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); 177 | } 178 | .navbar-default .navbar-nav > .active > a { 179 | background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%); 180 | background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%); 181 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0); 182 | background-repeat: repeat-x; 183 | -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); 184 | box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); 185 | } 186 | .navbar-brand, 187 | .navbar-nav > li > a { 188 | text-shadow: 0 1px 0 rgba(255, 255, 255, .25); 189 | } 190 | .navbar-inverse { 191 | background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); 192 | background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); 193 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); 194 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 195 | background-repeat: repeat-x; 196 | } 197 | .navbar-inverse .navbar-nav > .active > a { 198 | background-image: -webkit-linear-gradient(top, #222 0%, #282828 100%); 199 | background-image: linear-gradient(to bottom, #222 0%, #282828 100%); 200 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0); 201 | background-repeat: repeat-x; 202 | -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); 203 | box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); 204 | } 205 | .navbar-inverse .navbar-brand, 206 | .navbar-inverse .navbar-nav > li > a { 207 | text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); 208 | } 209 | .navbar-static-top, 210 | .navbar-fixed-top, 211 | .navbar-fixed-bottom { 212 | border-radius: 0; 213 | } 214 | .alert { 215 | text-shadow: 0 1px 0 rgba(255, 255, 255, .2); 216 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); 217 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); 218 | } 219 | .alert-success { 220 | background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); 221 | background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); 222 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); 223 | background-repeat: repeat-x; 224 | border-color: #b2dba1; 225 | } 226 | .alert-info { 227 | background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); 228 | background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); 229 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); 230 | background-repeat: repeat-x; 231 | border-color: #9acfea; 232 | } 233 | .alert-warning { 234 | background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); 235 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); 236 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); 237 | background-repeat: repeat-x; 238 | border-color: #f5e79e; 239 | } 240 | .alert-danger { 241 | background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); 242 | background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); 243 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); 244 | background-repeat: repeat-x; 245 | border-color: #dca7a7; 246 | } 247 | .progress { 248 | background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); 249 | background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); 250 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); 251 | background-repeat: repeat-x; 252 | } 253 | .progress-bar { 254 | background-image: -webkit-linear-gradient(top, #428bca 0%, #3071a9 100%); 255 | background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); 256 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0); 257 | background-repeat: repeat-x; 258 | } 259 | .progress-bar-success { 260 | background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); 261 | background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); 262 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); 263 | background-repeat: repeat-x; 264 | } 265 | .progress-bar-info { 266 | background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); 267 | background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); 268 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); 269 | background-repeat: repeat-x; 270 | } 271 | .progress-bar-warning { 272 | background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); 273 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); 274 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); 275 | background-repeat: repeat-x; 276 | } 277 | .progress-bar-danger { 278 | background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); 279 | background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); 280 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); 281 | background-repeat: repeat-x; 282 | } 283 | .list-group { 284 | border-radius: 4px; 285 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 286 | box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 287 | } 288 | .list-group-item.active, 289 | .list-group-item.active:hover, 290 | .list-group-item.active:focus { 291 | text-shadow: 0 -1px 0 #3071a9; 292 | background-image: -webkit-linear-gradient(top, #428bca 0%, #3278b3 100%); 293 | background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%); 294 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0); 295 | background-repeat: repeat-x; 296 | border-color: #3278b3; 297 | } 298 | .panel { 299 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); 300 | box-shadow: 0 1px 2px rgba(0, 0, 0, .05); 301 | } 302 | .panel-default > .panel-heading { 303 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 304 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); 305 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); 306 | background-repeat: repeat-x; 307 | } 308 | .panel-primary > .panel-heading { 309 | background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%); 310 | background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); 311 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); 312 | background-repeat: repeat-x; 313 | } 314 | .panel-success > .panel-heading { 315 | background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); 316 | background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); 317 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); 318 | background-repeat: repeat-x; 319 | } 320 | .panel-info > .panel-heading { 321 | background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); 322 | background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); 323 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); 324 | background-repeat: repeat-x; 325 | } 326 | .panel-warning > .panel-heading { 327 | background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); 328 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); 329 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); 330 | background-repeat: repeat-x; 331 | } 332 | .panel-danger > .panel-heading { 333 | background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); 334 | background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); 335 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); 336 | background-repeat: repeat-x; 337 | } 338 | .well { 339 | background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); 340 | background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); 341 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); 342 | background-repeat: repeat-x; 343 | border-color: #dcdcdc; 344 | -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); 345 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); 346 | } 347 | /*# sourceMappingURL=bootstrap-theme.css.map */ 348 | -------------------------------------------------------------------------------- /demos/assets/bootstrap/css/bootstrap-theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.1.1 (http://getbootstrap.com) 3 | * Copyright 2011-2014 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | .btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn:active,.btn.active{background-image:none}.btn-default{background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;text-shadow:0 1px 0 #fff;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-primary{background-image:-webkit-linear-gradient(top,#428bca 0,#2d6ca2 100%);background-image:linear-gradient(to bottom,#428bca 0,#2d6ca2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#2b669a}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-color:#e8e8e8}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-color:#357ebd}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f3f3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#222 0,#282828 100%);background-image:linear-gradient(to bottom,#222 0,#282828 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0)}.progress-bar{background-image:-webkit-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0)}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0)}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0)}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0)}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);border-color:#3278b3}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0)}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} -------------------------------------------------------------------------------- /demos/assets/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Reactive-Extensions/FutureJS/8cc4e1cf907ce0a61ddf5aa66dd35cf6889ae61c/demos/assets/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /demos/assets/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Reactive-Extensions/FutureJS/8cc4e1cf907ce0a61ddf5aa66dd35cf6889ae61c/demos/assets/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /demos/assets/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Reactive-Extensions/FutureJS/8cc4e1cf907ce0a61ddf5aa66dd35cf6889ae61c/demos/assets/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /demos/assets/respond/respond.min.js: -------------------------------------------------------------------------------- 1 | /*! Respond.js v1.4.2: min/max-width media query polyfill 2 | * Copyright 2014 Scott Jehl 3 | * Licensed under MIT 4 | * http://j.mp/respondjs */ 5 | 6 | !function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='­',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){v(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},g=function(a){return a.replace(c.regex.minmaxwh,"").match(c.regex.other)};if(c.ajax=f,c.queue=d,c.unsupportedmq=g,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,comments:/\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,maxw:/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,minmaxwh:/\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,other:/\([^\)]*\)/g},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var h,i,j,k=a.document,l=k.documentElement,m=[],n=[],o=[],p={},q=30,r=k.getElementsByTagName("head")[0]||l,s=k.getElementsByTagName("base")[0],t=r.getElementsByTagName("link"),u=function(){var a,b=k.createElement("div"),c=k.body,d=l.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=k.createElement("body"),c.style.background="none"),l.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&l.insertBefore(c,l.firstChild),a=b.offsetWidth,f?l.removeChild(c):c.removeChild(b),l.style.fontSize=d,e&&(c.style.fontSize=e),a=j=parseFloat(a)},v=function(b){var c="clientWidth",d=l[c],e="CSS1Compat"===k.compatMode&&d||k.body[c]||d,f={},g=t[t.length-1],p=(new Date).getTime();if(b&&h&&q>p-h)return a.clearTimeout(i),i=a.setTimeout(v,q),void 0;h=p;for(var s in m)if(m.hasOwnProperty(s)){var w=m[s],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?j||u():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?j||u():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(n[w.rules]))}for(var C in o)o.hasOwnProperty(C)&&o[C]&&o[C].parentNode===r&&r.removeChild(o[C]);o.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=k.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,r.insertBefore(E,g.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(k.createTextNode(F)),o.push(E)}},w=function(a,b,d){var e=a.replace(c.regex.comments,"").replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},i=!f&&d;b.length&&(b+="/"),i&&(f=1);for(var j=0;f>j;j++){var k,l,o,p;i?(k=d,n.push(h(a))):(k=e[j].match(c.regex.findStyles)&&RegExp.$1,n.push(RegExp.$2&&h(RegExp.$2))),o=k.split(","),p=o.length;for(var q=0;p>q;q++)l=o[q],g(l)||m.push({media:l.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:n.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}v()},x=function(){if(d.length){var b=d.shift();f(b.href,function(c){w(c,b.href,b.media),p[b.href]=!0,a.setTimeout(function(){x()},0)})}},y=function(){for(var b=0;b0&&(s=a,u=[]),c>=0&&u.push(t)},i.onError.bind(i),function(){i.onNext(u),i.onCompleted()})})}function o(t){if(0===t.length)throw Error(C);return t[0]}function s(t,e,n){return new b(function(i){var o=0,s=e.length;return t.subscribe(function(t){var u=!1;try{s>o&&(u=n(t,e[o++]))}catch(c){return i.onError(c),r}u||(i.onNext(!1),i.onCompleted())},i.onError.bind(i),function(){i.onNext(o===s),i.onCompleted()})})}function u(t,e,n,r){if(0>e)throw Error(x);return new b(function(i){var o=e;return t.subscribe(function(t){0===o&&(i.onNext(t),i.onCompleted()),o--},i.onError.bind(i),function(){n?(i.onNext(r),i.onCompleted()):i.onError(Error(x))})})}function c(t,e,n){return new b(function(r){var i=n,o=!1;return t.subscribe(function(t){o?r.onError(Error("Sequence contains more than one element")):(i=t,o=!0)},r.onError.bind(r),function(){o||e?(r.onNext(i),r.onCompleted()):r.onError(Error(C))})})}function a(t,e,n){return new b(function(r){return t.subscribe(function(t){r.onNext(t),r.onCompleted()},r.onError.bind(r),function(){e?(r.onNext(n),r.onCompleted()):r.onError(Error(C))})})}function l(t,e,n){return new b(function(r){var i=n,o=!1;return t.subscribe(function(t){i=t,o=!0},r.onError.bind(r),function(){o||e?(r.onNext(i),r.onCompleted()):r.onError(Error(C))})})}function h(t,e,n,i){return new b(function(o){var s=0;return t.subscribe(function(u){var c;try{c=e.call(n,u,s,t)}catch(a){return o.onError(a),r}c?(o.onNext(i?s:u),o.onCompleted()):s++},o.onError.bind(o),function(){o.onNext(i?-1:r),o.onCompleted()})})}var f=n.Observable,p=f.prototype,d=n.CompositeDisposable,b=n.AnonymousObservable,v=(n.internals.isEqual,n.helpers),m=v.defaultComparer,y=v.identity,w=v.defaultSubComparer,g=v.isPromise,E=f.fromPromise,x="Argument out of range",C="Sequence contains no elements.";return p.aggregate=function(){var t,e,n;return 2===arguments.length?(t=arguments[0],e=!0,n=arguments[1]):n=arguments[0],e?this.scan(t,n).startWith(t).finalValue():this.scan(n).finalValue()},p.reduce=function(t){var e,n;return 2===arguments.length&&(n=!0,e=arguments[1]),n?this.scan(e,t).startWith(e).finalValue():this.scan(t).finalValue()},p.some=p.any=function(t,e){var n=this;return t?n.where(t,e).any():new b(function(t){return n.subscribe(function(){t.onNext(!0),t.onCompleted()},t.onError.bind(t),function(){t.onNext(!1),t.onCompleted()})})},p.isEmpty=function(){return this.any().select(function(t){return!t})},p.every=p.all=function(t,e){return this.where(function(e){return!t(e)},e).any().select(function(t){return!t})},p.contains=function(t,e){return e||(e=m),this.where(function(n){return e(n,t)}).any()},p.count=function(t,e){return t?this.where(t,e).count():this.aggregate(0,function(t){return t+1})},p.sum=function(t,e){return t?this.select(t,e).sum():this.aggregate(0,function(t,e){return t+e})},p.minBy=function(t,e){return e||(e=w),i(this,t,function(t,n){return-1*e(t,n)})},p.min=function(t){return this.minBy(y,t).select(function(t){return o(t)})},p.maxBy=function(t,e){return e||(e=w),i(this,t,e)},p.max=function(t){return this.maxBy(y,t).select(function(t){return o(t)})},p.average=function(t,e){return t?this.select(t,e).average():this.scan({sum:0,count:0},function(t,e){return{sum:t.sum+e,count:t.count+1}}).finalValue().select(function(t){if(0===t.count)throw Error("The input sequence was empty");return t.sum/t.count})},p.sequenceEqual=function(t,e){var n=this;return e||(e=m),Array.isArray(t)?s(n,t,e):new b(function(i){var o=!1,s=!1,u=[],c=[],a=n.subscribe(function(t){var n,o;if(c.length>0){o=c.shift();try{n=e(o,t)}catch(a){return i.onError(a),r}n||(i.onNext(!1),i.onCompleted())}else s?(i.onNext(!1),i.onCompleted()):u.push(t)},i.onError.bind(i),function(){o=!0,0===u.length&&(c.length>0?(i.onNext(!1),i.onCompleted()):s&&(i.onNext(!0),i.onCompleted()))});g(t)&&(t=E(t));var l=t.subscribe(function(t){var n,s;if(u.length>0){s=u.shift();try{n=e(s,t)}catch(a){return i.onError(a),r}n||(i.onNext(!1),i.onCompleted())}else o?(i.onNext(!1),i.onCompleted()):c.push(t)},i.onError.bind(i),function(){s=!0,0===c.length&&(u.length>0?(i.onNext(!1),i.onCompleted()):o&&(i.onNext(!0),i.onCompleted()))});return new d(a,l)})},p.elementAt=function(t){return u(this,t,!1)},p.elementAtOrDefault=function(t,e){return u(this,t,!0,e)},p.single=function(t,e){return t?this.where(t,e).single():c(this,!1)},p.singleOrDefault=function(t,e,n){return t?this.where(t,n).singleOrDefault(null,e):c(this,!0,e)},p.first=function(t,e){return t?this.where(t,e).first():a(this,!1)},p.firstOrDefault=function(t,e){return t?this.where(t).firstOrDefault(null,e):a(this,!0,e)},p.last=function(t,e){return t?this.where(t,e).last():l(this,!1)},p.lastOrDefault=function(t,e,n){return t?this.where(t,n).lastOrDefault(null,e):l(this,!0,e)},p.find=function(t,e){return h(this,t,e,!1)},p.findIndex=function(t,e){return h(this,t,e,!0)},n}); -------------------------------------------------------------------------------- /demos/assets/rx/rx.async.compat.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | ;(function (factory) { 4 | var objectTypes = { 5 | 'boolean': false, 6 | 'function': true, 7 | 'object': true, 8 | 'number': false, 9 | 'string': false, 10 | 'undefined': false 11 | }; 12 | 13 | var root = (objectTypes[typeof window] && window) || this, 14 | freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports, 15 | freeModule = objectTypes[typeof module] && module && !module.nodeType && module, 16 | moduleExports = freeModule && freeModule.exports === freeExports && freeExports, 17 | freeGlobal = objectTypes[typeof global] && global; 18 | 19 | if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { 20 | root = freeGlobal; 21 | } 22 | 23 | // Because of build optimizers 24 | if (typeof define === 'function' && define.amd) { 25 | define(['rx.binding', 'exports'], function (Rx, exports) { 26 | root.Rx = factory(root, exports, Rx); 27 | return root.Rx; 28 | }); 29 | } else if (typeof module === 'object' && module && module.exports === freeExports) { 30 | module.exports = factory(root, module.exports, require('./rx')); 31 | } else { 32 | root.Rx = factory(root, {}, root.Rx); 33 | } 34 | }.call(this, function (root, exp, Rx, undefined) { 35 | 36 | // Aliases 37 | var Observable = Rx.Observable, 38 | observableProto = Observable.prototype, 39 | observableFromPromise = Observable.fromPromise, 40 | observableThrow = Observable.throwException, 41 | AnonymousObservable = Rx.AnonymousObservable, 42 | AsyncSubject = Rx.AsyncSubject, 43 | disposableCreate = Rx.Disposable.create, 44 | CompositeDisposable= Rx.CompositeDisposable, 45 | immediateScheduler = Rx.Scheduler.immediate, 46 | timeoutScheduler = Rx.Scheduler.timeout, 47 | slice = Array.prototype.slice; 48 | 49 | /** 50 | * Invokes the specified function asynchronously on the specified scheduler, surfacing the result through an observable sequence. 51 | * 52 | * @example 53 | * var res = Rx.Observable.start(function () { console.log('hello'); }); 54 | * var res = Rx.Observable.start(function () { console.log('hello'); }, Rx.Scheduler.timeout); 55 | * var res = Rx.Observable.start(function () { this.log('hello'); }, Rx.Scheduler.timeout, console); 56 | * 57 | * @param {Function} func Function to run asynchronously. 58 | * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout. 59 | * @param [context] The context for the func parameter to be executed. If not specified, defaults to undefined. 60 | * @returns {Observable} An observable sequence exposing the function's result value, or an exception. 61 | * 62 | * Remarks 63 | * * The function is called immediately, not during the subscription of the resulting sequence. 64 | * * Multiple subscriptions to the resulting sequence can observe the function's result. 65 | */ 66 | Observable.start = function (func, scheduler, context) { 67 | return observableToAsync(func, scheduler, context)(); 68 | }; 69 | 70 | /** 71 | * Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler. 72 | * 73 | * @example 74 | * var res = Rx.Observable.toAsync(function (x, y) { return x + y; })(4, 3); 75 | * var res = Rx.Observable.toAsync(function (x, y) { return x + y; }, Rx.Scheduler.timeout)(4, 3); 76 | * var res = Rx.Observable.toAsync(function (x) { this.log(x); }, Rx.Scheduler.timeout, console)('hello'); 77 | * 78 | * @param {Function} function Function to convert to an asynchronous function. 79 | * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout. 80 | * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined. 81 | * @returns {Function} Asynchronous function. 82 | */ 83 | var observableToAsync = Observable.toAsync = function (func, scheduler, context) { 84 | scheduler || (scheduler = timeoutScheduler); 85 | return function () { 86 | var args = arguments, 87 | subject = new AsyncSubject(); 88 | 89 | scheduler.schedule(function () { 90 | var result; 91 | try { 92 | result = func.apply(context, args); 93 | } catch (e) { 94 | subject.onError(e); 95 | return; 96 | } 97 | subject.onNext(result); 98 | subject.onCompleted(); 99 | }); 100 | return subject.asObservable(); 101 | }; 102 | }; 103 | 104 | /** 105 | * Converts a callback function to an observable sequence. 106 | * 107 | * @param {Function} function Function with a callback as the last parameter to convert to an Observable sequence. 108 | * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout. 109 | * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined. 110 | * @param {Function} [selector] A selector which takes the arguments from the callback to produce a single item to yield on next. 111 | * @returns {Function} A function, when executed with the required parameters minus the callback, produces an Observable sequence with a single value of the arguments to the callback as an array. 112 | */ 113 | Observable.fromCallback = function (func, scheduler, context, selector) { 114 | scheduler || (scheduler = immediateScheduler); 115 | return function () { 116 | var args = slice.call(arguments, 0); 117 | 118 | return new AnonymousObservable(function (observer) { 119 | return scheduler.schedule(function () { 120 | function handler(e) { 121 | var results = e; 122 | 123 | if (selector) { 124 | try { 125 | results = selector(arguments); 126 | } catch (err) { 127 | observer.onError(err); 128 | return; 129 | } 130 | } else { 131 | if (results.length === 1) { 132 | results = results[0]; 133 | } 134 | } 135 | 136 | observer.onNext(results); 137 | observer.onCompleted(); 138 | } 139 | 140 | args.push(handler); 141 | func.apply(context, args); 142 | }); 143 | }); 144 | }; 145 | }; 146 | 147 | /** 148 | * Converts a Node.js callback style function to an observable sequence. This must be in function (err, ...) format. 149 | * @param {Function} func The function to call 150 | * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout. 151 | * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined. 152 | * @param {Function} [selector] A selector which takes the arguments from the callback minus the error to produce a single item to yield on next. 153 | * @returns {Function} An async function which when applied, returns an observable sequence with the callback arguments as an array. 154 | */ 155 | Observable.fromNodeCallback = function (func, scheduler, context, selector) { 156 | scheduler || (scheduler = immediateScheduler); 157 | return function () { 158 | var args = slice.call(arguments, 0); 159 | 160 | return new AnonymousObservable(function (observer) { 161 | return scheduler.schedule(function () { 162 | 163 | function handler(err) { 164 | if (err) { 165 | observer.onError(err); 166 | return; 167 | } 168 | 169 | var results = slice.call(arguments, 1); 170 | 171 | if (selector) { 172 | try { 173 | results = selector(results); 174 | } catch (e) { 175 | observer.onError(e); 176 | return; 177 | } 178 | } else { 179 | if (results.length === 1) { 180 | results = results[0]; 181 | } 182 | } 183 | 184 | observer.onNext(results); 185 | observer.onCompleted(); 186 | } 187 | 188 | args.push(handler); 189 | func.apply(context, args); 190 | }); 191 | }); 192 | }; 193 | }; 194 | 195 | function fixEvent(event) { 196 | var stopPropagation = function () { 197 | this.cancelBubble = true; 198 | }; 199 | 200 | var preventDefault = function () { 201 | this.bubbledKeyCode = this.keyCode; 202 | if (this.ctrlKey) { 203 | try { 204 | this.keyCode = 0; 205 | } catch (e) { } 206 | } 207 | this.defaultPrevented = true; 208 | this.returnValue = false; 209 | this.modified = true; 210 | }; 211 | 212 | event || (event = root.event); 213 | if (!event.target) { 214 | event.target = event.target || event.srcElement; 215 | 216 | if (event.type == 'mouseover') { 217 | event.relatedTarget = event.fromElement; 218 | } 219 | if (event.type == 'mouseout') { 220 | event.relatedTarget = event.toElement; 221 | } 222 | // Adding stopPropogation and preventDefault to IE 223 | if (!event.stopPropagation){ 224 | event.stopPropagation = stopPropagation; 225 | event.preventDefault = preventDefault; 226 | } 227 | // Normalize key events 228 | switch(event.type){ 229 | case 'keypress': 230 | var c = ('charCode' in event ? event.charCode : event.keyCode); 231 | if (c == 10) { 232 | c = 0; 233 | event.keyCode = 13; 234 | } else if (c == 13 || c == 27) { 235 | c = 0; 236 | } else if (c == 3) { 237 | c = 99; 238 | } 239 | event.charCode = c; 240 | event.keyChar = event.charCode ? String.fromCharCode(event.charCode) : ''; 241 | break; 242 | } 243 | } 244 | 245 | return event; 246 | } 247 | 248 | function createListener (element, name, handler) { 249 | // Node.js specific 250 | if (element.addListener) { 251 | element.addListener(name, handler); 252 | return disposableCreate(function () { 253 | element.removeListener(name, handler); 254 | }); 255 | } 256 | // Standards compliant 257 | if (element.addEventListener) { 258 | element.addEventListener(name, handler, false); 259 | return disposableCreate(function () { 260 | element.removeEventListener(name, handler, false); 261 | }); 262 | } 263 | if (element.attachEvent) { 264 | // IE Specific 265 | var innerHandler = function (event) { 266 | handler(fixEvent(event)); 267 | }; 268 | element.attachEvent('on' + name, innerHandler); 269 | return disposableCreate(function () { 270 | element.detachEvent('on' + name, innerHandler); 271 | }); 272 | } 273 | // Level 1 DOM Events 274 | element['on' + name] = handler; 275 | return disposableCreate(function () { 276 | element['on' + name] = null; 277 | }); 278 | } 279 | 280 | function createEventListener (el, eventName, handler) { 281 | var disposables = new CompositeDisposable(); 282 | 283 | // Asume NodeList 284 | if (typeof el.item === 'function' && typeof el.length === 'number') { 285 | for (var i = 0, len = el.length; i < len; i++) { 286 | disposables.add(createEventListener(el.item(i), eventName, handler)); 287 | } 288 | } else if (el) { 289 | disposables.add(createListener(el, eventName, handler)); 290 | } 291 | 292 | return disposables; 293 | } 294 | 295 | // Check for Angular/jQuery/Zepto support 296 | var jq = 297 | !!root.angular && !!angular.element ? angular.element : 298 | (!!root.jQuery ? root.jQuery : ( 299 | !!root.Zepto ? root.Zepto : null)); 300 | 301 | // Check for ember 302 | var ember = !!root.Ember && typeof root.Ember.addListener === 'function'; 303 | 304 | /** 305 | * Creates an observable sequence by adding an event listener to the matching DOMElement or each item in the NodeList. 306 | * 307 | * @example 308 | * var source = Rx.Observable.fromEvent(element, 'mouseup'); 309 | * 310 | * @param {Object} element The DOMElement or NodeList to attach a listener. 311 | * @param {String} eventName The event name to attach the observable sequence. 312 | * @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next. 313 | * @returns {Observable} An observable sequence of events from the specified element and the specified event. 314 | */ 315 | Observable.fromEvent = function (element, eventName, selector) { 316 | if (ember) { 317 | return fromEventPattern( 318 | function (h) { Ember.addListener(element, eventName); }, 319 | function (h) { Ember.removeListener(element, eventName); }, 320 | selector); 321 | } 322 | if (jq) { 323 | var $elem = jq(element); 324 | return fromEventPattern( 325 | function (h) { $elem.on(eventName, h); }, 326 | function (h) { $elem.off(eventName, h); }, 327 | selector); 328 | } 329 | return new AnonymousObservable(function (observer) { 330 | return createEventListener( 331 | element, 332 | eventName, 333 | function handler (e) { 334 | var results = e; 335 | 336 | if (selector) { 337 | try { 338 | results = selector(arguments); 339 | } catch (err) { 340 | observer.onError(err); 341 | return 342 | } 343 | } 344 | 345 | observer.onNext(results); 346 | }); 347 | }).publish().refCount(); 348 | }; 349 | /** 350 | * Creates an observable sequence from an event emitter via an addHandler/removeHandler pair. 351 | * @param {Function} addHandler The function to add a handler to the emitter. 352 | * @param {Function} [removeHandler] The optional function to remove a handler from an emitter. 353 | * @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next. 354 | * @returns {Observable} An observable sequence which wraps an event from an event emitter 355 | */ 356 | var fromEventPattern = Observable.fromEventPattern = function (addHandler, removeHandler, selector) { 357 | return new AnonymousObservable(function (observer) { 358 | function innerHandler (e) { 359 | var result = e; 360 | if (selector) { 361 | try { 362 | result = selector(arguments); 363 | } catch (err) { 364 | observer.onError(err); 365 | return; 366 | } 367 | } 368 | observer.onNext(result); 369 | } 370 | 371 | var returnValue = addHandler(innerHandler); 372 | return disposableCreate(function () { 373 | if (removeHandler) { 374 | removeHandler(innerHandler, returnValue); 375 | } 376 | }); 377 | }).publish().refCount(); 378 | }; 379 | 380 | /** 381 | * Invokes the asynchronous function, surfacing the result through an observable sequence. 382 | * @param {Function} functionAsync Asynchronous function which returns a Promise to run. 383 | * @returns {Observable} An observable sequence exposing the function's result value, or an exception. 384 | */ 385 | Observable.startAsync = function (functionAsync) { 386 | var promise; 387 | try { 388 | promise = functionAsync(); 389 | } catch (e) { 390 | return observableThrow(e); 391 | } 392 | return observableFromPromise(promise); 393 | } 394 | 395 | return Rx; 396 | })); -------------------------------------------------------------------------------- /demos/assets/rx/rx.async.compat.min.js: -------------------------------------------------------------------------------- 1 | (function(t){var e={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},n=e[typeof window]&&window||this,r=e[typeof exports]&&exports&&!exports.nodeType&&exports,o=e[typeof module]&&module&&!module.nodeType&&module,i=(o&&o.exports===r&&r,e[typeof global]&&global);!i||i.global!==i&&i.window!==i||(n=i),"function"==typeof define&&define.amd?define(["rx.binding","exports"],function(e,r){return n.Rx=t(n,r,e),n.Rx}):"object"==typeof module&&module&&module.exports===r?module.exports=t(n,module.exports,require("./rx")):n.Rx=t(n,{},n.Rx)}).call(this,function(t,e,n){function r(e){var n=function(){this.cancelBubble=!0},r=function(){if(this.bubbledKeyCode=this.keyCode,this.ctrlKey)try{this.keyCode=0}catch(t){}this.defaultPrevented=!0,this.returnValue=!1,this.modified=!0};if(e||(e=t.event),!e.target)switch(e.target=e.target||e.srcElement,"mouseover"==e.type&&(e.relatedTarget=e.fromElement),"mouseout"==e.type&&(e.relatedTarget=e.toElement),e.stopPropagation||(e.stopPropagation=n,e.preventDefault=r),e.type){case"keypress":var o="charCode"in e?e.charCode:e.keyCode;10==o?(o=0,e.keyCode=13):13==o||27==o?o=0:3==o&&(o=99),e.charCode=o,e.keyChar=e.charCode?String.fromCharCode(e.charCode):""}return e}function o(t,e,n){if(t.addListener)return t.addListener(e,n),h(function(){t.removeListener(e,n)});if(t.addEventListener)return t.addEventListener(e,n,!1),h(function(){t.removeEventListener(e,n,!1)});if(t.attachEvent){var o=function(t){n(r(t))};return t.attachEvent("on"+e,o),h(function(){t.detachEvent("on"+e,o)})}return t["on"+e]=n,h(function(){t["on"+e]=null})}function i(t,e,n){var r=new f;if("function"==typeof t.item&&"number"==typeof t.length)for(var s=0,u=t.length;u>s;s++)r.add(i(t.item(s),e,n));else t&&r.add(o(t,e,n));return r}var s=n.Observable,u=(s.prototype,s.fromPromise),c=s.throwException,a=n.AnonymousObservable,l=n.AsyncSubject,h=n.Disposable.create,f=n.CompositeDisposable,p=n.Scheduler.immediate,d=n.Scheduler.timeout,b=Array.prototype.slice;s.start=function(t,e,n){return v(t,e,n)()};var v=s.toAsync=function(t,e,n){return e||(e=d),function(){var r=arguments,o=new l;return e.schedule(function(){var e;try{e=t.apply(n,r)}catch(i){return o.onError(i),undefined}o.onNext(e),o.onCompleted()}),o.asObservable()}};s.fromCallback=function(t,e,n,r){return e||(e=p),function(){var o=b.call(arguments,0);return new a(function(i){return e.schedule(function(){function e(t){var e=t;if(r)try{e=r(arguments)}catch(n){return i.onError(n),undefined}else 1===e.length&&(e=e[0]);i.onNext(e),i.onCompleted()}o.push(e),t.apply(n,o)})})}},s.fromNodeCallback=function(t,e,n,r){return e||(e=p),function(){var o=b.call(arguments,0);return new a(function(i){return e.schedule(function(){function e(t){if(t)return i.onError(t),undefined;var e=b.call(arguments,1);if(r)try{e=r(e)}catch(n){return i.onError(n),undefined}else 1===e.length&&(e=e[0]);i.onNext(e),i.onCompleted()}o.push(e),t.apply(n,o)})})}};var m=t.angular&&angular.element?angular.element:t.jQuery?t.jQuery:t.Zepto?t.Zepto:null,y=!!t.Ember&&"function"==typeof t.Ember.addListener;s.fromEvent=function(t,e,n){if(y)return w(function(){Ember.addListener(t,e)},function(){Ember.removeListener(t,e)},n);if(m){var r=m(t);return w(function(t){r.on(e,t)},function(t){r.off(e,t)},n)}return new a(function(r){return i(t,e,function(t){var e=t;if(n)try{e=n(arguments)}catch(o){return r.onError(o),undefined}r.onNext(e)})}).publish().refCount()};var w=s.fromEventPattern=function(t,e,n){return new a(function(r){function o(t){var e=t;if(n)try{e=n(arguments)}catch(o){return r.onError(o),undefined}r.onNext(e)}var i=t(o);return h(function(){e&&e(o,i)})}).publish().refCount()};return s.startAsync=function(t){var e;try{e=t()}catch(n){return c(n)}return u(e)},n}); -------------------------------------------------------------------------------- /demos/assets/rx/rx.async.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | ;(function (factory) { 4 | var objectTypes = { 5 | 'boolean': false, 6 | 'function': true, 7 | 'object': true, 8 | 'number': false, 9 | 'string': false, 10 | 'undefined': false 11 | }; 12 | 13 | var root = (objectTypes[typeof window] && window) || this, 14 | freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports, 15 | freeModule = objectTypes[typeof module] && module && !module.nodeType && module, 16 | moduleExports = freeModule && freeModule.exports === freeExports && freeExports, 17 | freeGlobal = objectTypes[typeof global] && global; 18 | 19 | if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { 20 | root = freeGlobal; 21 | } 22 | 23 | // Because of build optimizers 24 | if (typeof define === 'function' && define.amd) { 25 | define(['rx.binding', 'exports'], function (Rx, exports) { 26 | root.Rx = factory(root, exports, Rx); 27 | return root.Rx; 28 | }); 29 | } else if (typeof module === 'object' && module && module.exports === freeExports) { 30 | module.exports = factory(root, module.exports, require('./rx')); 31 | } else { 32 | root.Rx = factory(root, {}, root.Rx); 33 | } 34 | }.call(this, function (root, exp, Rx, undefined) { 35 | 36 | // Aliases 37 | var Observable = Rx.Observable, 38 | observableProto = Observable.prototype, 39 | observableFromPromise = Observable.fromPromise, 40 | observableThrow = Observable.throwException, 41 | AnonymousObservable = Rx.AnonymousObservable, 42 | AsyncSubject = Rx.AsyncSubject, 43 | disposableCreate = Rx.Disposable.create, 44 | CompositeDisposable= Rx.CompositeDisposable, 45 | immediateScheduler = Rx.Scheduler.immediate, 46 | timeoutScheduler = Rx.Scheduler.timeout, 47 | slice = Array.prototype.slice; 48 | 49 | /** 50 | * Invokes the specified function asynchronously on the specified scheduler, surfacing the result through an observable sequence. 51 | * 52 | * @example 53 | * var res = Rx.Observable.start(function () { console.log('hello'); }); 54 | * var res = Rx.Observable.start(function () { console.log('hello'); }, Rx.Scheduler.timeout); 55 | * var res = Rx.Observable.start(function () { this.log('hello'); }, Rx.Scheduler.timeout, console); 56 | * 57 | * @param {Function} func Function to run asynchronously. 58 | * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout. 59 | * @param [context] The context for the func parameter to be executed. If not specified, defaults to undefined. 60 | * @returns {Observable} An observable sequence exposing the function's result value, or an exception. 61 | * 62 | * Remarks 63 | * * The function is called immediately, not during the subscription of the resulting sequence. 64 | * * Multiple subscriptions to the resulting sequence can observe the function's result. 65 | */ 66 | Observable.start = function (func, scheduler, context) { 67 | return observableToAsync(func, scheduler, context)(); 68 | }; 69 | 70 | /** 71 | * Converts the function into an asynchronous function. Each invocation of the resulting asynchronous function causes an invocation of the original synchronous function on the specified scheduler. 72 | * 73 | * @example 74 | * var res = Rx.Observable.toAsync(function (x, y) { return x + y; })(4, 3); 75 | * var res = Rx.Observable.toAsync(function (x, y) { return x + y; }, Rx.Scheduler.timeout)(4, 3); 76 | * var res = Rx.Observable.toAsync(function (x) { this.log(x); }, Rx.Scheduler.timeout, console)('hello'); 77 | * 78 | * @param {Function} function Function to convert to an asynchronous function. 79 | * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout. 80 | * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined. 81 | * @returns {Function} Asynchronous function. 82 | */ 83 | var observableToAsync = Observable.toAsync = function (func, scheduler, context) { 84 | scheduler || (scheduler = timeoutScheduler); 85 | return function () { 86 | var args = arguments, 87 | subject = new AsyncSubject(); 88 | 89 | scheduler.schedule(function () { 90 | var result; 91 | try { 92 | result = func.apply(context, args); 93 | } catch (e) { 94 | subject.onError(e); 95 | return; 96 | } 97 | subject.onNext(result); 98 | subject.onCompleted(); 99 | }); 100 | return subject.asObservable(); 101 | }; 102 | }; 103 | 104 | /** 105 | * Converts a callback function to an observable sequence. 106 | * 107 | * @param {Function} function Function with a callback as the last parameter to convert to an Observable sequence. 108 | * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout. 109 | * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined. 110 | * @param {Function} [selector] A selector which takes the arguments from the callback to produce a single item to yield on next. 111 | * @returns {Function} A function, when executed with the required parameters minus the callback, produces an Observable sequence with a single value of the arguments to the callback as an array. 112 | */ 113 | Observable.fromCallback = function (func, scheduler, context, selector) { 114 | scheduler || (scheduler = immediateScheduler); 115 | return function () { 116 | var args = slice.call(arguments, 0); 117 | 118 | return new AnonymousObservable(function (observer) { 119 | return scheduler.schedule(function () { 120 | function handler(e) { 121 | var results = e; 122 | 123 | if (selector) { 124 | try { 125 | results = selector(arguments); 126 | } catch (err) { 127 | observer.onError(err); 128 | return; 129 | } 130 | } else { 131 | if (results.length === 1) { 132 | results = results[0]; 133 | } 134 | } 135 | 136 | observer.onNext(results); 137 | observer.onCompleted(); 138 | } 139 | 140 | args.push(handler); 141 | func.apply(context, args); 142 | }); 143 | }); 144 | }; 145 | }; 146 | 147 | /** 148 | * Converts a Node.js callback style function to an observable sequence. This must be in function (err, ...) format. 149 | * @param {Function} func The function to call 150 | * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout. 151 | * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined. 152 | * @param {Function} [selector] A selector which takes the arguments from the callback minus the error to produce a single item to yield on next. 153 | * @returns {Function} An async function which when applied, returns an observable sequence with the callback arguments as an array. 154 | */ 155 | Observable.fromNodeCallback = function (func, scheduler, context, selector) { 156 | scheduler || (scheduler = immediateScheduler); 157 | return function () { 158 | var args = slice.call(arguments, 0); 159 | 160 | return new AnonymousObservable(function (observer) { 161 | return scheduler.schedule(function () { 162 | 163 | function handler(err) { 164 | if (err) { 165 | observer.onError(err); 166 | return; 167 | } 168 | 169 | var results = slice.call(arguments, 1); 170 | 171 | if (selector) { 172 | try { 173 | results = selector(results); 174 | } catch (e) { 175 | observer.onError(e); 176 | return; 177 | } 178 | } else { 179 | if (results.length === 1) { 180 | results = results[0]; 181 | } 182 | } 183 | 184 | observer.onNext(results); 185 | observer.onCompleted(); 186 | } 187 | 188 | args.push(handler); 189 | func.apply(context, args); 190 | }); 191 | }); 192 | }; 193 | }; 194 | 195 | function createListener (element, name, handler) { 196 | // Node.js specific 197 | if (element.addListener) { 198 | element.addListener(name, handler); 199 | return disposableCreate(function () { 200 | element.removeListener(name, handler); 201 | }); 202 | } 203 | if (element.addEventListener) { 204 | element.addEventListener(name, handler, false); 205 | return disposableCreate(function () { 206 | element.removeEventListener(name, handler, false); 207 | }); 208 | } 209 | throw new Error('No listener found'); 210 | } 211 | 212 | function createEventListener (el, eventName, handler) { 213 | var disposables = new CompositeDisposable(); 214 | 215 | // Asume NodeList 216 | if (typeof el.item === 'function' && typeof el.length === 'number') { 217 | for (var i = 0, len = el.length; i < len; i++) { 218 | disposables.add(createEventListener(el.item(i), eventName, handler)); 219 | } 220 | } else if (el) { 221 | disposables.add(createListener(el, eventName, handler)); 222 | } 223 | 224 | return disposables; 225 | } 226 | 227 | // Check for Angular/jQuery/Zepto support 228 | var jq = 229 | !!root.angular && !!angular.element ? angular.element : 230 | (!!root.jQuery ? root.jQuery : ( 231 | !!root.Zepto ? root.Zepto : null)); 232 | 233 | // Check for ember 234 | var ember = !!root.Ember && typeof root.Ember.addListener === 'function'; 235 | 236 | /** 237 | * Creates an observable sequence by adding an event listener to the matching DOMElement or each item in the NodeList. 238 | * 239 | * @example 240 | * var source = Rx.Observable.fromEvent(element, 'mouseup'); 241 | * 242 | * @param {Object} element The DOMElement or NodeList to attach a listener. 243 | * @param {String} eventName The event name to attach the observable sequence. 244 | * @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next. 245 | * @returns {Observable} An observable sequence of events from the specified element and the specified event. 246 | */ 247 | Observable.fromEvent = function (element, eventName, selector) { 248 | if (ember) { 249 | return fromEventPattern( 250 | function (h) { Ember.addListener(element, eventName); }, 251 | function (h) { Ember.removeListener(element, eventName); }, 252 | selector); 253 | } 254 | if (jq) { 255 | var $elem = jq(element); 256 | return fromEventPattern( 257 | function (h) { $elem.on(eventName, h); }, 258 | function (h) { $elem.off(eventName, h); }, 259 | selector); 260 | } 261 | return new AnonymousObservable(function (observer) { 262 | return createEventListener( 263 | element, 264 | eventName, 265 | function handler (e) { 266 | var results = e; 267 | 268 | if (selector) { 269 | try { 270 | results = selector(arguments); 271 | } catch (err) { 272 | observer.onError(err); 273 | return 274 | } 275 | } 276 | 277 | observer.onNext(results); 278 | }); 279 | }).publish().refCount(); 280 | }; 281 | /** 282 | * Creates an observable sequence from an event emitter via an addHandler/removeHandler pair. 283 | * @param {Function} addHandler The function to add a handler to the emitter. 284 | * @param {Function} [removeHandler] The optional function to remove a handler from an emitter. 285 | * @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next. 286 | * @returns {Observable} An observable sequence which wraps an event from an event emitter 287 | */ 288 | var fromEventPattern = Observable.fromEventPattern = function (addHandler, removeHandler, selector) { 289 | return new AnonymousObservable(function (observer) { 290 | function innerHandler (e) { 291 | var result = e; 292 | if (selector) { 293 | try { 294 | result = selector(arguments); 295 | } catch (err) { 296 | observer.onError(err); 297 | return; 298 | } 299 | } 300 | observer.onNext(result); 301 | } 302 | 303 | var returnValue = addHandler(innerHandler); 304 | return disposableCreate(function () { 305 | if (removeHandler) { 306 | removeHandler(innerHandler, returnValue); 307 | } 308 | }); 309 | }).publish().refCount(); 310 | }; 311 | 312 | /** 313 | * Invokes the asynchronous function, surfacing the result through an observable sequence. 314 | * @param {Function} functionAsync Asynchronous function which returns a Promise to run. 315 | * @returns {Observable} An observable sequence exposing the function's result value, or an exception. 316 | */ 317 | Observable.startAsync = function (functionAsync) { 318 | var promise; 319 | try { 320 | promise = functionAsync(); 321 | } catch (e) { 322 | return observableThrow(e); 323 | } 324 | return observableFromPromise(promise); 325 | } 326 | 327 | return Rx; 328 | })); -------------------------------------------------------------------------------- /demos/assets/rx/rx.async.min.js: -------------------------------------------------------------------------------- 1 | (function(t){var e={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},n=e[typeof window]&&window||this,r=e[typeof exports]&&exports&&!exports.nodeType&&exports,o=e[typeof module]&&module&&!module.nodeType&&module,i=(o&&o.exports===r&&r,e[typeof global]&&global);!i||i.global!==i&&i.window!==i||(n=i),"function"==typeof define&&define.amd?define(["rx.binding","exports"],function(e,r){return n.Rx=t(n,r,e),n.Rx}):"object"==typeof module&&module&&module.exports===r?module.exports=t(n,module.exports,require("./rx")):n.Rx=t(n,{},n.Rx)}).call(this,function(t,e,n){function r(t,e,n){if(t.addListener)return t.addListener(e,n),l(function(){t.removeListener(e,n)});if(t.addEventListener)return t.addEventListener(e,n,!1),l(function(){t.removeEventListener(e,n,!1)});throw Error("No listener found")}function o(t,e,n){var i=new f;if("function"==typeof t.item&&"number"==typeof t.length)for(var s=0,u=t.length;u>s;s++)i.add(o(t.item(s),e,n));else t&&i.add(r(t,e,n));return i}var i=n.Observable,s=(i.prototype,i.fromPromise),u=i.throwException,c=n.AnonymousObservable,a=n.AsyncSubject,l=n.Disposable.create,f=n.CompositeDisposable,h=n.Scheduler.immediate,p=n.Scheduler.timeout,d=Array.prototype.slice;i.start=function(t,e,n){return b(t,e,n)()};var b=i.toAsync=function(t,e,n){return e||(e=p),function(){var r=arguments,o=new a;return e.schedule(function(){var e;try{e=t.apply(n,r)}catch(i){return o.onError(i),undefined}o.onNext(e),o.onCompleted()}),o.asObservable()}};i.fromCallback=function(t,e,n,r){return e||(e=h),function(){var o=d.call(arguments,0);return new c(function(i){return e.schedule(function(){function e(t){var e=t;if(r)try{e=r(arguments)}catch(n){return i.onError(n),undefined}else 1===e.length&&(e=e[0]);i.onNext(e),i.onCompleted()}o.push(e),t.apply(n,o)})})}},i.fromNodeCallback=function(t,e,n,r){return e||(e=h),function(){var o=d.call(arguments,0);return new c(function(i){return e.schedule(function(){function e(t){if(t)return i.onError(t),undefined;var e=d.call(arguments,1);if(r)try{e=r(e)}catch(n){return i.onError(n),undefined}else 1===e.length&&(e=e[0]);i.onNext(e),i.onCompleted()}o.push(e),t.apply(n,o)})})}};var v=t.angular&&angular.element?angular.element:t.jQuery?t.jQuery:t.Zepto?t.Zepto:null,m=!!t.Ember&&"function"==typeof t.Ember.addListener;i.fromEvent=function(t,e,n){if(m)return y(function(){Ember.addListener(t,e)},function(){Ember.removeListener(t,e)},n);if(v){var r=v(t);return y(function(t){r.on(e,t)},function(t){r.off(e,t)},n)}return new c(function(r){return o(t,e,function(t){var e=t;if(n)try{e=n(arguments)}catch(o){return r.onError(o),undefined}r.onNext(e)})}).publish().refCount()};var y=i.fromEventPattern=function(t,e,n){return new c(function(r){function o(t){var e=t;if(n)try{e=n(arguments)}catch(o){return r.onError(o),undefined}r.onNext(e)}var i=t(o);return l(function(){e&&e(o,i)})}).publish().refCount()};return i.startAsync=function(t){var e;try{e=t()}catch(n){return u(n)}return s(e)},n}); -------------------------------------------------------------------------------- /demos/assets/rx/rx.backpressure.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | ;(function (factory) { 4 | var objectTypes = { 5 | 'boolean': false, 6 | 'function': true, 7 | 'object': true, 8 | 'number': false, 9 | 'string': false, 10 | 'undefined': false 11 | }; 12 | 13 | var root = (objectTypes[typeof window] && window) || this, 14 | freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports, 15 | freeModule = objectTypes[typeof module] && module && !module.nodeType && module, 16 | moduleExports = freeModule && freeModule.exports === freeExports && freeExports, 17 | freeGlobal = objectTypes[typeof global] && global; 18 | 19 | if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { 20 | root = freeGlobal; 21 | } 22 | 23 | // Because of build optimizers 24 | if (typeof define === 'function' && define.amd) { 25 | define(['rx', 'exports'], function (Rx, exports) { 26 | root.Rx = factory(root, exports, Rx); 27 | return root.Rx; 28 | }); 29 | } else if (typeof module === 'object' && module && module.exports === freeExports) { 30 | module.exports = factory(root, module.exports, require('./rx')); 31 | } else { 32 | root.Rx = factory(root, {}, root.Rx); 33 | } 34 | }.call(this, function (root, exp, Rx, undefined) { 35 | 36 | // References 37 | var Observable = Rx.Observable, 38 | observableProto = Observable.prototype, 39 | AnonymousObservable = Rx.AnonymousObservable, 40 | CompositeDisposable = Rx.CompositeDisposable, 41 | Subject = Rx.Subject, 42 | Observer = Rx.Observer, 43 | disposableEmpty = Rx.Disposable.empty, 44 | disposableCreate = Rx.Disposable.create, 45 | inherits = Rx.internals.inherits, 46 | addProperties = Rx.internals.addProperties, 47 | timeoutScheduler = Rx.Scheduler.timeout, 48 | identity = Rx.helpers.identity; 49 | 50 | var objectDisposed = 'Object has been disposed'; 51 | function checkDisposed() { if (this.isDisposed) { throw new Error(objectDisposed); } } 52 | 53 | var PausableObservable = (function (_super) { 54 | 55 | inherits(PausableObservable, _super); 56 | 57 | function subscribe(observer) { 58 | var conn = this.source.publish(), 59 | subscription = conn.subscribe(observer), 60 | connection = disposableEmpty; 61 | 62 | var pausable = this.subject.distinctUntilChanged().subscribe(function (b) { 63 | if (b) { 64 | connection = conn.connect(); 65 | } else { 66 | connection.dispose(); 67 | connection = disposableEmpty; 68 | } 69 | }); 70 | 71 | return new CompositeDisposable(subscription, connection, pausable); 72 | } 73 | 74 | function PausableObservable(source, subject) { 75 | this.source = source; 76 | this.subject = subject || new Subject(); 77 | this.isPaused = true; 78 | _super.call(this, subscribe); 79 | } 80 | 81 | PausableObservable.prototype.pause = function () { 82 | if (this.isPaused === true){ 83 | return; 84 | } 85 | this.isPaused = true; 86 | this.subject.onNext(false); 87 | }; 88 | 89 | PausableObservable.prototype.resume = function () { 90 | if (this.isPaused === false){ 91 | return; 92 | } 93 | this.isPaused = false; 94 | this.subject.onNext(true); 95 | }; 96 | 97 | return PausableObservable; 98 | 99 | }(Observable)); 100 | 101 | /** 102 | * Pauses the underlying observable sequence based upon the observable sequence which yields true/false. 103 | * @example 104 | * var pauser = new Rx.Subject(); 105 | * var source = Rx.Observable.interval(100).pausable(pauser); 106 | * @param {Observable} pauser The observable sequence used to pause the underlying sequence. 107 | * @returns {Observable} The observable sequence which is paused based upon the pauser. 108 | */ 109 | observableProto.pausable = function (pauser) { 110 | return new PausableObservable(this, pauser); 111 | }; 112 | function combineLatestSource(source, subject, resultSelector) { 113 | return new AnonymousObservable(function (observer) { 114 | var n = 2, 115 | hasValue = [false, false], 116 | hasValueAll = false, 117 | isDone = false, 118 | values = new Array(n); 119 | 120 | function next(x, i) { 121 | values[i] = x 122 | var res; 123 | hasValue[i] = true; 124 | if (hasValueAll || (hasValueAll = hasValue.every(identity))) { 125 | try { 126 | res = resultSelector.apply(null, values); 127 | } catch (ex) { 128 | observer.onError(ex); 129 | return; 130 | } 131 | observer.onNext(res); 132 | } else if (isDone) { 133 | observer.onCompleted(); 134 | } 135 | } 136 | 137 | return new CompositeDisposable( 138 | source.subscribe( 139 | function (x) { 140 | next(x, 0); 141 | }, 142 | observer.onError.bind(observer), 143 | function () { 144 | isDone = true; 145 | observer.onCompleted(); 146 | }), 147 | subject.subscribe( 148 | function (x) { 149 | next(x, 1); 150 | }, 151 | observer.onError.bind(observer)) 152 | ); 153 | }); 154 | } 155 | 156 | var PausableBufferedObservable = (function (_super) { 157 | 158 | inherits(PausableBufferedObservable, _super); 159 | 160 | function subscribe(observer) { 161 | var q = [], previous = true; 162 | 163 | var subscription = 164 | combineLatestSource( 165 | this.source, 166 | this.subject.distinctUntilChanged(), 167 | function (data, shouldFire) { 168 | return { data: data, shouldFire: shouldFire }; 169 | }) 170 | .subscribe( 171 | function (results) { 172 | if (results.shouldFire && previous) { 173 | observer.onNext(results.data); 174 | } 175 | if (results.shouldFire && !previous) { 176 | while (q.length > 0) { 177 | observer.onNext(q.shift()); 178 | } 179 | previous = true; 180 | } else if (!results.shouldFire && !previous) { 181 | q.push(results.data); 182 | } else if (!results.shouldFire && previous) { 183 | previous = false; 184 | } 185 | 186 | }, 187 | observer.onError.bind(observer), 188 | observer.onCompleted.bind(observer) 189 | ); 190 | 191 | this.subject.onNext(false); 192 | 193 | return subscription; 194 | } 195 | 196 | function PausableBufferedObservable(source, subject) { 197 | this.source = source; 198 | this.subject = subject || new Subject(); 199 | this.isPaused = true; 200 | _super.call(this, subscribe); 201 | } 202 | 203 | PausableBufferedObservable.prototype.pause = function () { 204 | if (this.isPaused === true){ 205 | return; 206 | } 207 | this.isPaused = true; 208 | this.subject.onNext(false); 209 | }; 210 | 211 | PausableBufferedObservable.prototype.resume = function () { 212 | if (this.isPaused === false){ 213 | return; 214 | } 215 | this.isPaused = false; 216 | this.subject.onNext(true); 217 | }; 218 | 219 | return PausableBufferedObservable; 220 | 221 | }(Observable)); 222 | 223 | /** 224 | * Pauses the underlying observable sequence based upon the observable sequence which yields true/false, 225 | * and yields the values that were buffered while paused. 226 | * @example 227 | * var pauser = new Rx.Subject(); 228 | * var source = Rx.Observable.interval(100).pausableBuffered(pauser); 229 | * @param {Observable} pauser The observable sequence used to pause the underlying sequence. 230 | * @returns {Observable} The observable sequence which is paused based upon the pauser. 231 | */ 232 | observableProto.pausableBuffered = function (subject) { 233 | return new PausableBufferedObservable(this, subject); 234 | }; 235 | 236 | /** 237 | * Attaches a controller to the observable sequence with the ability to queue. 238 | * @example 239 | * var source = Rx.Observable.interval(100).controlled(); 240 | * source.request(3); // Reads 3 values 241 | * @param {Observable} pauser The observable sequence used to pause the underlying sequence. 242 | * @returns {Observable} The observable sequence which is paused based upon the pauser. 243 | */ 244 | observableProto.controlled = function (enableQueue) { 245 | if (enableQueue == null) { enableQueue = true; } 246 | return new ControlledObservable(this, enableQueue); 247 | }; 248 | var ControlledObservable = (function (_super) { 249 | 250 | inherits(ControlledObservable, _super); 251 | 252 | function subscribe (observer) { 253 | return this.source.subscribe(observer); 254 | } 255 | 256 | function ControlledObservable (source, enableQueue) { 257 | _super.call(this, subscribe); 258 | this.subject = new ControlledSubject(enableQueue); 259 | this.source = source.multicast(this.subject).refCount(); 260 | } 261 | 262 | ControlledObservable.prototype.request = function (numberOfItems) { 263 | if (numberOfItems == null) { numberOfItems = -1; } 264 | return this.subject.request(numberOfItems); 265 | }; 266 | 267 | return ControlledObservable; 268 | 269 | }(Observable)); 270 | 271 | var ControlledSubject = Rx.ControlledSubject = (function (_super) { 272 | 273 | function subscribe (observer) { 274 | return this.subject.subscribe(observer); 275 | } 276 | 277 | inherits(ControlledSubject, _super); 278 | 279 | function ControlledSubject(enableQueue) { 280 | if (enableQueue == null) { 281 | enableQueue = true; 282 | } 283 | 284 | _super.call(this, subscribe); 285 | this.subject = new Subject(); 286 | this.enableQueue = enableQueue; 287 | this.queue = enableQueue ? [] : null; 288 | this.requestedCount = 0; 289 | this.requestedDisposable = disposableEmpty; 290 | this.error = null; 291 | this.hasFailed = false; 292 | this.hasCompleted = false; 293 | this.controlledDisposable = disposableEmpty; 294 | } 295 | 296 | addProperties(ControlledSubject.prototype, Observer, { 297 | onCompleted: function () { 298 | checkDisposed.call(this); 299 | this.hasCompleted = true; 300 | 301 | if (!this.enableQueue || this.queue.length === 0) { 302 | this.subject.onCompleted(); 303 | } 304 | }, 305 | onError: function (error) { 306 | checkDisposed.call(this); 307 | this.hasFailed = true; 308 | this.error = error; 309 | 310 | if (!this.enableQueue || this.queue.length === 0) { 311 | this.subject.onError(error); 312 | } 313 | }, 314 | onNext: function (value) { 315 | checkDisposed.call(this); 316 | var hasRequested = false; 317 | 318 | if (this.requestedCount === 0) { 319 | if (this.enableQueue) { 320 | this.queue.push(value); 321 | } 322 | } else { 323 | if (this.requestedCount !== -1) { 324 | if (this.requestedCount-- === 0) { 325 | this.disposeCurrentRequest(); 326 | } 327 | } 328 | hasRequested = true; 329 | } 330 | 331 | if (hasRequested) { 332 | this.subject.onNext(value); 333 | } 334 | }, 335 | _processRequest: function (numberOfItems) { 336 | if (this.enableQueue) { 337 | //console.log('queue length', this.queue.length); 338 | 339 | while (this.queue.length >= numberOfItems && numberOfItems > 0) { 340 | //console.log('number of items', numberOfItems); 341 | this.subject.onNext(this.queue.shift()); 342 | numberOfItems--; 343 | } 344 | 345 | if (this.queue.length !== 0) { 346 | return { numberOfItems: numberOfItems, returnValue: true }; 347 | } else { 348 | return { numberOfItems: numberOfItems, returnValue: false }; 349 | } 350 | } 351 | 352 | if (this.hasFailed) { 353 | this.subject.onError(this.error); 354 | this.controlledDisposable.dispose(); 355 | this.controlledDisposable = disposableEmpty; 356 | } else if (this.hasCompleted) { 357 | this.subject.onCompleted(); 358 | this.controlledDisposable.dispose(); 359 | this.controlledDisposable = disposableEmpty; 360 | } 361 | 362 | return { numberOfItems: numberOfItems, returnValue: false }; 363 | }, 364 | request: function (number) { 365 | checkDisposed.call(this); 366 | this.disposeCurrentRequest(); 367 | var self = this, 368 | r = this._processRequest(number); 369 | 370 | number = r.numberOfItems; 371 | if (!r.returnValue) { 372 | this.requestedCount = number; 373 | this.requestedDisposable = disposableCreate(function () { 374 | self.requestedCount = 0; 375 | }); 376 | 377 | return this.requestedDisposable 378 | } else { 379 | return disposableEmpty; 380 | } 381 | }, 382 | disposeCurrentRequest: function () { 383 | this.requestedDisposable.dispose(); 384 | this.requestedDisposable = disposableEmpty; 385 | }, 386 | 387 | dispose: function () { 388 | this.isDisposed = true; 389 | this.error = null; 390 | this.subject.dispose(); 391 | this.requestedDisposable.dispose(); 392 | } 393 | }); 394 | 395 | return ControlledSubject; 396 | }(Observable)); 397 | return Rx; 398 | })); -------------------------------------------------------------------------------- /demos/assets/rx/rx.backpressure.min.js: -------------------------------------------------------------------------------- 1 | (function(t){var e={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},n=e[typeof window]&&window||this,r=e[typeof exports]&&exports&&!exports.nodeType&&exports,i=e[typeof module]&&module&&!module.nodeType&&module,o=(i&&i.exports===r&&r,e[typeof global]&&global);!o||o.global!==o&&o.window!==o||(n=o),"function"==typeof define&&define.amd?define(["rx","exports"],function(e,r){return n.Rx=t(n,r,e),n.Rx}):"object"==typeof module&&module&&module.exports===r?module.exports=t(n,module.exports,require("./rx")):n.Rx=t(n,{},n.Rx)}).call(this,function(t,e,n){function r(){if(this.isDisposed)throw Error(v)}function i(t,e,n){return new u(function(r){function i(t,e){h[e]=t;var i;if(s[e]=!0,u||(u=s.every(b))){try{i=n.apply(null,h)}catch(o){return r.onError(o),undefined}r.onNext(i)}else a&&r.onCompleted()}var o=2,s=[!1,!1],u=!1,a=!1,h=Array(o);return new c(t.subscribe(function(t){i(t,0)},r.onError.bind(r),function(){a=!0,r.onCompleted()}),e.subscribe(function(t){i(t,1)},r.onError.bind(r)))})}var o=n.Observable,s=o.prototype,u=n.AnonymousObservable,c=n.CompositeDisposable,a=n.Subject,h=n.Observer,l=n.Disposable.empty,f=n.Disposable.create,p=n.internals.inherits,d=n.internals.addProperties,b=(n.Scheduler.timeout,n.helpers.identity),v="Object has been disposed",m=function(t){function e(t){var e=this.source.publish(),n=e.subscribe(t),r=l,i=this.subject.distinctUntilChanged().subscribe(function(t){t?r=e.connect():(r.dispose(),r=l)});return new c(n,r,i)}function n(n,r){this.source=n,this.subject=r||new a,this.isPaused=!0,t.call(this,e)}return p(n,t),n.prototype.pause=function(){this.isPaused!==!0&&(this.isPaused=!0,this.subject.onNext(!1))},n.prototype.resume=function(){this.isPaused!==!1&&(this.isPaused=!1,this.subject.onNext(!0))},n}(o);s.pausable=function(t){return new m(this,t)};var y=function(t){function e(t){var e=[],n=!0,r=i(this.source,this.subject.distinctUntilChanged(),function(t,e){return{data:t,shouldFire:e}}).subscribe(function(r){if(r.shouldFire&&n&&t.onNext(r.data),r.shouldFire&&!n){for(;e.length>0;)t.onNext(e.shift());n=!0}else r.shouldFire||n?!r.shouldFire&&n&&(n=!1):e.push(r.data)},t.onError.bind(t),t.onCompleted.bind(t));return this.subject.onNext(!1),r}function n(n,r){this.source=n,this.subject=r||new a,this.isPaused=!0,t.call(this,e)}return p(n,t),n.prototype.pause=function(){this.isPaused!==!0&&(this.isPaused=!0,this.subject.onNext(!1))},n.prototype.resume=function(){this.isPaused!==!1&&(this.isPaused=!1,this.subject.onNext(!0))},n}(o);s.pausableBuffered=function(t){return new y(this,t)},s.controlled=function(t){return null==t&&(t=!0),new w(this,t)};var w=function(t){function e(t){return this.source.subscribe(t)}function n(n,r){t.call(this,e),this.subject=new g(r),this.source=n.multicast(this.subject).refCount()}return p(n,t),n.prototype.request=function(t){return null==t&&(t=-1),this.subject.request(t)},n}(o),g=n.ControlledSubject=function(t){function e(t){return this.subject.subscribe(t)}function n(n){null==n&&(n=!0),t.call(this,e),this.subject=new a,this.enableQueue=n,this.queue=n?[]:null,this.requestedCount=0,this.requestedDisposable=l,this.error=null,this.hasFailed=!1,this.hasCompleted=!1,this.controlledDisposable=l}return p(n,t),d(n.prototype,h,{onCompleted:function(){r.call(this),this.hasCompleted=!0,this.enableQueue&&0!==this.queue.length||this.subject.onCompleted()},onError:function(t){r.call(this),this.hasFailed=!0,this.error=t,this.enableQueue&&0!==this.queue.length||this.subject.onError(t)},onNext:function(t){r.call(this);var e=!1;0===this.requestedCount?this.enableQueue&&this.queue.push(t):(-1!==this.requestedCount&&0===this.requestedCount--&&this.disposeCurrentRequest(),e=!0),e&&this.subject.onNext(t)},_processRequest:function(t){if(this.enableQueue){for(;this.queue.length>=t&&t>0;)this.subject.onNext(this.queue.shift()),t--;return 0!==this.queue.length?{numberOfItems:t,returnValue:!0}:{numberOfItems:t,returnValue:!1}}return this.hasFailed?(this.subject.onError(this.error),this.controlledDisposable.dispose(),this.controlledDisposable=l):this.hasCompleted&&(this.subject.onCompleted(),this.controlledDisposable.dispose(),this.controlledDisposable=l),{numberOfItems:t,returnValue:!1}},request:function(t){r.call(this),this.disposeCurrentRequest();var e=this,n=this._processRequest(t);return t=n.numberOfItems,n.returnValue?l:(this.requestedCount=t,this.requestedDisposable=f(function(){e.requestedCount=0}),this.requestedDisposable)},disposeCurrentRequest:function(){this.requestedDisposable.dispose(),this.requestedDisposable=l},dispose:function(){this.isDisposed=!0,this.error=null,this.subject.dispose(),this.requestedDisposable.dispose()}}),n}(o);return n}); -------------------------------------------------------------------------------- /demos/assets/rx/rx.binding.min.js: -------------------------------------------------------------------------------- 1 | (function(t){var e={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},n=e[typeof window]&&window||this,r=e[typeof exports]&&exports&&!exports.nodeType&&exports,o=e[typeof module]&&module&&!module.nodeType&&module,i=(o&&o.exports===r&&r,e[typeof global]&&global);!i||i.global!==i&&i.window!==i||(n=i),"function"==typeof define&&define.amd?define(["rx","exports"],function(e,r){return n.Rx=t(n,r,e),n.Rx}):"object"==typeof module&&module&&module.exports===r?module.exports=t(n,module.exports,require("./rx")):n.Rx=t(n,{},n.Rx)}).call(this,function(t,e,n){function r(){if(this.isDisposed)throw Error(m)}var o=n.Observable,i=o.prototype,s=n.AnonymousObservable,u=n.Subject,c=n.AsyncSubject,a=n.Observer,l=n.internals.ScheduledObserver,h=n.Disposable.create,f=n.Disposable.empty,p=n.CompositeDisposable,d=n.Scheduler.currentThread,b=n.internals.inherits,v=n.internals.addProperties,m="Object has been disposed";i.multicast=function(t,e){var n=this;return"function"==typeof t?new s(function(r){var o=n.multicast(t());return new p(e(o).subscribe(r),o.connect())}):new E(n,t)},i.publish=function(t){return t?this.multicast(function(){return new u},t):this.multicast(new u)},i.share=function(){return this.publish(null).refCount()},i.publishLast=function(t){return t?this.multicast(function(){return new c},t):this.multicast(new c)},i.publishValue=function(t,e){return 2===arguments.length?this.multicast(function(){return new w(e)},t):this.multicast(new w(t))},i.shareValue=function(t){return this.publishValue(t).refCount()},i.replay=function(t,e,n,r){return t?this.multicast(function(){return new g(e,n,r)},t):this.multicast(new g(e,n,r))},i.replayWhileObserved=function(t,e,n){return this.replay(null,t,e,n).refCount()};var y=function(t,e){this.subject=t,this.observer=e};y.prototype.dispose=function(){if(!this.subject.isDisposed&&null!==this.observer){var t=this.subject.observers.indexOf(this.observer);this.subject.observers.splice(t,1),this.observer=null}};var w=n.BehaviorSubject=function(t){function e(t){if(r.call(this),!this.isStopped)return this.observers.push(t),t.onNext(this.value),new y(this,t);var e=this.exception;return e?t.onError(e):t.onCompleted(),f}function n(n){t.call(this,e),this.value=n,this.observers=[],this.isDisposed=!1,this.isStopped=!1,this.exception=null}return b(n,t),v(n.prototype,a,{hasObservers:function(){return this.observers.length>0},onCompleted:function(){if(r.call(this),!this.isStopped){var t=this.observers.slice(0);this.isStopped=!0;for(var e=0,n=t.length;n>e;e++)t[e].onCompleted();this.observers=[]}},onError:function(t){if(r.call(this),!this.isStopped){var e=this.observers.slice(0);this.isStopped=!0,this.exception=t;for(var n=0,o=e.length;o>n;n++)e[n].onError(t);this.observers=[]}},onNext:function(t){if(r.call(this),!this.isStopped){this.value=t;for(var e=this.observers.slice(0),n=0,o=e.length;o>n;n++)e[n].onNext(t)}},dispose:function(){this.isDisposed=!0,this.observers=null,this.value=null,this.exception=null}}),n}(o),g=n.ReplaySubject=function(t){function e(t,e){this.subject=t,this.observer=e}function n(t){var n=new l(this.scheduler,t),o=new e(this,n);r.call(this),this._trim(this.scheduler.now()),this.observers.push(n);for(var i=this.q.length,s=0,u=this.q.length;u>s;s++)n.onNext(this.q[s].value);return this.hasError?(i++,n.onError(this.error)):this.isStopped&&(i++,n.onCompleted()),n.ensureActive(i),o}function o(e,r,o){this.bufferSize=null==e?Number.MAX_VALUE:e,this.windowSize=null==r?Number.MAX_VALUE:r,this.scheduler=o||d,this.q=[],this.observers=[],this.isStopped=!1,this.isDisposed=!1,this.hasError=!1,this.error=null,t.call(this,n)}return e.prototype.dispose=function(){if(this.observer.dispose(),!this.subject.isDisposed){var t=this.subject.observers.indexOf(this.observer);this.subject.observers.splice(t,1)}},b(o,t),v(o.prototype,a,{hasObservers:function(){return this.observers.length>0},_trim:function(t){for(;this.q.length>this.bufferSize;)this.q.shift();for(;this.q.length>0&&t-this.q[0].interval>this.windowSize;)this.q.shift()},onNext:function(t){var e;if(r.call(this),!this.isStopped){var n=this.scheduler.now();this.q.push({interval:n,value:t}),this._trim(n);for(var o=this.observers.slice(0),i=0,s=o.length;s>i;i++)e=o[i],e.onNext(t),e.ensureActive()}},onError:function(t){var e;if(r.call(this),!this.isStopped){this.isStopped=!0,this.error=t,this.hasError=!0;var n=this.scheduler.now();this._trim(n);for(var o=this.observers.slice(0),i=0,s=o.length;s>i;i++)e=o[i],e.onError(t),e.ensureActive();this.observers=[]}},onCompleted:function(){var t;if(r.call(this),!this.isStopped){this.isStopped=!0;var e=this.scheduler.now();this._trim(e);for(var n=this.observers.slice(0),o=0,i=n.length;i>o;o++)t=n[o],t.onCompleted(),t.ensureActive();this.observers=[]}},dispose:function(){this.isDisposed=!0,this.observers=null}}),o}(o),E=n.ConnectableObservable=function(t){function e(e,n){function r(t){return o.subject.subscribe(t)}var o={subject:n,source:e.asObservable(),hasSubscription:!1,subscription:null};this.connect=function(){return o.hasSubscription||(o.hasSubscription=!0,o.subscription=new p(o.source.subscribe(o.subject),h(function(){o.hasSubscription=!1}))),o.subscription},t.call(this,r)}return b(e,t),e.prototype.connect=function(){return this.connect()},e.prototype.refCount=function(){var t=null,e=0,n=this;return new s(function(r){var o,i;return e++,o=1===e,i=n.subscribe(r),o&&(t=n.connect()),h(function(){i.dispose(),e--,0===e&&t.dispose()})})},e}(o);return n}); -------------------------------------------------------------------------------- /demos/assets/rx/rx.coincidence.min.js: -------------------------------------------------------------------------------- 1 | (function(t){var e={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},n=e[typeof window]&&window||this,r=e[typeof exports]&&exports&&!exports.nodeType&&exports,o=e[typeof module]&&module&&!module.nodeType&&module,i=(o&&o.exports===r&&r,e[typeof global]&&global);!i||i.global!==i&&i.window!==i||(n=i),"function"==typeof define&&define.amd?define(["rx","exports"],function(e,r){return n.Rx=t(n,r,e),n.Rx}):"object"==typeof module&&module&&module.exports===r?module.exports=t(n,module.exports,require("./rx")):n.Rx=t(n,{},n.Rx)}).call(this,function(t,e,n,r){function o(t){if(false&t)return 2===t;for(var e=Math.sqrt(t),n=3;e>=n;){if(0===t%n)return!1;n+=2}return!0}function i(t){var e,n,r;for(e=0;D.length>e;++e)if(n=D[e],n>=t)return n;for(r=1|t;D[D.length-1]>r;){if(o(r))return r;r+=2}return t}function s(t){var e=757602046;if(!t.length)return e;for(var n=0,r=t.length;r>n;n++){var o=t.charCodeAt(n);e=(e<<5)-e+o,e&=e}return e}function u(t){var e=668265261;return t=61^t^t>>>16,t+=t<<3,t^=t>>>4,t*=e,t^=t>>>15}function c(){return{key:null,value:null,next:0,hashCode:0}}function a(t,e){return t.groupJoin(this,e,function(){return g()},function(t,e){return e})}function l(t){var e=this;return new w(function(n){var r=new m,o=new p,i=new d(o);return n.onNext(E(r,i)),o.add(e.subscribe(function(t){r.onNext(t)},function(t){r.onError(t),n.onError(t)},function(){r.onCompleted(),n.onCompleted()})),o.add(t.subscribe(function(){r.onCompleted(),r=new m,n.onNext(E(r,i))},function(t){r.onError(t),n.onError(t)},function(){r.onCompleted(),n.onCompleted()})),i})}function h(t){var e=this;return new w(function(n){var o,i=new v,s=new p(i),u=new d(s),c=new m;return n.onNext(E(c,u)),s.add(e.subscribe(function(t){c.onNext(t)},function(t){c.onError(t),n.onError(t)},function(){c.onCompleted(),n.onCompleted()})),o=function(){var e,s;try{s=t()}catch(a){return n.onError(a),r}e=new b,i.setDisposable(e),e.setDisposable(s.take(1).subscribe(C,function(t){c.onError(t),n.onError(t)},function(){c.onCompleted(),c=new m,n.onNext(E(c,u)),o()}))},o(),u})}var f=n.Observable,p=n.CompositeDisposable,d=n.RefCountDisposable,b=n.SingleAssignmentDisposable,v=n.SerialDisposable,m=n.Subject,y=f.prototype,g=f.empty,w=n.AnonymousObservable,E=(n.Observer.create,n.internals.addRef),x=n.internals.isEqual,C=n.helpers.noop,D=[1,3,7,13,31,61,127,251,509,1021,2039,4093,8191,16381,32749,65521,131071,262139,524287,1048573,2097143,4194301,8388593,16777213,33554393,67108859,134217689,268435399,536870909,1073741789,2147483647],S="no such key",N="duplicate key",A=function(){var t=0;return function(e){if(null==e)throw Error(S);if("string"==typeof e)return s(e);if("number"==typeof e)return u(e);if("boolean"==typeof e)return e===!0?1:0;if(e instanceof Date)return e.getTime();if(e.getHashCode)return e.getHashCode();var n=17*t++;return e.getHashCode=function(){return n},n}}(),_=function(t,e){if(0>t)throw Error("out of range");t>0&&this._initialize(t),this.comparer=e||x,this.freeCount=0,this.size=0,this.freeList=-1};return _.prototype._initialize=function(t){var e,n=i(t);for(this.buckets=Array(n),this.entries=Array(n),e=0;n>e;e++)this.buckets[e]=-1,this.entries[e]=c();this.freeList=-1},_.prototype.count=function(){return this.size},_.prototype.add=function(t,e){return this._insert(t,e,!0)},_.prototype._insert=function(t,e,n){this.buckets||this._initialize(0);for(var o,i=2147483647&A(t),s=i%this.buckets.length,u=this.buckets[s];u>=0;u=this.entries[u].next)if(this.entries[u].hashCode===i&&this.comparer(this.entries[u].key,t)){if(n)throw Error(N);return this.entries[u].value=e,r}this.freeCount>0?(o=this.freeList,this.freeList=this.entries[o].next,--this.freeCount):(this.size===this.entries.length&&(this._resize(),s=i%this.buckets.length),o=this.size,++this.size),this.entries[o].hashCode=i,this.entries[o].next=this.buckets[s],this.entries[o].key=t,this.entries[o].value=e,this.buckets[s]=o},_.prototype._resize=function(){var t=i(2*this.size),e=Array(t);for(r=0;e.length>r;++r)e[r]=-1;var n=Array(t);for(r=0;this.size>r;++r)n[r]=this.entries[r];for(var r=this.size;t>r;++r)n[r]=c();for(var o=0;this.size>o;++o){var s=n[o].hashCode%t;n[o].next=e[s],e[s]=o}this.buckets=e,this.entries=n},_.prototype.remove=function(t){if(this.buckets)for(var e=2147483647&A(t),n=e%this.buckets.length,r=-1,o=this.buckets[n];o>=0;o=this.entries[o].next){if(this.entries[o].hashCode===e&&this.comparer(this.entries[o].key,t))return 0>r?this.buckets[n]=this.entries[o].next:this.entries[r].next=this.entries[o].next,this.entries[o].hashCode=-1,this.entries[o].next=this.freeList,this.entries[o].key=null,this.entries[o].value=null,this.freeList=o,++this.freeCount,!0;r=o}return!1},_.prototype.clear=function(){var t,e;if(!(0>=this.size)){for(t=0,e=this.buckets.length;e>t;++t)this.buckets[t]=-1;for(t=0;this.size>t;++t)this.entries[t]=c();this.freeList=-1,this.size=0}},_.prototype._findEntry=function(t){if(this.buckets)for(var e=2147483647&A(t),n=this.buckets[e%this.buckets.length];n>=0;n=this.entries[n].next)if(this.entries[n].hashCode===e&&this.comparer(this.entries[n].key,t))return n;return-1},_.prototype.count=function(){return this.size-this.freeCount},_.prototype.tryGetValue=function(t){var e=this._findEntry(t);return e>=0?this.entries[e].value:r},_.prototype.getValues=function(){var t=0,e=[];if(this.entries)for(var n=0;this.size>n;n++)this.entries[n].hashCode>=0&&(e[t++]=this.entries[n].value);return e},_.prototype.get=function(t){var e=this._findEntry(t);if(e>=0)return this.entries[e].value;throw Error(S)},_.prototype.set=function(t,e){this._insert(t,e,!1)},_.prototype.containskey=function(t){return this._findEntry(t)>=0},y.join=function(t,e,n,o){var i=this;return new w(function(s){var u=new p,c=!1,a=0,l=new _,h=!1,f=0,d=new _;return u.add(i.subscribe(function(t){var n,i,h,f,p=a++,v=new b;l.add(p,t),u.add(v),i=function(){return l.remove(p)&&0===l.count()&&c&&s.onCompleted(),u.remove(v)};try{n=e(t)}catch(m){return s.onError(m),r}v.setDisposable(n.take(1).subscribe(C,s.onError.bind(s),function(){i()})),f=d.getValues();for(var y=0;f.length>y;y++){try{h=o(t,f[y])}catch(g){return s.onError(g),r}s.onNext(h)}},s.onError.bind(s),function(){c=!0,(h||0===l.count())&&s.onCompleted()})),u.add(t.subscribe(function(t){var e,i,c,a,p=f++,v=new b;d.add(p,t),u.add(v),i=function(){return d.remove(p)&&0===d.count()&&h&&s.onCompleted(),u.remove(v)};try{e=n(t)}catch(m){return s.onError(m),r}v.setDisposable(e.take(1).subscribe(C,s.onError.bind(s),function(){i()})),a=l.getValues();for(var y=0;a.length>y;y++){try{c=o(a[y],t)}catch(m){return s.onError(m),r}s.onNext(c)}},s.onError.bind(s),function(){h=!0,(c||0===d.count())&&s.onCompleted()})),u})},y.groupJoin=function(t,e,n,o){var i=this;return new w(function(s){var u=function(){},c=new p,a=new d(c),l=new _,h=new _,f=0,v=0;return c.add(i.subscribe(function(t){var n=new m,i=f++;l.add(i,n);var p,d,v,y,g;try{g=o(t,E(n,a))}catch(w){for(v=l.getValues(),p=0,d=v.length;d>p;p++)v[p].onError(w);return s.onError(w),r}for(s.onNext(g),y=h.getValues(),p=0,d=y.length;d>p;p++)n.onNext(y[p]);var x=new b;c.add(x);var C,D=function(){l.remove(i)&&n.onCompleted(),c.remove(x)};try{C=e(t)}catch(w){for(v=l.getValues(),p=0,d=l.length;d>p;p++)v[p].onError(w);return s.onError(w),r}x.setDisposable(C.take(1).subscribe(u,function(t){for(v=l.getValues(),p=0,d=v.length;d>p;p++)v[p].onError(t);s.onError(t)},D))},function(t){for(var e=l.getValues(),n=0,r=e.length;r>n;n++)e[n].onError(t);s.onError(t)},s.onCompleted.bind(s))),c.add(t.subscribe(function(t){var e,o,i,a=v++;h.add(a,t);var f=new b;c.add(f);var p,d=function(){h.remove(a),c.remove(f)};try{p=n(t)}catch(m){for(e=l.getValues(),o=0,i=l.length;i>o;o++)e[o].onError(m);return s.onError(m),r}for(f.setDisposable(p.take(1).subscribe(u,function(t){for(e=l.getValues(),o=0,i=l.length;i>o;o++)e[o].onError(t);s.onError(t)},d)),e=l.getValues(),o=0,i=e.length;i>o;o++)e[o].onNext(t)},function(t){for(var e=l.getValues(),n=0,r=e.length;r>n;n++)e[n].onError(t);s.onError(t)})),a})},y.buffer=function(){return this.window.apply(this,arguments).selectMany(function(t){return t.toArray()})},y.window=function(t,e){return 1===arguments.length&&"function"!=typeof arguments[0]?l.call(this,t):"function"==typeof t?h.call(this,t):a.call(this,t,e)},y.pairwise=function(){var t=this;return new w(function(e){var n,r=!1;return t.subscribe(function(t){r?e.onNext([n,t]):r=!0,n=t},e.onError.bind(e),e.onCompleted.bind(e))})},y.partition=function(t,e){var n=this.publish().refCount();return[n.filter(t,e),n.filter(function(n,r,o){return!t.call(e,n,r,o)})]},n}); -------------------------------------------------------------------------------- /demos/assets/rx/rx.experimental.min.js: -------------------------------------------------------------------------------- 1 | (function(t){var e={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},n=e[typeof window]&&window||this,r=e[typeof exports]&&exports&&!exports.nodeType&&exports,o=e[typeof module]&&module&&!module.nodeType&&module,i=(o&&o.exports===r&&r,e[typeof global]&&global);!i||i.global!==i&&i.window!==i||(n=i),"function"==typeof define&&define.amd?define(["rx","exports"],function(e,r){return n.Rx=t(n,r,e),n.Rx}):"object"==typeof module&&module&&module.exports===r?module.exports=t(n,module.exports,require("./rx")):n.Rx=t(n,{},n.Rx)}).call(this,function(t,e,n,r){function o(t,e){return 1===t.length&&Array.isArray(t[e])?t[e]:x.call(t)}function i(t,e){return new m(function(){return new v(function(){return t()?{done:!1,value:e}:{done:!0,value:r}})})}var s=n.Observable,u=s.prototype,c=n.AnonymousObservable,a=s.concat,l=s.defer,f=s.empty,h=n.Disposable.empty,p=n.CompositeDisposable,d=n.SerialDisposable,b=n.SingleAssignmentDisposable,v=n.internals.Enumerator,m=n.internals.Enumerable,y=m.forEach,w=n.Scheduler.immediate,g=n.Scheduler.currentThread,x=Array.prototype.slice,E=n.AsyncSubject,C=n.Observer,D=n.internals.inherits,S=n.internals.addProperties,N=n.helpers.noop,A=n.helpers.isPromise,_=s.fromPromise,O="object"==typeof Symbol&&Symbol.iterator||"_es6shim_iterator_";t.Set&&"function"==typeof(new t.Set)["@@iterator"]&&(O="@@iterator"),u.letBind=u.let=function(t){return t(this)},s["if"]=s.ifThen=function(t,e,n){return l(function(){return n||(n=f()),A(e)&&(e=_(e)),A(n)&&(n=_(n)),"function"==typeof n.now&&(n=f(n)),t()?e:n})},s["for"]=s.forIn=function(t,e){return y(t,e).concat()};var j=s["while"]=s.whileDo=function(t,e){return A(e)&&(e=_(e)),i(t,e).concat()};u.doWhile=function(t){return a([this,j(t,this)])},s["case"]=s.switchCase=function(t,e,n){return l(function(){n||(n=f()),"function"==typeof n.now&&(n=f(n));var r=e[t()];return A(r)&&(r=_(r)),r||n})},u.expand=function(t,e){e||(e=w);var n=this;return new c(function(o){var i=[],s=new d,u=new p(s),c=0,a=!1,l=function(){var n=!1;i.length>0&&(n=!a,a=!0),n&&s.setDisposable(e.scheduleRecursive(function(e){var n;if(!(i.length>0))return a=!1,r;n=i.shift();var s=new b;u.add(s),s.setDisposable(n.subscribe(function(e){o.onNext(e);var n=null;try{n=t(e)}catch(r){o.onError(r)}i.push(n),c++,l()},o.onError.bind(o),function(){u.remove(s),c--,0===c&&o.onCompleted()})),e()}))};return i.push(n),c++,l(),u})},s.forkJoin=function(){var t=o(arguments,0);return new c(function(e){var n=t.length;if(0===n)return e.onCompleted(),h;for(var o=new p,i=!1,s=Array(n),u=Array(n),c=Array(n),a=0;n>a;a++)(function(a){var l=t[a];A(l)&&(l=_(l)),o.add(l.subscribe(function(t){i||(s[a]=!0,c[a]=t)},function(t){i=!0,e.onError(t),o.dispose()},function(){if(!i){if(!s[a])return e.onCompleted(),r;u[a]=!0;for(var t=0;n>t;t++)if(!u[t])return;i=!0,e.onNext(c),e.onCompleted()}}))})(a);return o})},u.forkJoin=function(t,e){var n=this;return new c(function(o){var i,s,u=!1,c=!1,a=!1,l=!1,f=new b,h=new b;return A(t)&&(t=_(t)),f.setDisposable(n.subscribe(function(t){a=!0,i=t},function(t){h.dispose(),o.onError(t)},function(){if(u=!0,c)if(a)if(l){var t;try{t=e(i,s)}catch(n){return o.onError(n),r}o.onNext(t),o.onCompleted()}else o.onCompleted();else o.onCompleted()})),h.setDisposable(t.subscribe(function(t){l=!0,s=t},function(t){f.dispose(),o.onError(t)},function(){if(c=!0,u)if(a)if(l){var t;try{t=e(i,s)}catch(n){return o.onError(n),r}o.onNext(t),o.onCompleted()}else o.onCompleted();else o.onCompleted()})),new p(f,h)})},u.manySelect=function(t,e){e||(e=w);var n=this;return l(function(){var r;return n.select(function(t){var e=new R(t);return r&&r.onNext(t),r=e,e}).doAction(N,function(t){r&&r.onError(t)},function(){r&&r.onCompleted()}).observeOn(e).select(function(e,n,r){return t(e,n,r)})})};var R=function(t){function e(t){var e=this,n=new p;return n.add(g.schedule(function(){t.onNext(e.head),n.add(e.tail.mergeObservable().subscribe(t))})),n}function n(n){t.call(this,e),this.head=n,this.tail=new E}return D(n,t),S(n.prototype,C,{onCompleted:function(){this.onNext(s.empty())},onError:function(t){this.onNext(s.throwException(t))},onNext:function(t){this.tail.onNext(t),this.tail.onCompleted()}}),n}(s);return n}); -------------------------------------------------------------------------------- /demos/assets/rx/rx.joinpatterns.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | ;(function (factory) { 4 | var objectTypes = { 5 | 'boolean': false, 6 | 'function': true, 7 | 'object': true, 8 | 'number': false, 9 | 'string': false, 10 | 'undefined': false 11 | }; 12 | 13 | var root = (objectTypes[typeof window] && window) || this, 14 | freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports, 15 | freeModule = objectTypes[typeof module] && module && !module.nodeType && module, 16 | moduleExports = freeModule && freeModule.exports === freeExports && freeExports, 17 | freeGlobal = objectTypes[typeof global] && global; 18 | 19 | if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { 20 | root = freeGlobal; 21 | } 22 | 23 | // Because of build optimizers 24 | if (typeof define === 'function' && define.amd) { 25 | define(['rx', 'exports'], function (Rx, exports) { 26 | root.Rx = factory(root, exports, Rx); 27 | return root.Rx; 28 | }); 29 | } else if (typeof module === 'object' && module && module.exports === freeExports) { 30 | module.exports = factory(root, module.exports, require('./rx')); 31 | } else { 32 | root.Rx = factory(root, {}, root.Rx); 33 | } 34 | }.call(this, function (root, exp, Rx, undefined) { 35 | 36 | // Aliases 37 | var Observable = Rx.Observable, 38 | observableProto = Observable.prototype, 39 | AnonymousObservable = Rx.AnonymousObservable, 40 | observableThrow = Observable.throwException, 41 | observerCreate = Rx.Observer.create, 42 | SingleAssignmentDisposable = Rx.SingleAssignmentDisposable, 43 | CompositeDisposable = Rx.CompositeDisposable, 44 | AbstractObserver = Rx.internals.AbstractObserver, 45 | noop = Rx.helpers.noop, 46 | defaultComparer = Rx.internals.isEqual, 47 | inherits = Rx.internals.inherits, 48 | slice = Array.prototype.slice; 49 | 50 | // Utilities 51 | function argsOrArray(args, idx) { 52 | return args.length === 1 && Array.isArray(args[idx]) ? 53 | args[idx] : 54 | slice.call(args); 55 | } 56 | 57 | /** @private */ 58 | var Map = (function () { 59 | 60 | /** 61 | * @constructor 62 | * @private 63 | */ 64 | function Map() { 65 | this.keys = []; 66 | this.values = []; 67 | } 68 | 69 | /** 70 | * @private 71 | * @memberOf Map# 72 | */ 73 | Map.prototype['delete'] = function (key) { 74 | var i = this.keys.indexOf(key); 75 | if (i !== -1) { 76 | this.keys.splice(i, 1); 77 | this.values.splice(i, 1); 78 | } 79 | return i !== -1; 80 | }; 81 | 82 | /** 83 | * @private 84 | * @memberOf Map# 85 | */ 86 | Map.prototype.get = function (key, fallback) { 87 | var i = this.keys.indexOf(key); 88 | return i !== -1 ? this.values[i] : fallback; 89 | }; 90 | 91 | /** 92 | * @private 93 | * @memberOf Map# 94 | */ 95 | Map.prototype.set = function (key, value) { 96 | var i = this.keys.indexOf(key); 97 | if (i !== -1) { 98 | this.values[i] = value; 99 | } 100 | this.values[this.keys.push(key) - 1] = value; 101 | }; 102 | 103 | /** 104 | * @private 105 | * @memberOf Map# 106 | */ 107 | Map.prototype.size = function () { return this.keys.length; }; 108 | 109 | /** 110 | * @private 111 | * @memberOf Map# 112 | */ 113 | Map.prototype.has = function (key) { 114 | return this.keys.indexOf(key) !== -1; 115 | }; 116 | 117 | /** 118 | * @private 119 | * @memberOf Map# 120 | */ 121 | Map.prototype.getKeys = function () { return this.keys.slice(0); }; 122 | 123 | /** 124 | * @private 125 | * @memberOf Map# 126 | */ 127 | Map.prototype.getValues = function () { return this.values.slice(0); }; 128 | 129 | return Map; 130 | }()); 131 | 132 | /** 133 | * @constructor 134 | * Represents a join pattern over observable sequences. 135 | */ 136 | function Pattern(patterns) { 137 | this.patterns = patterns; 138 | } 139 | 140 | /** 141 | * Creates a pattern that matches the current plan matches and when the specified observable sequences has an available value. 142 | * 143 | * @param other Observable sequence to match in addition to the current pattern. 144 | * @return Pattern object that matches when all observable sequences in the pattern have an available value. 145 | */ 146 | Pattern.prototype.and = function (other) { 147 | var patterns = this.patterns.slice(0); 148 | patterns.push(other); 149 | return new Pattern(patterns); 150 | }; 151 | 152 | /** 153 | * Matches when all observable sequences in the pattern (specified using a chain of and operators) have an available value and projects the values. 154 | * 155 | * @param selector Selector that will be invoked with available values from the source sequences, in the same order of the sequences in the pattern. 156 | * @return Plan that produces the projected values, to be fed (with other plans) to the when operator. 157 | */ 158 | Pattern.prototype.then = function (selector) { 159 | return new Plan(this, selector); 160 | }; 161 | 162 | function Plan(expression, selector) { 163 | this.expression = expression; 164 | this.selector = selector; 165 | } 166 | 167 | Plan.prototype.activate = function (externalSubscriptions, observer, deactivate) { 168 | var self = this; 169 | var joinObservers = []; 170 | for (var i = 0, len = this.expression.patterns.length; i < len; i++) { 171 | joinObservers.push(planCreateObserver(externalSubscriptions, this.expression.patterns[i], observer.onError.bind(observer))); 172 | } 173 | var activePlan = new ActivePlan(joinObservers, function () { 174 | var result; 175 | try { 176 | result = self.selector.apply(self, arguments); 177 | } catch (exception) { 178 | observer.onError(exception); 179 | return; 180 | } 181 | observer.onNext(result); 182 | }, function () { 183 | for (var j = 0, jlen = joinObservers.length; j < jlen; j++) { 184 | joinObservers[j].removeActivePlan(activePlan); 185 | } 186 | deactivate(activePlan); 187 | }); 188 | for (i = 0, len = joinObservers.length; i < len; i++) { 189 | joinObservers[i].addActivePlan(activePlan); 190 | } 191 | return activePlan; 192 | }; 193 | 194 | function planCreateObserver(externalSubscriptions, observable, onError) { 195 | var entry = externalSubscriptions.get(observable); 196 | if (!entry) { 197 | var observer = new JoinObserver(observable, onError); 198 | externalSubscriptions.set(observable, observer); 199 | return observer; 200 | } 201 | return entry; 202 | } 203 | 204 | // Active Plan 205 | function ActivePlan(joinObserverArray, onNext, onCompleted) { 206 | var i, joinObserver; 207 | this.joinObserverArray = joinObserverArray; 208 | this.onNext = onNext; 209 | this.onCompleted = onCompleted; 210 | this.joinObservers = new Map(); 211 | for (i = 0; i < this.joinObserverArray.length; i++) { 212 | joinObserver = this.joinObserverArray[i]; 213 | this.joinObservers.set(joinObserver, joinObserver); 214 | } 215 | } 216 | 217 | ActivePlan.prototype.dequeue = function () { 218 | var values = this.joinObservers.getValues(); 219 | for (var i = 0, len = values.length; i < len; i++) { 220 | values[i].queue.shift(); 221 | } 222 | }; 223 | ActivePlan.prototype.match = function () { 224 | var firstValues, i, len, isCompleted, values, hasValues = true; 225 | for (i = 0, len = this.joinObserverArray.length; i < len; i++) { 226 | if (this.joinObserverArray[i].queue.length === 0) { 227 | hasValues = false; 228 | break; 229 | } 230 | } 231 | if (hasValues) { 232 | firstValues = []; 233 | isCompleted = false; 234 | for (i = 0, len = this.joinObserverArray.length; i < len; i++) { 235 | firstValues.push(this.joinObserverArray[i].queue[0]); 236 | if (this.joinObserverArray[i].queue[0].kind === 'C') { 237 | isCompleted = true; 238 | } 239 | } 240 | if (isCompleted) { 241 | this.onCompleted(); 242 | } else { 243 | this.dequeue(); 244 | values = []; 245 | for (i = 0; i < firstValues.length; i++) { 246 | values.push(firstValues[i].value); 247 | } 248 | this.onNext.apply(this, values); 249 | } 250 | } 251 | }; 252 | 253 | /** @private */ 254 | var JoinObserver = (function (_super) { 255 | 256 | inherits(JoinObserver, _super); 257 | 258 | /** 259 | * @constructor 260 | * @private 261 | */ 262 | function JoinObserver(source, onError) { 263 | _super.call(this); 264 | this.source = source; 265 | this.onError = onError; 266 | this.queue = []; 267 | this.activePlans = []; 268 | this.subscription = new SingleAssignmentDisposable(); 269 | this.isDisposed = false; 270 | } 271 | 272 | var JoinObserverPrototype = JoinObserver.prototype; 273 | 274 | /** 275 | * @memberOf JoinObserver# 276 | * @private 277 | */ 278 | JoinObserverPrototype.next = function (notification) { 279 | if (!this.isDisposed) { 280 | if (notification.kind === 'E') { 281 | this.onError(notification.exception); 282 | return; 283 | } 284 | this.queue.push(notification); 285 | var activePlans = this.activePlans.slice(0); 286 | for (var i = 0, len = activePlans.length; i < len; i++) { 287 | activePlans[i].match(); 288 | } 289 | } 290 | }; 291 | 292 | /** 293 | * @memberOf JoinObserver# 294 | * @private 295 | */ 296 | JoinObserverPrototype.error = noop; 297 | 298 | /** 299 | * @memberOf JoinObserver# 300 | * @private 301 | */ 302 | JoinObserverPrototype.completed = noop; 303 | 304 | /** 305 | * @memberOf JoinObserver# 306 | * @private 307 | */ 308 | JoinObserverPrototype.addActivePlan = function (activePlan) { 309 | this.activePlans.push(activePlan); 310 | }; 311 | 312 | /** 313 | * @memberOf JoinObserver# 314 | * @private 315 | */ 316 | JoinObserverPrototype.subscribe = function () { 317 | this.subscription.setDisposable(this.source.materialize().subscribe(this)); 318 | }; 319 | 320 | /** 321 | * @memberOf JoinObserver# 322 | * @private 323 | */ 324 | JoinObserverPrototype.removeActivePlan = function (activePlan) { 325 | var idx = this.activePlans.indexOf(activePlan); 326 | this.activePlans.splice(idx, 1); 327 | if (this.activePlans.length === 0) { 328 | this.dispose(); 329 | } 330 | }; 331 | 332 | /** 333 | * @memberOf JoinObserver# 334 | * @private 335 | */ 336 | JoinObserverPrototype.dispose = function () { 337 | _super.prototype.dispose.call(this); 338 | if (!this.isDisposed) { 339 | this.isDisposed = true; 340 | this.subscription.dispose(); 341 | } 342 | }; 343 | 344 | return JoinObserver; 345 | } (AbstractObserver)); 346 | 347 | /** 348 | * Creates a pattern that matches when both observable sequences have an available value. 349 | * 350 | * @param right Observable sequence to match with the current sequence. 351 | * @return {Pattern} Pattern object that matches when both observable sequences have an available value. 352 | */ 353 | observableProto.and = function (right) { 354 | return new Pattern([this, right]); 355 | }; 356 | 357 | /** 358 | * Matches when the observable sequence has an available value and projects the value. 359 | * 360 | * @param selector Selector that will be invoked for values in the source sequence. 361 | * @returns {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator. 362 | */ 363 | observableProto.then = function (selector) { 364 | return new Pattern([this]).then(selector); 365 | }; 366 | 367 | /** 368 | * Joins together the results from several patterns. 369 | * 370 | * @param plans A series of plans (specified as an Array of as a series of arguments) created by use of the Then operator on patterns. 371 | * @returns {Observable} Observable sequence with the results form matching several patterns. 372 | */ 373 | Observable.when = function () { 374 | var plans = argsOrArray(arguments, 0); 375 | return new AnonymousObservable(function (observer) { 376 | var activePlans = [], 377 | externalSubscriptions = new Map(), 378 | group, 379 | i, len, 380 | joinObserver, 381 | joinValues, 382 | outObserver; 383 | outObserver = observerCreate(observer.onNext.bind(observer), function (exception) { 384 | var values = externalSubscriptions.getValues(); 385 | for (var j = 0, jlen = values.length; j < jlen; j++) { 386 | values[j].onError(exception); 387 | } 388 | observer.onError(exception); 389 | }, observer.onCompleted.bind(observer)); 390 | try { 391 | for (i = 0, len = plans.length; i < len; i++) { 392 | activePlans.push(plans[i].activate(externalSubscriptions, outObserver, function (activePlan) { 393 | var idx = activePlans.indexOf(activePlan); 394 | activePlans.splice(idx, 1); 395 | if (activePlans.length === 0) { 396 | outObserver.onCompleted(); 397 | } 398 | })); 399 | } 400 | } catch (e) { 401 | observableThrow(e).subscribe(observer); 402 | } 403 | group = new CompositeDisposable(); 404 | joinValues = externalSubscriptions.getValues(); 405 | for (i = 0, len = joinValues.length; i < len; i++) { 406 | joinObserver = joinValues[i]; 407 | joinObserver.subscribe(); 408 | group.add(joinObserver); 409 | } 410 | return group; 411 | }); 412 | }; 413 | 414 | return Rx; 415 | })); -------------------------------------------------------------------------------- /demos/assets/rx/rx.joinpatterns.min.js: -------------------------------------------------------------------------------- 1 | (function(t){var e={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},n=e[typeof window]&&window||this,r=e[typeof exports]&&exports&&!exports.nodeType&&exports,o=e[typeof module]&&module&&!module.nodeType&&module,i=(o&&o.exports===r&&r,e[typeof global]&&global);!i||i.global!==i&&i.window!==i||(n=i),"function"==typeof define&&define.amd?define(["rx","exports"],function(e,r){return n.Rx=t(n,r,e),n.Rx}):"object"==typeof module&&module&&module.exports===r?module.exports=t(n,module.exports,require("./rx")):n.Rx=t(n,{},n.Rx)}).call(this,function(t,e,n){function r(t,e){return 1===t.length&&Array.isArray(t[e])?t[e]:y.call(t)}function o(t){this.patterns=t}function i(t,e){this.expression=t,this.selector=e}function s(t,e,n){var r=t.get(e);if(!r){var o=new g(e,n);return t.set(e,o),o}return r}function u(t,e,n){var r,o;for(this.joinObserverArray=t,this.onNext=e,this.onCompleted=n,this.joinObservers=new w,r=0;this.joinObserverArray.length>r;r++)o=this.joinObserverArray[r],this.joinObservers.set(o,o)}var c=n.Observable,a=c.prototype,l=n.AnonymousObservable,h=c.throwException,f=n.Observer.create,p=n.SingleAssignmentDisposable,d=n.CompositeDisposable,b=n.internals.AbstractObserver,v=n.helpers.noop,m=(n.internals.isEqual,n.internals.inherits),y=Array.prototype.slice,w=function(){function t(){this.keys=[],this.values=[]}return t.prototype["delete"]=function(t){var e=this.keys.indexOf(t);return-1!==e&&(this.keys.splice(e,1),this.values.splice(e,1)),-1!==e},t.prototype.get=function(t,e){var n=this.keys.indexOf(t);return-1!==n?this.values[n]:e},t.prototype.set=function(t,e){var n=this.keys.indexOf(t);-1!==n&&(this.values[n]=e),this.values[this.keys.push(t)-1]=e},t.prototype.size=function(){return this.keys.length},t.prototype.has=function(t){return-1!==this.keys.indexOf(t)},t.prototype.getKeys=function(){return this.keys.slice(0)},t.prototype.getValues=function(){return this.values.slice(0)},t}();o.prototype.and=function(t){var e=this.patterns.slice(0);return e.push(t),new o(e)},o.prototype.then=function(t){return new i(this,t)},i.prototype.activate=function(t,e,n){for(var r=this,o=[],i=0,c=this.expression.patterns.length;c>i;i++)o.push(s(t,this.expression.patterns[i],e.onError.bind(e)));var a=new u(o,function(){var t;try{t=r.selector.apply(r,arguments)}catch(n){return e.onError(n),undefined}e.onNext(t)},function(){for(var t=0,e=o.length;e>t;t++)o[t].removeActivePlan(a);n(a)});for(i=0,c=o.length;c>i;i++)o[i].addActivePlan(a);return a},u.prototype.dequeue=function(){for(var t=this.joinObservers.getValues(),e=0,n=t.length;n>e;e++)t[e].queue.shift()},u.prototype.match=function(){var t,e,n,r,o,i=!0;for(e=0,n=this.joinObserverArray.length;n>e;e++)if(0===this.joinObserverArray[e].queue.length){i=!1;break}if(i){for(t=[],r=!1,e=0,n=this.joinObserverArray.length;n>e;e++)t.push(this.joinObserverArray[e].queue[0]),"C"===this.joinObserverArray[e].queue[0].kind&&(r=!0);if(r)this.onCompleted();else{for(this.dequeue(),o=[],e=0;t.length>e;e++)o.push(t[e].value);this.onNext.apply(this,o)}}};var g=function(t){function e(e,n){t.call(this),this.source=e,this.onError=n,this.queue=[],this.activePlans=[],this.subscription=new p,this.isDisposed=!1}m(e,t);var n=e.prototype;return n.next=function(t){if(!this.isDisposed){if("E"===t.kind)return this.onError(t.exception),undefined;this.queue.push(t);for(var e=this.activePlans.slice(0),n=0,r=e.length;r>n;n++)e[n].match()}},n.error=v,n.completed=v,n.addActivePlan=function(t){this.activePlans.push(t)},n.subscribe=function(){this.subscription.setDisposable(this.source.materialize().subscribe(this))},n.removeActivePlan=function(t){var e=this.activePlans.indexOf(t);this.activePlans.splice(e,1),0===this.activePlans.length&&this.dispose()},n.dispose=function(){t.prototype.dispose.call(this),this.isDisposed||(this.isDisposed=!0,this.subscription.dispose())},e}(b);return a.and=function(t){return new o([this,t])},a.then=function(t){return new o([this]).then(t)},c.when=function(){var t=r(arguments,0);return new l(function(e){var n,r,o,i,s,u,c=[],a=new w;u=f(e.onNext.bind(e),function(t){for(var n=a.getValues(),r=0,o=n.length;o>r;r++)n[r].onError(t);e.onError(t)},e.onCompleted.bind(e));try{for(r=0,o=t.length;o>r;r++)c.push(t[r].activate(a,u,function(t){var e=c.indexOf(t);c.splice(e,1),0===c.length&&u.onCompleted()}))}catch(l){h(l).subscribe(e)}for(n=new d,s=a.getValues(),r=0,o=s.length;o>r;r++)i=s[r],i.subscribe(),n.add(i);return n})},n}); -------------------------------------------------------------------------------- /demos/assets/rx/rx.node.js: -------------------------------------------------------------------------------- 1 | var Rx = require('./rx'); 2 | require('./rx.aggregates'); 3 | require('./rx.backpressure'); 4 | require('./rx.async'); 5 | require('./rx.binding'); 6 | require('./rx.coincidence'); 7 | require('./rx.experimental'); 8 | require('./rx.joinpatterns'); 9 | require('./rx.time'); 10 | require('./rx.virtualtime'); 11 | require('./rx.testing'); 12 | 13 | // Add specific Node functions 14 | var EventEmitter = require('events').EventEmitter, 15 | Observable = Rx.Observable; 16 | 17 | Rx.Node = { 18 | /** 19 | * @deprecated Use Rx.Observable.fromCallback from rx.async.js instead. 20 | * 21 | * Converts a callback function to an observable sequence. 22 | * 23 | * @param {Function} func Function to convert to an asynchronous function. 24 | * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout. 25 | * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined. 26 | * @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next. 27 | * @returns {Function} Asynchronous function. 28 | */ 29 | fromCallback: function (func, scheduler, context, selector) { 30 | return Observable.fromCallback(func, scheduler, context, selector); 31 | }, 32 | 33 | /** 34 | * @deprecated Use Rx.Observable.fromNodeCallback from rx.async.js instead. 35 | * 36 | * Converts a Node.js callback style function to an observable sequence. This must be in function (err, ...) format. 37 | * 38 | * @param {Function} func The function to call 39 | * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout. 40 | * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined. 41 | * @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next. 42 | * @returns {Function} An async function which when applied, returns an observable sequence with the callback arguments as an array. 43 | */ 44 | fromNodeCallback: function (func, scheduler, context, selector) { 45 | return Observable.fromNodeCallback(func, scheduler, context, selector); 46 | }, 47 | 48 | /** 49 | * @deprecated Use Rx.Observable.fromNodeCallback from rx.async.js instead. 50 | * 51 | * Handles an event from the given EventEmitter as an observable sequence. 52 | * 53 | * @param {EventEmitter} eventEmitter The EventEmitter to subscribe to the given event. 54 | * @param {String} eventName The event name to subscribe 55 | * @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next. 56 | * @returns {Observable} An observable sequence generated from the named event from the given EventEmitter. The data will be returned as an array of arguments to the handler. 57 | */ 58 | fromEvent: function (eventEmitter, eventName, selector) { 59 | return Observable.fromEvent(eventEmitter, eventName, selector); 60 | }, 61 | 62 | /** 63 | * Converts the given observable sequence to an event emitter with the given event name. 64 | * The errors are handled on the 'error' event and completion on the 'end' event. 65 | * @param {Observable} observable The observable sequence to convert to an EventEmitter. 66 | * @param {String} eventName The event name to emit onNext calls. 67 | * @returns {EventEmitter} An EventEmitter which emits the given eventName for each onNext call in addition to 'error' and 'end' events. 68 | * You must call publish in order to invoke the subscription on the Observable sequuence. 69 | */ 70 | toEventEmitter: function (observable, eventName) { 71 | var e = new EventEmitter(); 72 | 73 | // Used to publish the events from the observable 74 | e.publish = function () { 75 | e.subscription = observable.subscribe( 76 | function (x) { 77 | e.emit(eventName, x); 78 | }, 79 | function (err) { 80 | e.emit('error', err); 81 | }, 82 | function () { 83 | e.emit('end'); 84 | }); 85 | }; 86 | 87 | return e; 88 | }, 89 | 90 | /** 91 | * Converts a flowing stream to an Observable sequence. 92 | * @param {Stream} stream A stream to convert to a observable sequence. 93 | * @returns {Observable} An observable sequence which fires on each 'data' event as well as handling 'error' and 'end' events. 94 | */ 95 | fromStream: function (stream) { 96 | return Observable.create(function (observer) { 97 | function dataHandler (data) { 98 | observer.onNext(data); 99 | } 100 | 101 | function errorHandler (err) { 102 | observer.onError(err); 103 | } 104 | 105 | function endHandler () { 106 | observer.onCompleted(); 107 | } 108 | 109 | stream.addListener('data', dataHandler); 110 | stream.addListener('error', errorHandler); 111 | stream.addListener('end', endHandler); 112 | 113 | return function () { 114 | stream.removeListener('data', dataHandler); 115 | stream.removeListener('error', errorHandler); 116 | stream.removeListener('end', endHandler); 117 | }; 118 | }).publish().refCount(); 119 | }, 120 | 121 | /** 122 | * Writes an observable sequence to a stream 123 | * @param {Observable} observable Observable sequence to write to a stream. 124 | * @param {Stream} stream The stream to write to. 125 | * @param {String} [encoding] The encoding of the item to write. 126 | * @returns {Disposable} The subscription handle. 127 | */ 128 | writeToStream: function (observable, stream, encoding) { 129 | return observable.subscribe( 130 | function (x) { 131 | stream.write(String(x), encoding); 132 | }, 133 | function (err) { 134 | stream.emit('error', err); 135 | }, function () { 136 | // Hack check because STDIO is not closable 137 | !stream._isStdio && stream.end(); 138 | }); 139 | } 140 | }; 141 | 142 | module.exports = Rx; -------------------------------------------------------------------------------- /demos/assets/rx/rx.testing.min.js: -------------------------------------------------------------------------------- 1 | (function(t){var e={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},n=e[typeof window]&&window||this,r=e[typeof exports]&&exports&&!exports.nodeType&&exports,o=e[typeof module]&&module&&!module.nodeType&&module,i=(o&&o.exports===r&&r,e[typeof global]&&global);!i||i.global!==i&&i.window!==i||(n=i),"function"==typeof define&&define.amd?define(["rx.virtualtime","exports"],function(e,r){return n.Rx=t(n,r,e),n.Rx}):"object"==typeof module&&module&&module.exports===r?module.exports=t(n,module.exports,require("./rx")):n.Rx=t(n,{},n.Rx)}).call(this,function(t,e,n){function r(t,e){return 1===t.length&&Array.isArray(t[e])?t[e]:d.call(t)}function o(t){this.predicate=t}function i(t){this.predicate=t}var s=n.Observer,u=n.Observable,c=n.Notification,a=n.VirtualTimeScheduler,l=n.Disposable,h=l.empty,f=l.create,p=n.CompositeDisposable,d=(n.SingleAssignmentDisposable,Array.prototype.slice),b=n.internals.inherits,v=n.internals.isEqual;o.prototype.equals=function(t){return t===this?!0:null==t?!1:"N"!==t.kind?!1:this.predicate(t.value)},i.prototype.equals=function(t){return t===this?!0:null==t?!1:"E"!==t.kind?!1:this.predicate(t.exception)};var m=n.ReactiveTest={created:100,subscribed:200,disposed:1e3,onNext:function(t,e){return"function"==typeof e?new y(t,new o(e)):new y(t,c.createOnNext(e))},onError:function(t,e){return"function"==typeof e?new y(t,new i(e)):new y(t,c.createOnError(e))},onCompleted:function(t){return new y(t,c.createOnCompleted())},subscribe:function(t,e){return new g(t,e)}},y=n.Recorded=function(t,e,n){this.time=t,this.value=e,this.comparer=n||v};y.prototype.equals=function(t){return this.time===t.time&&this.comparer(this.value,t.value)},y.prototype.toString=function(){return""+this.value+"@"+this.time};var g=n.Subscription=function(t,e){this.subscribe=t,this.unsubscribe=e||Number.MAX_VALUE};g.prototype.equals=function(t){return this.subscribe===t.subscribe&&this.unsubscribe===t.unsubscribe},g.prototype.toString=function(){return"("+this.subscribe+", "+this.unsubscribe===Number.MAX_VALUE?"Infinite":this.unsubscribe+")"};var w=n.MockDisposable=function(t){this.scheduler=t,this.disposes=[],this.disposes.push(this.scheduler.clock)};w.prototype.dispose=function(){this.disposes.push(this.scheduler.clock)};var x=function(t){function e(e){t.call(this),this.scheduler=e,this.messages=[]}b(e,t);var n=e.prototype;return n.onNext=function(t){this.messages.push(new y(this.scheduler.clock,c.createOnNext(t)))},n.onError=function(t){this.messages.push(new y(this.scheduler.clock,c.createOnError(t)))},n.onCompleted=function(){this.messages.push(new y(this.scheduler.clock,c.createOnCompleted()))},e}(s),E=function(t){function e(t){var e=this;this.observers.push(t),this.subscriptions.push(new g(this.scheduler.clock));var n=this.subscriptions.length-1;return f(function(){var r=e.observers.indexOf(t);e.observers.splice(r,1),e.subscriptions[n]=new g(e.subscriptions[n].subscribe,e.scheduler.clock)})}function n(n,r){t.call(this,e);var o,i,s=this;this.scheduler=n,this.messages=r,this.subscriptions=[],this.observers=[];for(var u=0,c=this.messages.length;c>u;u++)o=this.messages[u],i=o.value,function(t){n.scheduleAbsoluteWithState(null,o.time,function(){for(var e=s.observers.slice(0),n=0,r=e.length;r>n;n++)t.accept(e[n]);return h})}(i)}return b(n,t),n}(u),C=function(t){function e(t){var e,n,r=this;this.subscriptions.push(new g(this.scheduler.clock));for(var o=this.subscriptions.length-1,i=new p,s=0,u=this.messages.length;u>s;s++)e=this.messages[s],n=e.value,function(n){i.add(r.scheduler.scheduleRelativeWithState(null,e.time,function(){return n.accept(t),h}))}(n);return f(function(){r.subscriptions[o]=new g(r.subscriptions[o].subscribe,r.scheduler.clock),i.dispose()})}function n(n,r){t.call(this,e),this.scheduler=n,this.messages=r,this.subscriptions=[]}return b(n,t),n}(u);return n.TestScheduler=function(t){function e(t,e){return t>e?1:e>t?-1:0}function n(){t.call(this,0,e)}return b(n,t),n.prototype.scheduleAbsoluteWithState=function(e,n,r){return this.clock>=n&&(n=this.clock+1),t.prototype.scheduleAbsoluteWithState.call(this,e,n,r)},n.prototype.add=function(t,e){return t+e},n.prototype.toDateTimeOffset=function(t){return new Date(t).getTime()},n.prototype.toRelative=function(t){return t},n.prototype.startWithTiming=function(t,e,n,r){var o,i,s=this.createObserver();return this.scheduleAbsoluteWithState(null,e,function(){return o=t(),h}),this.scheduleAbsoluteWithState(null,n,function(){return i=o.subscribe(s),h}),this.scheduleAbsoluteWithState(null,r,function(){return i.dispose(),h}),this.start(),s},n.prototype.startWithDispose=function(t,e){return this.startWithTiming(t,m.created,m.subscribed,e)},n.prototype.startWithCreate=function(t){return this.startWithTiming(t,m.created,m.subscribed,m.disposed)},n.prototype.createHotObservable=function(){var t=r(arguments,0);return new E(this,t)},n.prototype.createColdObservable=function(){var t=r(arguments,0);return new C(this,t)},n.prototype.createObserver=function(){return new x(this)},n}(a),n}); -------------------------------------------------------------------------------- /demos/assets/rx/rx.time.min.js: -------------------------------------------------------------------------------- 1 | (function(t){var e={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},n=e[typeof window]&&window||this,r=e[typeof exports]&&exports&&!exports.nodeType&&exports,o=e[typeof module]&&module&&!module.nodeType&&module,i=(o&&o.exports===r&&r,e[typeof global]&&global);!i||i.global!==i&&i.window!==i||(n=i),"function"==typeof define&&define.amd?define(["rx","exports"],function(e,r){return n.Rx=t(n,r,e),n.Rx}):"object"==typeof module&&module&&module.exports===r?module.exports=t(n,module.exports,require("./rx")):n.Rx=t(n,{},n.Rx)}).call(this,function(t,e,n,r){function o(t,e){return new p(function(n){return e.scheduleWithAbsolute(t,function(){n.onNext(0),n.onCompleted()})})}function i(t,e,n){var r=S(e);return new p(function(e){var o=0,i=t;return n.scheduleRecursiveWithAbsolute(i,function(t){var s;r>0&&(s=n.now(),i+=r,s>=i&&(i=s+r)),e.onNext(o++),t(i)})})}function s(t,e){var n=S(t);return new p(function(t){return e.scheduleWithRelative(n,function(){t.onNext(0),t.onCompleted()})})}function u(t,e,n){return t===e?new p(function(t){return n.schedulePeriodicWithState(0,e,function(e){return t.onNext(e),e+1})}):d(function(){return i(n.now()+t,e,n)})}function c(t,e){var n=this;return new p(function(r){var o,i=!1,s=new x,u=null,c=[],a=!1;return o=n.materialize().timestamp(e).subscribe(function(n){var o,l;"E"===n.value.kind?(c=[],c.push(n),u=n.value.exception,l=!a):(c.push({value:n.value,timestamp:n.timestamp+t}),l=!i,i=!0),l&&(null!==u?r.onError(u):(o=new g,s.setDisposable(o),o.setDisposable(e.scheduleRecursiveWithRelative(t,function(t){var n,o,s,l;if(null===u){a=!0;do s=null,c.length>0&&0>=c[0].timestamp-e.now()&&(s=c.shift().value),null!==s&&s.accept(r);while(null!==s);l=!1,o=0,c.length>0?(l=!0,o=Math.max(0,c[0].timestamp-e.now())):i=!1,n=u,a=!1,null!==n?r.onError(n):l&&t(o)}}))))}),new E(o,s)})}function a(t,e){var n=this;return d(function(){var r=t-e.now();return c.call(n,r,e)})}function l(t,e){return new p(function(n){function r(){s&&(s=!1,n.onNext(i)),o&&n.onCompleted()}var o,i,s;return new E(t.subscribe(function(t){s=!0,i=t},n.onError.bind(n),function(){o=!0}),e.subscribe(r,n.onError.bind(n),r))})}var f=n.Observable,h=f.prototype,p=n.AnonymousObservable,d=f.defer,b=f.empty,v=f.never,m=f.throwException,y=f.fromArray,w=n.Scheduler.timeout,g=n.SingleAssignmentDisposable,x=n.SerialDisposable,E=n.CompositeDisposable,C=n.RefCountDisposable,D=n.Subject,A=n.internals.addRef,S=n.Scheduler.normalize,N=f.interval=function(t,e){return e||(e=w),u(t,t,e)},O=f.timer=function(t,e,n){var c;return n||(n=w),e!==r&&"number"==typeof e?c=e:e!==r&&"object"==typeof e&&(n=e),t instanceof Date&&c===r?o(t.getTime(),n):t instanceof Date&&c!==r?(c=e,i(t.getTime(),c,n)):c===r?s(t,n):u(t,c,n)};return h.delay=function(t,e){return e||(e=w),t instanceof Date?a.call(this,t.getTime(),e):c.call(this,t,e)},h.throttle=function(t,e){return e||(e=w),this.throttleWithSelector(function(){return O(t,e)})},h.windowWithTime=function(t,e,n){var o,i=this;return e===r&&(o=t),n===r&&(n=w),"number"==typeof e?o=e:"object"==typeof e&&(o=t,n=e),new p(function(e){function r(){var t=new g,i=!1,s=!1;f.setDisposable(t),a===c?(i=!0,s=!0):c>a?i=!0:s=!0;var p=i?a:c,d=p-h;h=p,i&&(a+=o),s&&(c+=o),t.setDisposable(n.scheduleWithRelative(d,function(){var t;s&&(t=new D,l.push(t),e.onNext(A(t,u))),i&&(t=l.shift(),t.onCompleted()),r()}))}var s,u,c=o,a=t,l=[],f=new x,h=0;return s=new E(f),u=new C(s),l.push(new D),e.onNext(A(l[0],u)),r(),s.add(i.subscribe(function(t){var e,n;for(e=0;l.length>e;e++)n=l[e],n.onNext(t)},function(t){var n,r;for(n=0;l.length>n;n++)r=l[n],r.onError(t);e.onError(t)},function(){var t,n;for(t=0;l.length>t;t++)n=l[t],n.onCompleted();e.onCompleted()})),u})},h.windowWithTimeOrCount=function(t,e,n){var r=this;return n||(n=w),new p(function(o){var i,s,u,c,a=0,l=new x,f=0;return s=new E(l),u=new C(s),i=function(e){var r=new g;l.setDisposable(r),r.setDisposable(n.scheduleWithRelative(t,function(){var t;e===f&&(a=0,t=++f,c.onCompleted(),c=new D,o.onNext(A(c,u)),i(t))}))},c=new D,o.onNext(A(c,u)),i(0),s.add(r.subscribe(function(t){var n=0,r=!1;c.onNext(t),a++,a===e&&(r=!0,a=0,n=++f,c.onCompleted(),c=new D,o.onNext(A(c,u))),r&&i(n)},function(t){c.onError(t),o.onError(t)},function(){c.onCompleted(),o.onCompleted()})),u})},h.bufferWithTime=function(){return this.windowWithTime.apply(this,arguments).selectMany(function(t){return t.toArray()})},h.bufferWithTimeOrCount=function(t,e,n){return this.windowWithTimeOrCount(t,e,n).selectMany(function(t){return t.toArray()})},h.timeInterval=function(t){var e=this;return t||(t=w),d(function(){var n=t.now();return e.select(function(e){var r=t.now(),o=r-n;return n=r,{value:e,interval:o}})})},h.timestamp=function(t){return t||(t=w),this.select(function(e){return{value:e,timestamp:t.now()}})},h.sample=function(t,e){return e||(e=w),"number"==typeof t?l(this,N(t,e)):l(this,t)},h.timeout=function(t,e,n){var r,o=this;return e||(e=m(Error("Timeout"))),n||(n=w),r=t instanceof Date?function(t,e){n.scheduleWithAbsolute(t,e)}:function(t,e){n.scheduleWithRelative(t,e)},new p(function(n){var i,s=0,u=new g,c=new x,a=!1,l=new x;return c.setDisposable(u),i=function(){var o=s;l.setDisposable(r(t,function(){a=s===o;var t=a;t&&c.setDisposable(e.subscribe(n))}))},i(),u.setDisposable(o.subscribe(function(t){var e=!a;e&&(s++,n.onNext(t),i())},function(t){var e=!a;e&&(s++,n.onError(t))},function(){var t=!a;t&&(s++,n.onCompleted())})),new E(c,l)})},f.generateWithAbsoluteTime=function(t,e,n,o,i,s){return s||(s=w),new p(function(u){var c,a,l=!0,f=!1,h=t;return s.scheduleRecursiveWithAbsolute(s.now(),function(t){f&&u.onNext(c);try{l?l=!1:h=n(h),f=e(h),f&&(c=o(h),a=i(h))}catch(s){return u.onError(s),r}f?t(a):u.onCompleted()})})},f.generateWithRelativeTime=function(t,e,n,o,i,s){return s||(s=w),new p(function(u){var c,a,l=!0,f=!1,h=t;return s.scheduleRecursiveWithRelative(0,function(t){f&&u.onNext(c);try{l?l=!1:h=n(h),f=e(h),f&&(c=o(h),a=i(h))}catch(s){return u.onError(s),r}f?t(a):u.onCompleted()})})},h.delaySubscription=function(t,e){return e||(e=w),this.delayWithSelector(O(t,e),function(){return b()})},h.delayWithSelector=function(t,e){var n,o,i=this;return"function"==typeof t?o=t:(n=t,o=e),new p(function(t){var e=new E,s=!1,u=function(){s&&0===e.length&&t.onCompleted()},c=new x,a=function(){c.setDisposable(i.subscribe(function(n){var i;try{i=o(n)}catch(s){return t.onError(s),r}var c=new g;e.add(c),c.setDisposable(i.subscribe(function(){t.onNext(n),e.remove(c),u()},t.onError.bind(t),function(){t.onNext(n),e.remove(c),u()}))},t.onError.bind(t),function(){s=!0,c.dispose(),u()}))};return n?c.setDisposable(n.subscribe(function(){a()},t.onError.bind(t),function(){a()})):a(),new E(c,e)})},h.timeoutWithSelector=function(t,e,n){if(1===arguments.length){e=t;var t=v()}n||(n=m(Error("Timeout")));var o=this;return new p(function(i){var s=new x,u=new x,c=new g;s.setDisposable(c);var a=0,l=!1,f=function(t){var e=a,r=function(){return a===e},o=new g;u.setDisposable(o),o.setDisposable(t.subscribe(function(){r()&&s.setDisposable(n.subscribe(i)),o.dispose()},function(t){r()&&i.onError(t)},function(){r()&&s.setDisposable(n.subscribe(i))}))};f(t);var h=function(){var t=!l;return t&&a++,t};return c.setDisposable(o.subscribe(function(t){if(h()){i.onNext(t);var n;try{n=e(t)}catch(o){return i.onError(o),r}f(n)}},function(t){h()&&i.onError(t)},function(){h()&&i.onCompleted()})),new E(s,u)})},h.throttleWithSelector=function(t){var e=this;return new p(function(n){var o,i=!1,s=new x,u=0,c=e.subscribe(function(e){var c;try{c=t(e)}catch(a){return n.onError(a),r}i=!0,o=e,u++;var l=u,f=new g;s.setDisposable(f),f.setDisposable(c.subscribe(function(){i&&u===l&&n.onNext(o),i=!1,f.dispose()},n.onError.bind(n),function(){i&&u===l&&n.onNext(o),i=!1,f.dispose()}))},function(t){s.dispose(),n.onError(t),i=!1,u++},function(){s.dispose(),i&&n.onNext(o),n.onCompleted(),i=!1,u++});return new E(c,s)})},h.skipLastWithTime=function(t,e){e||(e=w);var n=this;return new p(function(r){var o=[];return n.subscribe(function(n){var i=e.now();for(o.push({interval:i,value:n});o.length>0&&i-o[0].interval>=t;)r.onNext(o.shift().value)},r.onError.bind(r),function(){for(var n=e.now();o.length>0&&n-o[0].interval>=t;)r.onNext(o.shift().value);r.onCompleted()})})},h.takeLastWithTime=function(t,e,n){return this.takeLastBufferWithTime(t,e).selectMany(function(t){return y(t,n)})},h.takeLastBufferWithTime=function(t,e){var n=this;return e||(e=w),new p(function(r){var o=[];return n.subscribe(function(n){var r=e.now();for(o.push({interval:r,value:n});o.length>0&&r-o[0].interval>=t;)o.shift()},r.onError.bind(r),function(){for(var n=e.now(),i=[];o.length>0;){var s=o.shift();t>=n-s.interval&&i.push(s.value)}r.onNext(i),r.onCompleted()})})},h.takeWithTime=function(t,e){var n=this;return e||(e=w),new p(function(r){var o=e.scheduleWithRelative(t,function(){r.onCompleted()});return new E(o,n.subscribe(r))})},h.skipWithTime=function(t,e){var n=this;return e||(e=w),new p(function(r){var o=!1,i=e.scheduleWithRelative(t,function(){o=!0}),s=n.subscribe(function(t){o&&r.onNext(t)},r.onError.bind(r),r.onCompleted.bind(r));return new E(i,s)})},h.skipUntilWithTime=function(t,e){e||(e=w);var n=this;return new p(function(r){var o=!1,i=e.scheduleWithAbsolute(t,function(){o=!0}),s=n.subscribe(function(t){o&&r.onNext(t)},r.onError.bind(r),r.onCompleted.bind(r));return new E(i,s)})},h.takeUntilWithTime=function(t,e){e||(e=w);var n=this;return new p(function(r){return new E(e.scheduleWithAbsolute(t,function(){r.onCompleted()}),n.subscribe(r))})},n}); -------------------------------------------------------------------------------- /demos/assets/rx/rx.virtualtime.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. 2 | 3 | ;(function (factory) { 4 | var objectTypes = { 5 | 'boolean': false, 6 | 'function': true, 7 | 'object': true, 8 | 'number': false, 9 | 'string': false, 10 | 'undefined': false 11 | }; 12 | 13 | var root = (objectTypes[typeof window] && window) || this, 14 | freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports, 15 | freeModule = objectTypes[typeof module] && module && !module.nodeType && module, 16 | moduleExports = freeModule && freeModule.exports === freeExports && freeExports, 17 | freeGlobal = objectTypes[typeof global] && global; 18 | 19 | if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { 20 | root = freeGlobal; 21 | } 22 | 23 | // Because of build optimizers 24 | if (typeof define === 'function' && define.amd) { 25 | define(['rx', 'exports'], function (Rx, exports) { 26 | root.Rx = factory(root, exports, Rx); 27 | return root.Rx; 28 | }); 29 | } else if (typeof module === 'object' && module && module.exports === freeExports) { 30 | module.exports = factory(root, module.exports, require('./rx')); 31 | } else { 32 | root.Rx = factory(root, {}, root.Rx); 33 | } 34 | }.call(this, function (root, exp, Rx, undefined) { 35 | 36 | // Aliases 37 | var Scheduler = Rx.Scheduler, 38 | PriorityQueue = Rx.internals.PriorityQueue, 39 | ScheduledItem = Rx.internals.ScheduledItem, 40 | SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive, 41 | disposableEmpty = Rx.Disposable.empty, 42 | inherits = Rx.internals.inherits, 43 | defaultSubComparer = Rx.helpers.defaultSubComparer; 44 | 45 | /** Provides a set of extension methods for virtual time scheduling. */ 46 | Rx.VirtualTimeScheduler = (function (_super) { 47 | 48 | function notImplemented() { 49 | throw new Error('Not implemented'); 50 | } 51 | 52 | function localNow() { 53 | return this.toDateTimeOffset(this.clock); 54 | } 55 | 56 | function scheduleNow(state, action) { 57 | return this.scheduleAbsoluteWithState(state, this.clock, action); 58 | } 59 | 60 | function scheduleRelative(state, dueTime, action) { 61 | return this.scheduleRelativeWithState(state, this.toRelative(dueTime), action); 62 | } 63 | 64 | function scheduleAbsolute(state, dueTime, action) { 65 | return this.scheduleRelativeWithState(state, this.toRelative(dueTime - this.now()), action); 66 | } 67 | 68 | function invokeAction(scheduler, action) { 69 | action(); 70 | return disposableEmpty; 71 | } 72 | 73 | inherits(VirtualTimeScheduler, _super); 74 | 75 | /** 76 | * Creates a new virtual time scheduler with the specified initial clock value and absolute time comparer. 77 | * 78 | * @constructor 79 | * @param {Number} initialClock Initial value for the clock. 80 | * @param {Function} comparer Comparer to determine causality of events based on absolute time. 81 | */ 82 | function VirtualTimeScheduler(initialClock, comparer) { 83 | this.clock = initialClock; 84 | this.comparer = comparer; 85 | this.isEnabled = false; 86 | this.queue = new PriorityQueue(1024); 87 | _super.call(this, localNow, scheduleNow, scheduleRelative, scheduleAbsolute); 88 | } 89 | 90 | var VirtualTimeSchedulerPrototype = VirtualTimeScheduler.prototype; 91 | 92 | /** 93 | * Adds a relative time value to an absolute time value. 94 | * @param {Number} absolute Absolute virtual time value. 95 | * @param {Number} relative Relative virtual time value to add. 96 | * @return {Number} Resulting absolute virtual time sum value. 97 | */ 98 | VirtualTimeSchedulerPrototype.add = notImplemented; 99 | 100 | /** 101 | * Converts an absolute time to a number 102 | * @param {Any} The absolute time. 103 | * @returns {Number} The absolute time in ms 104 | */ 105 | VirtualTimeSchedulerPrototype.toDateTimeOffset = notImplemented; 106 | 107 | /** 108 | * Converts the TimeSpan value to a relative virtual time value. 109 | * @param {Number} timeSpan TimeSpan value to convert. 110 | * @return {Number} Corresponding relative virtual time value. 111 | */ 112 | VirtualTimeSchedulerPrototype.toRelative = notImplemented; 113 | 114 | /** 115 | * Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be emulated using recursive scheduling. 116 | * @param {Mixed} state Initial state passed to the action upon the first iteration. 117 | * @param {Number} period Period for running the work periodically. 118 | * @param {Function} action Action to be executed, potentially updating the state. 119 | * @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort). 120 | */ 121 | VirtualTimeSchedulerPrototype.schedulePeriodicWithState = function (state, period, action) { 122 | var s = new SchedulePeriodicRecursive(this, state, period, action); 123 | return s.start(); 124 | }; 125 | 126 | /** 127 | * Schedules an action to be executed after dueTime. 128 | * @param {Mixed} state State passed to the action to be executed. 129 | * @param {Number} dueTime Relative time after which to execute the action. 130 | * @param {Function} action Action to be executed. 131 | * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). 132 | */ 133 | VirtualTimeSchedulerPrototype.scheduleRelativeWithState = function (state, dueTime, action) { 134 | var runAt = this.add(this.clock, dueTime); 135 | return this.scheduleAbsoluteWithState(state, runAt, action); 136 | }; 137 | 138 | /** 139 | * Schedules an action to be executed at dueTime. 140 | * @param {Number} dueTime Relative time after which to execute the action. 141 | * @param {Function} action Action to be executed. 142 | * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). 143 | */ 144 | VirtualTimeSchedulerPrototype.scheduleRelative = function (dueTime, action) { 145 | return this.scheduleRelativeWithState(action, dueTime, invokeAction); 146 | }; 147 | 148 | /** 149 | * Starts the virtual time scheduler. 150 | */ 151 | VirtualTimeSchedulerPrototype.start = function () { 152 | var next; 153 | if (!this.isEnabled) { 154 | this.isEnabled = true; 155 | do { 156 | next = this.getNext(); 157 | if (next !== null) { 158 | if (this.comparer(next.dueTime, this.clock) > 0) { 159 | this.clock = next.dueTime; 160 | } 161 | next.invoke(); 162 | } else { 163 | this.isEnabled = false; 164 | } 165 | } while (this.isEnabled); 166 | } 167 | }; 168 | 169 | /** 170 | * Stops the virtual time scheduler. 171 | */ 172 | VirtualTimeSchedulerPrototype.stop = function () { 173 | this.isEnabled = false; 174 | }; 175 | 176 | /** 177 | * Advances the scheduler's clock to the specified time, running all work till that point. 178 | * @param {Number} time Absolute time to advance the scheduler's clock to. 179 | */ 180 | VirtualTimeSchedulerPrototype.advanceTo = function (time) { 181 | var next; 182 | var dueToClock = this.comparer(this.clock, time); 183 | if (this.comparer(this.clock, time) > 0) { 184 | throw new Error(argumentOutOfRange); 185 | } 186 | if (dueToClock === 0) { 187 | return; 188 | } 189 | if (!this.isEnabled) { 190 | this.isEnabled = true; 191 | do { 192 | next = this.getNext(); 193 | if (next !== null && this.comparer(next.dueTime, time) <= 0) { 194 | if (this.comparer(next.dueTime, this.clock) > 0) { 195 | this.clock = next.dueTime; 196 | } 197 | next.invoke(); 198 | } else { 199 | this.isEnabled = false; 200 | } 201 | } while (this.isEnabled); 202 | this.clock = time; 203 | } 204 | }; 205 | 206 | /** 207 | * Advances the scheduler's clock by the specified relative time, running all work scheduled for that timespan. 208 | * @param {Number} time Relative time to advance the scheduler's clock by. 209 | */ 210 | VirtualTimeSchedulerPrototype.advanceBy = function (time) { 211 | var dt = this.add(this.clock, time); 212 | var dueToClock = this.comparer(this.clock, dt); 213 | if (dueToClock > 0) { 214 | throw new Error(argumentOutOfRange); 215 | } 216 | if (dueToClock === 0) { 217 | return; 218 | } 219 | this.advanceTo(dt); 220 | }; 221 | 222 | /** 223 | * Advances the scheduler's clock by the specified relative time. 224 | * @param {Number} time Relative time to advance the scheduler's clock by. 225 | */ 226 | VirtualTimeSchedulerPrototype.sleep = function (time) { 227 | var dt = this.add(this.clock, time); 228 | 229 | if (this.comparer(this.clock, dt) >= 0) { 230 | throw new Error(argumentOutOfRange); 231 | } 232 | 233 | this.clock = dt; 234 | }; 235 | 236 | /** 237 | * Gets the next scheduled item to be executed. 238 | * @returns {ScheduledItem} The next scheduled item. 239 | */ 240 | VirtualTimeSchedulerPrototype.getNext = function () { 241 | var next; 242 | while (this.queue.length > 0) { 243 | next = this.queue.peek(); 244 | if (next.isCancelled()) { 245 | this.queue.dequeue(); 246 | } else { 247 | return next; 248 | } 249 | } 250 | return null; 251 | }; 252 | 253 | /** 254 | * Schedules an action to be executed at dueTime. 255 | * @param {Scheduler} scheduler Scheduler to execute the action on. 256 | * @param {Number} dueTime Absolute time at which to execute the action. 257 | * @param {Function} action Action to be executed. 258 | * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). 259 | */ 260 | VirtualTimeSchedulerPrototype.scheduleAbsolute = function (dueTime, action) { 261 | return this.scheduleAbsoluteWithState(action, dueTime, invokeAction); 262 | }; 263 | 264 | /** 265 | * Schedules an action to be executed at dueTime. 266 | * @param {Mixed} state State passed to the action to be executed. 267 | * @param {Number} dueTime Absolute time at which to execute the action. 268 | * @param {Function} action Action to be executed. 269 | * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). 270 | */ 271 | VirtualTimeSchedulerPrototype.scheduleAbsoluteWithState = function (state, dueTime, action) { 272 | var self = this, 273 | run = function (scheduler, state1) { 274 | self.queue.remove(si); 275 | return action(scheduler, state1); 276 | }, 277 | si = new ScheduledItem(self, state, run, dueTime, self.comparer); 278 | self.queue.enqueue(si); 279 | return si.disposable; 280 | }; 281 | 282 | return VirtualTimeScheduler; 283 | }(Scheduler)); 284 | 285 | /** Provides a virtual time scheduler that uses Date for absolute time and number for relative time. */ 286 | Rx.HistoricalScheduler = (function (_super) { 287 | inherits(HistoricalScheduler, _super); 288 | 289 | /** 290 | * Creates a new historical scheduler with the specified initial clock value. 291 | * 292 | * @constructor 293 | * @param {Number} initialClock Initial value for the clock. 294 | * @param {Function} comparer Comparer to determine causality of events based on absolute time. 295 | */ 296 | function HistoricalScheduler(initialClock, comparer) { 297 | var clock = initialClock == null ? 0 : initialClock; 298 | var cmp = comparer || defaultSubComparer; 299 | _super.call(this, clock, cmp); 300 | } 301 | 302 | var HistoricalSchedulerProto = HistoricalScheduler.prototype; 303 | 304 | /** 305 | * Adds a relative time value to an absolute time value. 306 | * @param {Number} absolute Absolute virtual time value. 307 | * @param {Number} relative Relative virtual time value to add. 308 | * @return {Number} Resulting absolute virtual time sum value. 309 | */ 310 | HistoricalSchedulerProto.add = function (absolute, relative) { 311 | return absolute + relative; 312 | }; 313 | 314 | /** 315 | * @private 316 | */ 317 | HistoricalSchedulerProto.toDateTimeOffset = function (absolute) { 318 | return new Date(absolute).getTime(); 319 | }; 320 | 321 | /** 322 | * Converts the TimeSpan value to a relative virtual time value. 323 | * 324 | * @memberOf HistoricalScheduler 325 | * @param {Number} timeSpan TimeSpan value to convert. 326 | * @return {Number} Corresponding relative virtual time value. 327 | */ 328 | HistoricalSchedulerProto.toRelative = function (timeSpan) { 329 | return timeSpan; 330 | }; 331 | 332 | return HistoricalScheduler; 333 | }(Rx.VirtualTimeScheduler)); 334 | return Rx; 335 | })); -------------------------------------------------------------------------------- /demos/assets/rx/rx.virtualtime.min.js: -------------------------------------------------------------------------------- 1 | (function(t){var e={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},n=e[typeof window]&&window||this,r=e[typeof exports]&&exports&&!exports.nodeType&&exports,o=e[typeof module]&&module&&!module.nodeType&&module,i=(o&&o.exports===r&&r,e[typeof global]&&global);!i||i.global!==i&&i.window!==i||(n=i),"function"==typeof define&&define.amd?define(["rx","exports"],function(e,r){return n.Rx=t(n,r,e),n.Rx}):"object"==typeof module&&module&&module.exports===r?module.exports=t(n,module.exports,require("./rx")):n.Rx=t(n,{},n.Rx)}).call(this,function(t,e,n){var r=n.Scheduler,o=n.internals.PriorityQueue,i=n.internals.ScheduledItem,s=n.internals.SchedulePeriodicRecursive,u=n.Disposable.empty,c=n.internals.inherits,a=n.helpers.defaultSubComparer;return n.VirtualTimeScheduler=function(t){function e(){throw Error("Not implemented")}function n(){return this.toDateTimeOffset(this.clock)}function r(t,e){return this.scheduleAbsoluteWithState(t,this.clock,e)}function a(t,e,n){return this.scheduleRelativeWithState(t,this.toRelative(e),n)}function l(t,e,n){return this.scheduleRelativeWithState(t,this.toRelative(e-this.now()),n)}function h(t,e){return e(),u}function f(e,i){this.clock=e,this.comparer=i,this.isEnabled=!1,this.queue=new o(1024),t.call(this,n,r,a,l)}c(f,t);var p=f.prototype;return p.add=e,p.toDateTimeOffset=e,p.toRelative=e,p.schedulePeriodicWithState=function(t,e,n){var r=new s(this,t,e,n);return r.start()},p.scheduleRelativeWithState=function(t,e,n){var r=this.add(this.clock,e);return this.scheduleAbsoluteWithState(t,r,n)},p.scheduleRelative=function(t,e){return this.scheduleRelativeWithState(e,t,h)},p.start=function(){var t;if(!this.isEnabled){this.isEnabled=!0;do t=this.getNext(),null!==t?(this.comparer(t.dueTime,this.clock)>0&&(this.clock=t.dueTime),t.invoke()):this.isEnabled=!1;while(this.isEnabled)}},p.stop=function(){this.isEnabled=!1},p.advanceTo=function(t){var e,n=this.comparer(this.clock,t);if(this.comparer(this.clock,t)>0)throw Error(argumentOutOfRange);if(0!==n&&!this.isEnabled){this.isEnabled=!0;do e=this.getNext(),null!==e&&0>=this.comparer(e.dueTime,t)?(this.comparer(e.dueTime,this.clock)>0&&(this.clock=e.dueTime),e.invoke()):this.isEnabled=!1;while(this.isEnabled);this.clock=t}},p.advanceBy=function(t){var e=this.add(this.clock,t),n=this.comparer(this.clock,e);if(n>0)throw Error(argumentOutOfRange);0!==n&&this.advanceTo(e)},p.sleep=function(t){var e=this.add(this.clock,t);if(this.comparer(this.clock,e)>=0)throw Error(argumentOutOfRange);this.clock=e},p.getNext=function(){for(var t;this.queue.length>0;){if(t=this.queue.peek(),!t.isCancelled())return t;this.queue.dequeue()}return null},p.scheduleAbsolute=function(t,e){return this.scheduleAbsoluteWithState(e,t,h)},p.scheduleAbsoluteWithState=function(t,e,n){var r=this,o=function(t,e){return r.queue.remove(s),n(t,e)},s=new i(r,t,o,e,r.comparer);return r.queue.enqueue(s),s.disposable},f}(r),n.HistoricalScheduler=function(t){function e(e,n){var r=null==e?0:e,o=n||a;t.call(this,r,o)}c(e,t);var n=e.prototype;return n.add=function(t,e){return t+e},n.toDateTimeOffset=function(t){return new Date(t).getTime()},n.toRelative=function(t){return t},e}(n.VirtualTimeScheduler),n}); -------------------------------------------------------------------------------- /demos/dragndrop/dragndrop.css: -------------------------------------------------------------------------------- 1 | #dragTarget { 2 | background-image: url(logo.png); 3 | background-repeat: no-repeat; 4 | background-position: center; 5 | background-size: contain; 6 | height: 200px; 7 | width: 200px; 8 | background-color: #000000; 9 | border: 1px solid #666666; 10 | color: #ffffff; 11 | padding: 10px; 12 | position: absolute; 13 | cursor: move; 14 | } -------------------------------------------------------------------------------- /demos/dragndrop/dragndrop.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Rx for JavaScript Rocks! 10 | 11 | 12 | 13 | 14 |
Drag Me!
15 |
16 | 20 |
21 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /demos/dragndrop/dragndrop.js: -------------------------------------------------------------------------------- 1 | (function (global) { 2 | 3 | function main () { 4 | var dragTarget = document.getElementById('dragTarget'); 5 | 6 | // Get the three major events 7 | var mouseup = Rx.Observable.fromEvent(dragTarget, 'mouseup'); 8 | var mousemove = Rx.Observable.fromEvent(document, 'mousemove'); 9 | var mousedown = Rx.Observable.fromEvent(dragTarget, 'mousedown'); 10 | 11 | var mousedrag = mousedown.flatMap(function (md) { 12 | 13 | // calculate offsets when mouse down 14 | var startX = md.offsetX, startY = md.offsetY; 15 | 16 | // Calculate delta with mousemove until mouseup 17 | return mousemove.map(function (mm) { 18 | mm.preventDefault(); 19 | 20 | return { 21 | left: mm.clientX - startX, 22 | top: mm.clientY - startY 23 | }; 24 | }).takeUntil(mouseup); 25 | }); 26 | 27 | // Update position 28 | subscription = mousedrag.subscribe(function (pos) { 29 | dragTarget.style.top = pos.top + 'px'; 30 | dragTarget.style.left = pos.left + 'px'; 31 | }); 32 | } 33 | 34 | main(); 35 | 36 | }(window)); -------------------------------------------------------------------------------- /demos/dragndrop/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Reactive-Extensions/FutureJS/8cc4e1cf907ce0a61ddf5aa66dd35cf6889ae61c/demos/dragndrop/logo.png -------------------------------------------------------------------------------- /demos/letterrcount/lettercount.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 10px; 3 | font-family: sans-serif; 4 | text-align: center; 5 | background-color: #CCFFCC; 6 | color: #006600;} 7 | } 8 | 9 | .block { 10 | border: 1px solid black; 11 | padding: 10px; 12 | background-color: #ffffff; 13 | } 14 | 15 | li { 16 | padding: 5px; 17 | } 18 | 19 | .contrastBlock { 20 | background-color: #000000; 21 | border: 1px solid #666666; 22 | color: #ffffff; 23 | padding: 10px; 24 | } 25 | 26 | .fixedBlock { 27 | border: 1px solid black; 28 | font-family: Courier New, Andale Mono, monospace 29 | padding: 10px; 30 | background-color: #ffffff; 31 | } 32 | 33 | label { 34 | display: block; 35 | padding: 5px; 36 | } 37 | fieldset { 38 | border-style: solid; 39 | border-width: 3px; 40 | } -------------------------------------------------------------------------------- /demos/letterrcount/lettercount.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Rx for JavaScript Rocks! 10 | 11 | 12 | 13 | 14 |
15 | 19 |
20 |

Text buffer:

21 |

Start Typing!

22 |
23 |
24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /demos/letterrcount/lettercount.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var $toCount = document.querySelector('#toCount'); 3 | var $result = document.querySelector('#result'); 4 | 5 | var source = Rx.Observable.fromEvent($toCount, 'keyup') 6 | .map(function (e) { return 'length: ' + e.target.value.length; }) 7 | .distinctUntilChanged(); 8 | 9 | function setHtml(text) { 10 | console.log(text); 11 | this.innerHTML = text; 12 | } 13 | 14 | source.subscribe(setHtml.bind($result)); 15 | }()); -------------------------------------------------------------------------------- /demos/mouse1/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #ffffff; 3 | padding: 10px; 4 | font-family: sans-serif; 5 | } 6 | 7 | .block { 8 | border: 1px solid black; 9 | padding: 10px; 10 | background-color: #ffffff; 11 | } 12 | 13 | li { 14 | padding: 5px; 15 | } 16 | 17 | .contrastBlock { 18 | background-color: #000000; 19 | border: 1px solid #666666; 20 | color: #ffffff; 21 | padding: 10px; 22 | } 23 | 24 | .fixedBlock { 25 | border: 1px solid black; 26 | font-family: Courier New, Andale Mono, monospace 27 | padding: 10px; 28 | background-color: #ffffff; 29 | } 30 | 31 | label { 32 | display: block; 33 | padding: 5px; 34 | } 35 | fieldset { 36 | border-style: solid; 37 | border-width: 3px; 38 | } -------------------------------------------------------------------------------- /demos/mouse1/mouse1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Rx for JavaScript Rocks! 10 | 11 | 12 | 13 | 14 |
the mouse!
15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /demos/mouse1/mouse1.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | function extractClientX(e) { return e.clientX; } 4 | function extractClientY(e) { return e.clientY; } 5 | function setLeft(x) { this.style.left = x + 'px'; } 6 | function setTop(y) { this.style.top = y + 'px'; } 7 | 8 | var delay = 300; 9 | 10 | var mousemove = Rx.Observable.fromEvent(document, 'mousemove'); 11 | var left = mousemove.map(extractClientX); 12 | var top = mousemove.map(extractClientY); 13 | 14 | // Update the mouse 15 | var themouse = document.querySelector('#themouse'); 16 | left.subscribe(setLeft.bind(themouse)); 17 | top.subscribe(setTop.bind(themouse)); 18 | 19 | }()); -------------------------------------------------------------------------------- /demos/mouse2/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #ffffff; 3 | padding: 10px; 4 | font-family: sans-serif; 5 | } 6 | 7 | .block { 8 | border: 1px solid black; 9 | padding: 10px; 10 | background-color: #ffffff; 11 | } 12 | 13 | li { 14 | padding: 5px; 15 | } 16 | 17 | .contrastBlock { 18 | background-color: #000000; 19 | border: 1px solid #666666; 20 | color: #ffffff; 21 | padding: 10px; 22 | } 23 | 24 | .fixedBlock { 25 | border: 1px solid black; 26 | font-family: Courier New, Andale Mono, monospace 27 | padding: 10px; 28 | background-color: #ffffff; 29 | } 30 | 31 | label { 32 | display: block; 33 | padding: 5px; 34 | } 35 | fieldset { 36 | border-style: solid; 37 | border-width: 3px; 38 | } -------------------------------------------------------------------------------- /demos/mouse2/mouse2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Rx for JavaScript Rocks! 10 | 11 | 12 | 13 | 14 |
the mouse!
15 |
its tail!
16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /demos/mouse2/mouse2.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | function extractClientX(e) { return e.clientX; } 4 | function extractClientY(e) { return e.clientY; } 5 | function setLeft(x) { this.style.left = x + 'px'; } 6 | function setTop(y) { this.style.top = y + 'px'; } 7 | function add(x, y) { return x + y; } 8 | var partialAdd = function (x) { return add.bind(null, x); }; 9 | 10 | var delay = 300; 11 | 12 | var mousemove = Rx.Observable.fromEvent(document, 'mousemove'); 13 | var left = mousemove.map(extractClientX); 14 | var top = mousemove.map(extractClientY); 15 | 16 | // Update the mouse 17 | var themouse = document.querySelector('#themouse'); 18 | left.subscribe(setLeft.bind(themouse)); 19 | top.subscribe(setTop.bind(themouse)); 20 | 21 | // Update the tail 22 | var mouseoffset = themouse.offsetWidth; 23 | var thetail = document.querySelector('#thetail'); 24 | left 25 | .map(partialAdd(mouseoffset)) 26 | .delay(delay) 27 | .subscribe(setLeft.bind(thetail)); 28 | top 29 | .delay(delay) 30 | .subscribe(setTop.bind(thetail)); 31 | 32 | }()); -------------------------------------------------------------------------------- /demos/mouse3/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #ffffff; 3 | padding: 10px; 4 | font-family: sans-serif; 5 | } 6 | 7 | .block { 8 | border: 1px solid black; 9 | padding: 10px; 10 | background-color: #ffffff; 11 | } 12 | 13 | li { 14 | padding: 5px; 15 | } 16 | 17 | .contrastBlock { 18 | background-color: #000000; 19 | border: 1px solid #666666; 20 | color: #ffffff; 21 | padding: 10px; 22 | } 23 | 24 | .fixedBlock { 25 | border: 1px solid black; 26 | font-family: Courier New, Andale Mono, monospace 27 | padding: 10px; 28 | background-color: #ffffff; 29 | } 30 | 31 | label { 32 | display: block; 33 | padding: 5px; 34 | } 35 | fieldset { 36 | border-style: solid; 37 | border-width: 3px; 38 | } -------------------------------------------------------------------------------- /demos/mouse3/mouse3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Rx for JavaScript Rocks! 10 | 11 | 12 | 13 | 14 |
the mouse!
15 |
its tail!
16 |
is happy!
17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /demos/mouse3/mouse3.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | function extractClientX(e) { return e.clientX; } 4 | function extractClientY(e) { return e.clientY; } 5 | function setLeft(x) { this.style.left = x + 'px'; } 6 | function setTop(y) { this.style.top = y + 'px'; } 7 | function add(x, y) { return x + y; } 8 | var partialAdd = function (x) { return add.bind(null, x); }; 9 | function randomize() { return Math.round(10 * Math.random() - 5); } 10 | 11 | var delay = 300; 12 | 13 | var mousemove = Rx.Observable.fromEvent(document, 'mousemove'); 14 | var left = mousemove.map(extractClientX); 15 | var top = mousemove.map(extractClientY); 16 | 17 | // Update the mouse 18 | var themouse = document.querySelector('#themouse'); 19 | left.subscribe(setLeft.bind(themouse)); 20 | top.subscribe(setTop.bind(themouse)); 21 | 22 | // Update the tail 23 | var mouseoffset = themouse.offsetWidth; 24 | var thetail = document.querySelector('#thetail'); 25 | left 26 | .map(partialAdd(mouseoffset)) 27 | .delay(delay) 28 | .subscribe(setLeft.bind(thetail)); 29 | top 30 | .delay(delay) 31 | .subscribe(setTop.bind(thetail)); 32 | 33 | // Update wagging 34 | var wagDelay = delay * 1.5; 35 | var wagging = document.querySelector('#wagging'); 36 | var mouseandtailoffset = mouseoffset + thetail.offsetWidth; 37 | left 38 | .map(partialAdd(mouseandtailoffset)) 39 | .delay(wagDelay) 40 | .subscribe(setLeft.bind(wagging)); 41 | 42 | var waggingDelay = Rx.Observable 43 | .interval(100) 44 | .map(randomize); 45 | 46 | top.delay(wagDelay) 47 | .combineLatest(waggingDelay, add) 48 | .subscribe(setTop.bind(wagging)); 49 | }()); --------------------------------------------------------------------------------