├── .gitattributes ├── LICENSE ├── README.md ├── bower.json ├── bower_components ├── dexie │ ├── .bower.json │ ├── LICENSE │ ├── README.md │ ├── bower.json │ ├── dist │ │ └── latest │ │ │ ├── Dexie.js │ │ │ ├── Dexie.min.js │ │ │ └── Dexie.min.js.map │ └── package.json └── qunit │ ├── .bower.json │ ├── AUTHORS.txt │ ├── CONTRIBUTING.md │ ├── History.md │ ├── LICENSE.txt │ ├── README.md │ ├── bower.json │ ├── browserstack.json │ ├── build │ └── release.js │ ├── external │ └── jsdiff │ │ └── jsdiff.js │ ├── qunit │ ├── qunit.css │ └── qunit.js │ ├── reporter │ └── html.js │ └── src │ ├── assert.js │ ├── core.js │ ├── dump.js │ ├── equiv.js │ ├── export.js │ ├── intro.js │ ├── outro.js │ ├── qunit.css │ └── test.js ├── idb-iegap.js ├── idb-iegap.min.js ├── idb-iegap.min.js.map └── test ├── index.html ├── migration-phase-1.html ├── migration-phase-2.html ├── tests-common.js └── unit-tests.html /.gitattributes: -------------------------------------------------------------------------------- 1 | idb-iegap.js export-subst 2 | -------------------------------------------------------------------------------- /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. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **NOTICE!** 2 | This library is outdated. Please use [IndexedDBShim](https://github.com/axemclion/IndexedDBShim) instead. 3 | 4 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "idb-iegap", 3 | "version": "0.9.3", 4 | "homepage": "https://github.com/dfahlander/idb-iegap", 5 | "authors": [ 6 | "David Fahlander " 7 | ], 8 | "description": "Polyfill that makes IE10 / IE11 support the full IndexedDB specification by implementing compound and multiEntry index handling", 9 | "main": "idb-iegap.min.js", 10 | "moduleType": [ 11 | "globals" 12 | ], 13 | "keywords": [ 14 | "indexeddb", 15 | "polyfill", 16 | "ie10", 17 | "ie11", 18 | "compound", 19 | "multiEntry", 20 | "composed", 21 | "index" 22 | ], 23 | "license": "Apache 2.0", 24 | "ignore": [ 25 | "**/.*", 26 | "node_modules", 27 | "bower_components", 28 | "test", 29 | "tests" 30 | ], 31 | "devDependencies": { 32 | "qunit": "~1.15.0", 33 | "dexie": "~1.0.1" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /bower_components/dexie/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dexie", 3 | "homepage": "https://github.com/dfahlander/Dexie.js", 4 | "authors": [ 5 | "David Fahlander" 6 | ], 7 | "description": "Minimalistic IndexedDB API with bullet proof transactions", 8 | "main": "dist/latest/Dexie.min.js", 9 | "moduleType": [ 10 | "amd", 11 | "globals", 12 | "node" 13 | ], 14 | "keywords": [ 15 | "indexeddb", 16 | "browser", 17 | "database" 18 | ], 19 | "license": "Apache-2.0", 20 | "ignore": [ 21 | "**/.*", 22 | "addons", 23 | "test", 24 | "samples", 25 | "dist/allversions/", 26 | "src" 27 | ], 28 | "version": "1.0.1", 29 | "_release": "1.0.1", 30 | "_resolution": { 31 | "type": "version", 32 | "tag": "v1.0.1", 33 | "commit": "617f7793c2cd769bc48e749d3ae8dc136aa20d68" 34 | }, 35 | "_source": "git://github.com/dfahlander/dexie.js.git", 36 | "_target": "~1.0.1", 37 | "_originalSource": "dexie", 38 | "_direct": true 39 | } -------------------------------------------------------------------------------- /bower_components/dexie/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. 202 | 203 | -------------------------------------------------------------------------------- /bower_components/dexie/README.md: -------------------------------------------------------------------------------- 1 | Dexie.js 2 | ======== 3 | A bullet proof indexedDB wrapper. 4 | 5 | * Minimalistic and straight forward API, easy to use. 6 | * Code Completion friendly - Your IDE will guide you as you type! 7 | * Human readable queries: db.friends.where("lastName").anyOf("Helenius", "Fahlander").each(function(friend){...}) 8 | * Bullet proof error handling using transaction scopes 9 | * The only indexedDB wrapper (so far) to support case insensitive search, set matching and logical OR operations. 10 | * Promise/A+ compliant 11 | * Does not hide backend indexedDB from the caller - always possible to reach the backend IDB objects. 12 | * Performance focused 13 | * Portable across all browsers: 14 | * IE10+ 15 | * Chrome 16 | * Firefox 17 | * Opera 15+ 18 | * Android browser 19 | * Blackberry browser 20 | * Opera mobile 16+ 21 | * Chrome for Android 22 | * Firefox for Android 23 | * IE Mobile 24 | * Safari 8 25 | * IOS Safari 8 26 | * Extended key range queries: equalsIgnoreCase(), anyOf([a,b,c,d,...]), startsWith(), startsWithIgnoreCase() 27 | * Logical "OR": friends.where("age").below(40).or("length").above(200).toArray(...); 28 | * Built to be easily extended and build addons upon. 29 | * Simplified and robust error handling 30 | * Simplified upgrading framework 31 | * Thoroughly unit tested 32 | 33 | Documentation 34 | ------------- 35 | https://github.com/dfahlander/Dexie.js/wiki/Dexie.js 36 | 37 | Samples 38 | ------- 39 | https://github.com/dfahlander/Dexie.js/wiki/Samples 40 | 41 | Forum 42 | ----- 43 | https://groups.google.com/forum/#!forum/dexiejs 44 | 45 | Download 46 | -------- 47 | https://raw.githubusercontent.com/dfahlander/Dexie.js/master/dist/latest/Dexie.js 48 | https://raw.githubusercontent.com/dfahlander/Dexie.js/master/dist/latest/Dexie.min.js 49 | 50 | 51 | -------------------------------------------------------------------------------- /bower_components/dexie/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dexie", 3 | "homepage": "https://github.com/dfahlander/Dexie.js", 4 | "authors": [ 5 | "David Fahlander" 6 | ], 7 | "description": "Minimalistic IndexedDB API with bullet proof transactions", 8 | "main": "dist/latest/Dexie.min.js", 9 | "moduleType": [ 10 | "amd", 11 | "globals", 12 | "node" 13 | ], 14 | "keywords": [ 15 | "indexeddb", 16 | "browser", 17 | "database" 18 | ], 19 | "license": "Apache-2.0", 20 | "ignore": [ 21 | "**/.*", 22 | "addons", 23 | "test", 24 | "samples", 25 | "dist/allversions/", 26 | "src" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /bower_components/dexie/dist/latest/Dexie.min.js: -------------------------------------------------------------------------------- 1 | (function(n,t,i,r){"use strict";function h(n,t){return typeof t!="object"&&(t=t()),Object.keys(t).forEach(function(i){n[i]=t[i]}),n}function y(n){return{from:function(t){return n.prototype=Object.create(t.prototype),n.prototype.constructor=n,{extend:function(i){h(n.prototype,typeof i!="object"?i(t.prototype):i)}}}}}function p(n,t){return t(n)}function f(t){function or(){if(i)w.on("versionchange",function(t){w.close();t.newVersion&&n.location.reload(!0)})}function ki(n){this._cfg={version:n,storesSource:null,dbschema:{},tables:{},contentUpgrade:null};this.stores({})}function sr(n,t,i,r){var e,f,o,h,l,c;if(n==0)Object.keys(pt).forEach(function(n){di(t,n,pt[n].primKey,pt[n].indexes)}),e=w._createTransaction(kt,ri,pt),e.idbtrans=t,e.idbtrans.onerror=s(i,["populating database"]),e.on("error").subscribe(i),u.newPSD(function(){u.PSD.trans=e;try{w.on("populate").fire(e)}catch(n){r.onerror=t.onerror=function(n){n.preventDefault()};try{t.abort()}catch(f){}t.db.close();i(n)}});else{if(f=[],o=ii.filter(function(t){return t._cfg.version===n})[0],!o)throw new et("Dexie specification of currently installed DB version is missing");pt=w._dbSchema=o._cfg.dbschema;h=!1;l=ii.filter(function(t){return t._cfg.version>n});l.forEach(function(n){var e=pt,r=n._cfg.dbschema,u;ur(e,t);ur(r,t);pt=w._dbSchema=r;u=hr(e,r);u.add.forEach(function(n){f.push(function(t,i){di(t,n[0],n[1].primKey,n[1].indexes);i()})});u.change.forEach(function(n){if(n.recreate)throw new et("Not yet support for changing primary key");else f.push(function(t,i){var r=t.objectStore(n.name);n.add.forEach(function(n){gi(r,n)});n.change.forEach(function(n){r.deleteIndex(n.name);gi(r,n)});n.del.forEach(function(n){r.deleteIndex(n)});i()})});n._cfg.contentUpgrade&&f.push(function(t,u){var f,e;h=!0;f=w._createTransaction(kt,[].slice.call(t.db.objectStoreNames,0),r);f.idbtrans=t;e=0;f._promise=p(f._promise,function(n){return function(t,i,r){function f(n){return function(){n.apply(this,arguments);--e==0&&u()}}return++e,n.call(this,t,function(n,t){arguments[0]=f(n);arguments[1]=f(t);i.apply(this,arguments)},r)}});t.onerror=s(i,["running upgrader function for version",n._cfg.version]);f.on("error").subscribe(i);n._cfg.contentUpgrade(f);e===0&&u()});h&&wr()||f.push(function(n,t){lr(r,n);t()})});c=function(){try{f.length?f.shift()(t,c):cr(pt,t)}catch(n){r.onerror=t.onerror=function(n){n.preventDefault()};t.abort();t.db.close();i(n)}};c()}}function hr(n,t){var f={del:[],add:[],change:[]},r,e,o,i,c,s,u,l,h;for(r in n)t[r]||f.del.push(r);for(r in t)if(e=n[r],o=t[r],e)if(i={name:r,def:t[r],recreate:!1,del:[],add:[],change:[]},e.primKey.src!=o.primKey.src)i.recreate=!0,f.change.push(i);else{c=e.indexes.reduce(function(n,t){return n[t.name]=t,n},{});s=o.indexes.reduce(function(n,t){return n[t.name]=t,n},{});for(u in c)s[u]||i.del.push(u);for(u in s)l=c[u],h=s[u],l?l.src!=h.src&&i.change.push(h):i.add.push(h);(i.recreate||i.del.length>0||i.add.length>0||i.change.length>0)&&f.change.push(i)}else f.add.push([r,o]);return f}function di(n,t,i,r){var u=n.db.createObjectStore(t,i.keyPath?{keyPath:i.keyPath,autoIncrement:i.auto}:{autoIncrement:i.auto});return r.forEach(function(n){gi(u,n)}),u}function cr(n,t){Object.keys(n).forEach(function(i){t.db.objectStoreNames.contains(i)||di(t,i,n[i].primKey,n[i].indexes)})}function lr(n,t){for(var u,i=0;it?1:0}function fr(n,t){return nt?-1:0}function er(n){return function(t,i){for(var u,r=0;;){if(u=n(t[r],i[r]),u!==0)return u;if(++r,r===t.length||r==i.length)return n(t.length,i.length)}}}function wi(n,t){return n?t?function(){return n.apply(this,arguments)&&t.apply(this,arguments)}:n:t}function wr(){return navigator.userAgent.indexOf("Trident")>=0||navigator.userAgent.indexOf("MSIE")>=0}function br(){if(w.verno=lt.version/10,w._dbSchema=pt={},ri=[].slice.call(lt.objectStoreNames,0),ri.length!=0){var n=lt.transaction(ri,"readonly");ri.forEach(function(t){for(var u,s,r=n.objectStore(t),i=r.keyPath,f=i&&typeof i=="string"&&i.indexOf(".")!=-1,h=new v(i,i||"",!1,!1,!!r.autoIncrement,i&&typeof i!="string",f),o=[],e=0;eMath.pow(2,62)?0:n.oldVersion,sr(u/10,r.transaction,f,r))},f);r.onsuccess=d(function(){li=!1;lt=r.result;ai?br():lt.objectStoreNames.length>0&&ur(pt,lt.transaction(lt.objectStoreNames,ni));lt.onversionchange=w.on("versionchange").fire;rt(function(n){if(n.indexOf(t)===-1)return n.push(t)});u.newPSD(function(){function i(){oi=!1;ti.forEach(function(n){n.resume()});ti=[];n()}u.PSD.letThrough=!0;try{var t=w.on.ready.fire();t&&typeof t.then=="function"?t.then(i,function(n){lt.close();lt=null;f(n)}):k(i)}catch(r){f(r)}})},f)}catch(o){f(o)}})};this.close=function(){lt&&(lt.close(),lt=null,oi=!0,ui=null)};this.delete=function(){var n=arguments;return new u(function(i,r){function u(){w.close();var n=ci.deleteDatabase(t);n.onsuccess=function(){rt(function(n){var i=n.indexOf(t);if(i>=0)return n.splice(i,1)});i()};n.onerror=s(r,["deleting",t]);n.onblocked=function(){w.on("blocked").fire()}}if(n.length>0)throw new et("Arguments not allowed in db.delete()");li?ti.push({resume:u}):u()})};this.backendDB=function(){return lt};this.isOpen=function(){return lt!==null};this.hasFailed=function(){return ui!==null};this.name=t;Object.defineProperty(this,"tables",{get:function(){return Object.keys(gt).map(function(n){return gt[n]})}});this.on=b(this,"error","populate","blocked",{ready:[yt,e],versionchange:[at,e]});this.on.ready.subscribe=p(this.on.ready.subscribe,function(n){return function(t,i){function r(){return i||w.on.ready.unsubscribe(r),t.apply(this,arguments)}n.call(this,r);w.isOpen()&&(oi?ti.push({resume:r}):r())}});o(function(){w.on("populate").fire(w._createTransaction(kt,ri,pt));w.on("error").fire(new et)});this.transaction=function(n,t,i){function s(t,e){var s=null,c,a,h;try{if(f)throw f;s=w._createTransaction(n,o,pt,r);c=o.map(function(n){return s.tables[n]});c.push(s);h=0;u.newPSD(function(){u.PSD.trans=s;s.scopeFunc=i;r&&(s.idbtrans=r.idbtrans,s._promise=p(s._promise,function(n){return function(t,i,r){function u(n){return function(t){var i=n(t);return--h==0&&s.active&&(s.active=!1,s.on.complete.fire()),i}}return++h,n.call(this,t,function(n,t,r){return i(u(n),u(t),r)},r)}}));s.complete(function(){t(a)});s.error(function(n){s.idbtrans.onerror=ot;s.abort();r&&(r.active=!1,r.on.error.fire(n));var t=e(n);r||t||w.on.error.fire(n)});a=i.apply(s,c)});(!s.idbtrans||r&&h===0)&&s._nop()}catch(l){s&&s.idbtrans&&(s.idbtrans.onerror=ot);s&&s.abort();r&&r.on.error.fire(l);k(function(){e(l)||w.on("error").fire(l)})}}var r,e;t=[].slice.call(arguments,1,arguments.length-1);i=arguments[arguments.length-1];r=u.PSD&&u.PSD.trans;n.indexOf("!")!==-1&&(r=null);e=n.indexOf("?")!==-1;n=n.replace("!","").replace("?","");var h=Array.isArray(t[0])?t.reduce(function(n,t){return n.concat(t)}):t,f=null,o=h.map(function(n){return typeof n=="string"?n:(n instanceof fi||(f=f||new vi("Invalid type. Arguments following mode must be instances of Table or String")),n.name)});return n=="r"||n==ni?n=ni:n=="rw"||n==kt?n=kt:f=new et("Invalid transaction mode: "+n),r&&(f||(r.db!=w&&(e?r=null:f=new et("Current transaction bound to different database instance")),r&&r.mode===ni&&n===kt&&(e?r=null:f=f||new et("Cannot enter a sub-transaction with READWRITE mode when parent transaction is READONLY")),r&&o.forEach(function(n){r.tables.hasOwnProperty(n)||(e?r=null:f=f||new et("Table "+n+" not included in parent transaction. Parent Transaction function: "+r.scopeFunc.toString()))}))),r?r._promise(n,s,"lock"):w._whenReady(s)};this.table=function(n){if(!ai&&!gt.hasOwnProperty(n))throw new et("Table does not exist");return gt[n]};h(fi.prototype,function(){function n(){throw new et("Current Transaction is READONLY");}return{_trans:function(n,t,i){return this._tpf(n,[this.name],t,i)},_idbstore:function(n,t,i){var r=this;return this._tpf(n,[this.name],function(n,i,u){t(n,i,u.idbtrans.objectStore(r.name),u)},i)},get:function(n,t){var i=this;return o(function(){t(i.schema.instanceTemplate)}),this._idbstore(ni,function(t,r,u){var f=u.get(n);f.onerror=s(r,["getting",n,"from",i.name]);f.onsuccess=function(){t(i.hook.reading.fire(f.result))}}).then(t)},where:function(n){return new si(this,n)},count:function(n){return this.toCollection().count(n)},offset:function(n){return this.toCollection().offset(n)},limit:function(n){return this.toCollection().limit(n)},reverse:function(){return this.toCollection().reverse()},filter:function(n){return this.toCollection().and(n)},each:function(n){var t=this;return o(function(){n(t.schema.instanceTemplate)}),this._idbstore(ni,function(i,r,u){var f=u.openCursor();f.onerror=s(r,["calling","Table.each()","on",t.name]);yi(f,null,n,i,r,t.hook.reading.fire)})},toArray:function(n){var t=this;return o(function(){n([t.schema.instanceTemplate])}),this._idbstore(ni,function(n,i,r){var u=[],f=r.openCursor();f.onerror=s(i,["calling","Table.toArray()","on",t.name]);yi(f,null,function(n){u.push(n)},function(){n(u)},i,t.hook.reading.fire)}).then(n)},orderBy:function(n){return new this._collClass(new si(this,n))},toCollection:function(){return new this._collClass(new si(this))},mapToClass:function(n,t){var i,r;return this.schema.mappedClass=n,i=Object.create(n.prototype),this.schema.primKey.keyPath&&(c(i,this.schema.primKey.keyPath,this.schema.primKey.auto?0:""),ft(n.prototype,this.schema.primKey.keyPath)),t&&it(i,t),this.schema.instanceTemplate=i,r=Object.setPrototypeOf?function(t){return t?(Object.setPrototypeOf(t,n.prototype),t):t}:function(t){var r,i;if(!t)return t;r=Object.create(n.prototype);for(i in t)t.hasOwnProperty(i)&&(r[i]=t[i]);return r},this.schema.readHook&&this.hook.reading.unsubscribe(this.schema.readHook),this.schema.readHook=r,this.hook("reading",r),n},defineClass:function(n){return this.mapToClass(f.defineClass(n),n)},add:n,put:n,"delete":n,clear:n,update:n}});y(nr).from(fi).extend(function(){return{add:function(n,t){var u=this,i=this.hook.creating.fire;return this._idbstore(kt,function(f,o,h,a){var v={},w,y,p;i!==e&&(w=t||(h.keyPath?l(n,h.keyPath):r),y=i.call(v,w,n,a),w===r&&y!==r&&(h.keyPath?c(n,h.keyPath,y):t=y));p=t?h.add(n,t):h.add(n);p.onerror=s(function(n){if(v.onerror)v.onerror(n);return o(n)},["adding",n,"into",u.name]);p.onsuccess=function(t){var i=h.keyPath;if(i&&c(n,i,t.target.result),v.onsuccess)v.onsuccess(t.target.result);f(p.result)}})},put:function(n,t){var i=this,u=this.hook.creating.fire,f=this.hook.updating.fire;return u!==e||f!==e?this._trans(kt,function(u,f,e){var o=t||i.schema.primKey.keyPath&&l(n,i.schema.primKey.keyPath);o===r?e.tables[i.name].add(n).then(u,f):(e._lock(),n=a(n),e.tables[i.name].where(":id").equals(o).modify(function(){this.value=n}).then(function(r){return r===0?e.tables[i.name].add(n,t):o}).finally(function(){e._unlock()}).then(u,f))}):this._idbstore(kt,function(r,u,f){var e=t?f.put(n,t):f.put(n);e.onerror=s(u,["putting",n,"into",i.name]);e.onsuccess=function(t){var i=f.keyPath;i&&c(n,i,t.target.result);r(e.result)}})},"delete":function(n){return this.hook.deleting.subscribers.length?this.where(":id").equals(n).delete():this._idbstore(kt,function(t,i,r){var u=r.delete(n);u.onerror=s(i,["deleting",n,"from",r.name]);u.onsuccess=function(){t(u.result)}})},clear:function(){return this.hook.deleting.subscribers.length?this.toCollection().delete():this._idbstore(kt,function(n,t,i){var r=i.clear();r.onerror=s(t,["clearing",i.name]);r.onsuccess=function(){n(r.result)}})},update:function(n,t){if(typeof t!="object"||Array.isArray(t))throw new et("db.update(keyOrObject, modifications). modifications must be an object.");if(typeof n!="object"||Array.isArray(n))return this.where(":id").equals(n).modify(t);Object.keys(t).forEach(function(i){c(n,i,t[i])});var i=l(n,this.schema.primKey.keyPath);return i===r&&u.reject(new et("Object does not contain its primary key")),this.where(":id").equals(i).modify(t)}}});h(tr.prototype,{_lock:function(){return++this._reculock,this._reculock===1&&u.PSD&&(u.PSD.lockOwnerFor=this),this},_unlock:function(){if(--this._reculock==0)for(u.PSD&&(u.PSD.lockOwnerFor=null);this._blockedFuncs.length>0&&!this._locked();){var n=this._blockedFuncs.shift();try{n()}catch(t){}}return this},_locked:function(){return this._reculock&&(!u.PSD||u.PSD.lockOwnerFor!==this)},_nop:function(n){this.tables[this.storeNames[0]].get(0).then(n)},_promise:function(n,t,i){var r=this;return u.newPSD(function(){var e;return r._locked()?e=new u(function(u,f){r._blockedFuncs.push(function(){r._promise(n,t,i).then(u,f)})}):(e=r.active?new u(function(u,e){if(!r.idbtrans&&n){if(!lt)throw ui?new et("Database not open. Following error in populate, ready or upgrade function made Dexie.open() fail: "+ui):new et("Database not open");var o=r.idbtrans=lt.transaction(r.storeNames,r.mode);o.onerror=function(n){r.on("error").fire(n&&n.target.error);n.preventDefault();r.abort()};o.onabort=function(n){r.active=!1;r.on("abort").fire(n)};o.oncomplete=function(n){r.active=!1;r.on("complete").fire(n)}}i&&r._lock();try{t(u,e,r)}catch(s){f.spawn(function(){r.on("error").fire(s)});r.abort();e(s)}}):u.reject(bt(new et("Transaction is inactive. Original Scope Function Source: "+r.scopeFunc.toString()))),r.active&&i&&e.finally(function(){r._unlock()})),e.onuncatched=function(n){f.spawn(function(){r.on("error").fire(n)});r.abort()},e})},complete:function(n){return this.on("complete",n)},error:function(n){return this.on("error",n)},abort:function(){if(this.idbtrans&&this.active)try{this.active=!1;this.idbtrans.abort();this.on.error.fire(new et("Transaction Aborted"))}catch(n){}},table:function(n){if(!this.tables.hasOwnProperty(n))throw new et("Table "+n+" not in transaction");return this.tables[n]}});h(si.prototype,function(){function n(n,t){try{throw t;}catch(i){n._ctx.error=i}return n}function i(n){return Array.prototype.slice.call(n.length===1&&Array.isArray(n[0])?n[0]:n)}function r(n){return n==="next"?function(n){return n.toUpperCase()}:function(n){return n.toLowerCase()}}function u(n){return n==="next"?function(n){return n.toLowerCase()}:function(n){return n.toUpperCase()}}function f(n,t,i,r,u,f){for(var h,s=Math.min(n.length,r.length),o=-1,e=0;e=0?n.substr(0,o)+t[o]+i.substr(o+1):null;u(n[e],h)<0&&(o=e)}return st||n==t&&(i||r)&&!(i&&r))?new this._ctx.collClass(this,dt.only(n)).limit(0):new this._ctx.collClass(this,dt.bound(n,t,!i,!r))},equals:function(n){return new this._ctx.collClass(this,dt.only(n))},above:function(n){return new this._ctx.collClass(this,dt.lowerBound(n,!0))},aboveOrEqual:function(n){return new this._ctx.collClass(this,dt.lowerBound(n))},below:function(n){return new this._ctx.collClass(this,dt.upperBound(n,!0))},belowOrEqual:function(n){return new this._ctx.collClass(this,dt.upperBound(n))},startsWith:function(t){return typeof t!="string"?n(new this._ctx.collClass(this),new vi("String expected")):this.between(t,t+String.fromCharCode(65535),!0,!0)},startsWithIgnoreCase:function(i){if(typeof i!="string")return n(new this._ctx.collClass(this),new vi("String expected"));if(i==="")return this.startsWith(i);var r=new this._ctx.collClass(this,dt.bound(i.toUpperCase(),i.toLowerCase()+String.fromCharCode(65535)));return t(r,function(n,t){return n.indexOf(t)===0},i),r._ondirectionchange=function(){n(r,new et("reverse() not supported with WhereClause.startsWithIgnoreCase()"))},r},equalsIgnoreCase:function(i){if(typeof i!="string")return n(new this._ctx.collClass(this),new vi("String expected"));var r=new this._ctx.collClass(this,dt.bound(i.toUpperCase(),i.toLowerCase()));return t(r,function(n,t){return n===t},i),r},anyOf:function(){var f=this._ctx,e=f.table.schema,o=f.index?e.idxByName[f.index]:e.primKey,s=o&&o.compound,n=i(arguments),t=s?er(pi):pi,u,r;return(n.sort(t),n.length===0)?new this._ctx.collClass(this,dt.only("")).limit(0):(u=new this._ctx.collClass(this,dt.bound(n[0],n[n.length-1])),u._ondirectionchange=function(i){t=i==="next"?pi:fr;s&&(t=er(t));n.sort(t)},r=0,u._addAlgorithm(function(i,u,f){for(var e=i.key;t(e,n[r])>0;)if(++r,r===n.length)return u(f),!1;return t(e,n[r])===0?(u(function(){i.continue()}),!0):(u(function(){i.continue(n[r])}),!1)}),u)}}});h(hi.prototype,function(){function t(n,t){n.filter=wi(n.filter,t)}function f(n,t){n.isMatch=wi(n.isMatch,t)}function r(n,t){if(n.isPrimKey)return t;var i=n.table.schema.idxByName[n.index];if(!i)throw new et("KeyPath "+n.index+" on object store "+t.name+" is not indexed");return n.isPrimKey?t:t.index(i.name)}function u(n,t){return r(n,t)[n.op](n.range||null,n.dir+n.unique)}function i(n,t,i,r,f){n.or?function(){function e(){++c==2&&i()}function h(n,i,u){if(!o||o(i,u,e,r)){var f=i.primaryKey.toString();s.hasOwnProperty(f)||(s[f]=!0,t(n,i,u))}}var o=n.filter,s={},l=n.table.schema.primKey.keyPath,c=0;n.or._iterate(h,e,r,f);yi(u(n,f),n.algorithm,h,e,r,n.table.hook.reading.fire)}():yi(u(n,f),wi(n.algorithm,n.filter),t,i,r,n.table.hook.reading.fire)}function n(n){return n.table.schema.instanceTemplate}return{_read:function(n,t){var i=this._ctx;return i.error?i.table._trans(null,function(n,t){t(i.error)}):i.table._idbstore(ni,n).then(t)},_write:function(n){var t=this._ctx;return t.error?t.table._trans(null,function(n,i){i(t.error)}):t.table._idbstore(kt,n,"locked")},_addAlgorithm:function(n){var t=this._ctx;t.algorithm=wi(t.algorithm,n)},_iterate:function(n,t,r,u){return i(this._ctx,n,t,r,u)},each:function(t){var r=this._ctx;return o(function(){t(n(r))}),this._read(function(n,u,f){i(r,t,n,u,f)})},count:function(n){var f,t,u;return o(function(){n(0)}),f=this,t=this._ctx,t.filter||t.algorithm||t.or?(u=0,this._read(function(n,r,f){i(t,function(){return++u,!1},function(){n(u)},r,f)},n)):this._read(function(n,i,u){var e=r(t,u),o=t.range?e.count(t.range):e.count();o.onerror=s(i,["calling","count()","on",f.name]);o.onsuccess=function(i){n(Math.min(i.target.result,Math.max(0,t.limit-t.offset)))}},n)},sortBy:function(t,i){function u(n,t){return t?u(n[r[t]],t-1):n[h]}function c(n,t){var i=u(n,e),r=u(t,e);return ir?f:0}var s=this._ctx,f;o(function(){i([n(s)])});var r=t.split(".").reverse(),h=r[0],e=r.length-1;return f=this._ctx.dir==="next"?1:-1,this.toArray(function(n){return n.sort(c)}).then(i)},toArray:function(t){var r=this._ctx;return o(function(){t([n(r)])}),this._read(function(n,t,u){var f=[];i(r,function(n){f.push(n)},function(){n(f)},t,u)},t)},offset:function(n){var i=this._ctx;return n<=0?this:(i.offset+=n,i.or||i.algorithm||i.filter?t(i,function(){return--n<0}):t(i,function(t,i){return n===0?!0:n===1?(--n,!1):(i(function(){t.advance(n);n=0}),!1)}),this)},limit:function(n){return this._ctx.limit=Math.min(this._ctx.limit,n),t(this._ctx,function(t,i,r){return--n<=0&&i(r),n>=0}),this},until:function(i,r){var u=this._ctx;return o(function(){i(n(u))}),t(this._ctx,function(n,t,u){return i(n.value)?(t(u),r):!0}),this},first:function(t){var i=this;return o(function(){t(n(i._ctx))}),this.limit(1).toArray(function(n){return n[0]}).then(t)},last:function(n){return this.reverse().first(n)},and:function(i){var r=this;return o(function(){i(n(r._ctx))}),t(this._ctx,function(n){return i(n.value)}),f(this._ctx,i),this},or:function(n){return new si(this._ctx.table,n,this)},reverse:function(){return this._ctx.dir=this._ctx.dir=="prev"?"next":"prev",this._ondirectionchange&&this._ondirectionchange(this._ctx.dir),this},desc:function(){return this.reverse()},eachKey:function(t){var i=this,r=this._ctx;return o(function(){t(n(i._ctx)[i._ctx.index])}),r.isPrimKey||(r.op="openKeyCursor"),this.each(function(n,i){t(i.key,i)})},eachUniqueKey:function(n){return this._ctx.unique="unique",this.eachKey(n)},keys:function(t){var u,i,r;return o(function(){t([n(i)[u._ctx.index]])}),u=this,i=this._ctx,i.isPrimKey||(i.op="openKeyCursor"),r=[],this.each(function(n,t){r.push(t.key)}).then(function(){return r}).then(t)},uniqueKeys:function(n){return this._ctx.unique="unique",this.keys(n)},firstKey:function(n){var t=this;return this.limit(1).keys(function(n){return n[0]}).then(n)},lastKey:function(n){return this.reverse().firstKey(n)},distinct:function(){var n={};return t(this._ctx,function(t){var i=t.primaryKey.toString(),r=n.hasOwnProperty(i);return n[i]=!0,!r}),this}}});y(ir).from(hi).extend({modify:function(n){var f=this,t=this._ctx,r=t.table.hook,i=r.updating.fire,u=r.deleting.fire;return o(function(){typeof n=="function"&&n.call({value:t.table.schema.instanceTemplate},t.table.schema.instanceTemplate)}),this._write(function(r,o,v,y){function st(n,i){var r,u,f;ft=i.primaryKey;r={primKey:i.primaryKey,value:n};w.call(r,n)!==!1&&(u=!r.hasOwnProperty("value"),f=u?i.delete():i.update(r.value),++rt,f.onerror=s(function(n){if(p.push(n),nt.push(r.primKey),r.onerror)r.onerror(n);return!0},u?["deleting",n,"from",t.table.name]:["modifying",n,"on",t.table.name]),f.onsuccess=function(){if(r.onsuccess)r.onsuccess(r.value);++b;ot()})}function et(n){return n&&(p.push(n),nt.push(ft)),o(new g("Error modifying one or more objects",p,b,nt))}function ot(){ut&&b+p.length===rt&&(p.length>0?et():r(b))}var w,k,it,d;typeof n=="function"?w=i===e&&u===e?n:function(t){var f=a(t),e,r;if(n.call(this,t)===!1)return!1;this.hasOwnProperty("value")?(e=wt(f,this.value),r=i.call(this,e,this.primKey,f,y),r&&(t=this.value,Object.keys(r).forEach(function(n){c(t,n,r[n])}))):u.call(this,this.primKey,t,y)}:i===e?(k=Object.keys(n),it=k.length,w=function(t){for(var i,u,f=!1,r=0;r0)p();i=h;f=!0}}function c(n){n._catched=!0;n._parent&&c(n._parent)}function o(n,i){var r=t.PSD;t.PSD=n._PSD;try{if(i===n)throw new TypeError("A promise cannot be resolved with itself.");if(i&&(typeof i=="object"||typeof i=="function")&&typeof i.then=="function"){v(n,function(n,t){i.then(n,t)},function(t){o(n,t)},function(t){u(n,t)});return}n._state=!0;n._value=i;l.call(n)}catch(f){u(f)}finally{t.PSD=r}}function u(n,i){var r=t.PSD;if(t.PSD=n._PSD,n._state=!1,n._value=i,l.call(n),!n._catched&&n.onuncatched)try{n.onuncatched(n._value)}catch(u){}return t.PSD=r,n._catched}function l(){for(var n=0,t=this._deferreds.length;n 2 | Ariel Flesler 3 | Scott González 4 | Richard Worth 5 | Philippe Rathé 6 | John Resig 7 | Will Moffat 8 | Jan Kassens 9 | Ziling Zhao 10 | Ryan Szulczewski 11 | Chris Lloyd 12 | Louis-Rémi Babé 13 | Jake Archibald 14 | Frances Berriman 15 | Rune Halvorsen 16 | Chris Thatcher 17 | Fábio Rehm 18 | Leon Sorokin 19 | Douglas Neiner 20 | Paul Elliott 21 | Nikita Vasilyev 22 | Benjamin Lee 23 | Paul Irish 24 | Oleg Slobodskoi 25 | Anton Matzneller 26 | Aurélien Bombo 27 | Mathias Bynens 28 | Erik Vold 29 | Wesley Walser 30 | Rob Kinninmont 31 | Marc Portier 32 | Michael Righi 33 | Timo Tijhof 34 | Jan Alonzo 35 | Daniel Trebbien 36 | Bob Fanger 37 | Markus Messner-Chaney 38 | Trevor Parscal 39 | Ashar Voultoiz 40 | Jimmy Mabey 41 | Domenic Denicola 42 | Mike Sherov 43 | Seong-A Kong 44 | Graham Conzett 45 | Niall Smart 46 | Johan Sörlin 47 | Gijs Kruitbosch 48 | Erkan Yilmaz 49 | Jonathan Sanchez 50 | Keith Cirkel 51 | Rick Waldron 52 | Herbert Vojčík 53 | Richard Gibson 54 | Alex J Burke 55 | Sergii Kliuchnyk 56 | Corey Frang 57 | John Reeves 58 | Antranig Basman 59 | Vivin Paliath 60 | Joshua Niehus 61 | Glen Huang 62 | Jochen Ulrich 63 | Jamie Hoover 64 | James M. Greene 65 | Rodney Rehm 66 | Peter Wagenet 67 | Clog 68 | Matthew Mirande 69 | Jared Wyles 70 | Dmitry Gusev 71 | Ian Wallis 72 | Dan Andreescu 73 | Matthew DuVall 74 | Dave K. Smith 75 | David Vollbracht 76 | Katie Gengler 77 | Joshua Peek 78 | Leonardo Balter 79 | Jeff Cooper 80 | Corey Frang 81 | Nathan Dauber 82 | Michał Gołębiowski 83 | XhmikosR 84 | Patrick Stapleton 85 | DarkPark 86 | Oleg Gaidarenko 87 | Mike Sidorov 88 | Don Kirkby 89 | don 90 | Sean Xu 91 | -------------------------------------------------------------------------------- /bower_components/qunit/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Welcome! Thanks for your interest in contributing to QUnit. You're **almost** in the right place. More information on how to contribute to this and all other jQuery Foundation projects is over at [contribute.jquery.org](http://contribute.jquery.org). You'll definitely want to take a look at the articles on contributing [code](http://contribute.jquery.org/code). 2 | 3 | You may also want to take a look at our [commit & pull request guide](http://contribute.jquery.org/commits-and-pull-requests/) and [style guides](http://contribute.jquery.org/style-guide/) for instructions on how to maintain your fork and submit your code. Before we can merge any pull request, we'll also need you to sign our [contributor license agreement](http://contribute.jquery.org/cla). 4 | 5 | You can find us on [IRC](http://irc.jquery.org), specifically in #jquery-dev should you have any questions. If you've never contributed to open source before, we've put together [a short guide with tips, tricks, and ideas on getting started](http://contribute.jquery.org/open-source/). 6 | -------------------------------------------------------------------------------- /bower_components/qunit/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2006, 2014 jQuery Foundation and other contributors, 2 | https://jquery.org/ 3 | 4 | This software consists of voluntary contributions made by many 5 | individuals. For exact contribution history, see the revision history 6 | available at https://github.com/jquery/qunit 7 | 8 | The following license applies to all parts of this software except as 9 | documented below: 10 | 11 | ==== 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining 14 | a copy of this software and associated documentation files (the 15 | "Software"), to deal in the Software without restriction, including 16 | without limitation the rights to use, copy, modify, merge, publish, 17 | distribute, sublicense, and/or sell copies of the Software, and to 18 | permit persons to whom the Software is furnished to do so, subject to 19 | the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be 22 | included in all copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 | 32 | ==== 33 | 34 | All files located in the node_modules and external directories are 35 | externally maintained libraries used by this software which have their 36 | own licenses; we recommend you read them, as their terms may differ from 37 | the terms above. 38 | -------------------------------------------------------------------------------- /bower_components/qunit/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](http://jenkins.jquery.com/job/QUnit/badge/icon)](http://jenkins.jquery.com/job/QUnit/) 2 | [![Coverage Status](https://coveralls.io/repos/jquery/qunit/badge.png)](https://coveralls.io/r/jquery/qunit) 3 | 4 | # [QUnit](http://qunitjs.com) - A JavaScript Unit Testing Framework. 5 | 6 | QUnit is a powerful, easy-to-use, JavaScript unit testing framework. It's used by the jQuery 7 | project to test its code and plugins but is capable of testing any generic 8 | JavaScript code (and even capable of testing JavaScript code on the server-side). 9 | 10 | QUnit is especially useful for regression testing: Whenever a bug is reported, 11 | write a test that asserts the existence of that particular bug. Then fix it and 12 | commit both. Every time you work on the code again, run the tests. If the bug 13 | comes up again - a regression - you'll spot it immediately and know how to fix 14 | it, because you know what code you just changed. 15 | 16 | Having good unit test coverage makes safe refactoring easy and cheap. You can 17 | run the tests after each small refactoring step and always know what change 18 | broke something. 19 | 20 | QUnit is similar to other unit testing frameworks like JUnit, but makes use of 21 | the features JavaScript provides and helps with testing code in the browser, e.g. 22 | with its stop/start facilities for testing asynchronous code. 23 | 24 | If you are interested in helping developing QUnit, you are in the right place. 25 | For related discussions, visit the 26 | [QUnit and Testing forum](http://forum.jquery.com/qunit-and-testing). 27 | 28 | ## Development 29 | 30 | To submit patches, fork the repository, create a branch for the change. Then implement 31 | the change, run `grunt` to lint and test it, then commit, push and create a pull request. 32 | 33 | Include some background for the change in the commit message and `Fixes #nnn`, referring 34 | to the issue number you're addressing. 35 | 36 | To run `grunt`, you need [Node.js](http://nodejs.org/download/), which includes `npm`, then `npm install -g grunt-cli`. That gives you a global grunt binary. For additional grunt tasks, also run `npm install`. 37 | 38 | ## Releases 39 | 40 | Use [jquery-release](https://github.com/jquery/jquery-release). The following aren't yet handled there: 41 | 42 | * Install [git-extras](https://github.com/visionmedia/git-extras) and run `git changelog` to update History.md. Clean up the changelog, removing merge commits or whitespace cleanups. 43 | * Run `grunt authors` and add any new authors to AUTHORS.txt 44 | * Update the version property in `package.json` to have the right -pre version. Not necessary for patch releases. 45 | 46 | Commit these, then run the script. 47 | 48 | Update web sites, replacing previous versions with new ones: 49 | 50 | * jquery/jquery-wp-content themes/jquery/footer-qunit.php 51 | * jquery/qunitjs.com pages/index.html 52 | 53 | Finally announce on Twitter @qunitjs 54 | 55 | Released @VERSION: https://github.com/jquery/qunit/tree/@VERSION 56 | Changelog: https://github.com/jquery/qunit/blob/@VERSION/History.md 57 | -------------------------------------------------------------------------------- /bower_components/qunit/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "qunit", 3 | "main": [ 4 | "qunit/qunit.js", 5 | "qunit/qunit.css" 6 | ], 7 | "license": "https://github.com/jquery/qunit/blob/master/LICENSE.txt", 8 | "ignore": [ 9 | "**/.*", 10 | "!LICENSE.txt", 11 | "package.json", 12 | "bower.json", 13 | "Gruntfile.js", 14 | "node_modules", 15 | "test" 16 | ], 17 | "version": "1.15.0" 18 | } 19 | -------------------------------------------------------------------------------- /bower_components/qunit/browserstack.json: -------------------------------------------------------------------------------- 1 | { 2 | "username": "BROWSERSTACK_USERNAME", 3 | "key": "BROWSERSTACK_KEY", 4 | "test_framework": "qunit", 5 | "test_path": [ 6 | "test/index.html", 7 | "test/async.html", 8 | "test/logs.html", 9 | "test/setTimeout.html" 10 | ], 11 | "browsers": [ 12 | "chrome_previous", 13 | "chrome_latest", 14 | "firefox_previous", 15 | "firefox_latest", 16 | "opera_previous", 17 | "opera_latest", 18 | "safari_previous", 19 | "safari_latest", 20 | "ie_6", 21 | "ie_7", 22 | "ie_8", 23 | "ie_9", 24 | "ie_10", 25 | "ie_11" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /bower_components/qunit/build/release.js: -------------------------------------------------------------------------------- 1 | /*jshint node:true */ 2 | module.exports = function( Release ) { 3 | 4 | var shell = require( "shelljs" ); 5 | 6 | Release.define({ 7 | npmPublish: true, 8 | issueTracker: "github", 9 | changelogShell: function() { 10 | return "# Changelog for QUnit v" + Release.newVersion + "\n"; 11 | }, 12 | 13 | generateArtifacts: function( done ) { 14 | Release.exec( "grunt", "Grunt command failed" ); 15 | shell.mkdir( "-p", "qunit" ); 16 | shell.cp( "-r", "dist/*", "qunit/" ); 17 | shell.mkdir( "-p", "dist/cdn" ); 18 | shell.cp( "dist/qunit.js", "dist/cdn/qunit-" + Release.newVersion + ".js" ); 19 | shell.cp( "dist/qunit.css", "dist/cdn/qunit-" + Release.newVersion + ".css" ); 20 | done([ "qunit/qunit.js", "qunit/qunit.css" ]); 21 | } 22 | }); 23 | 24 | }; 25 | 26 | module.exports.dependencies = [ 27 | "shelljs@0.2.6" 28 | ]; 29 | -------------------------------------------------------------------------------- /bower_components/qunit/external/jsdiff/jsdiff.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Javascript Diff Algorithm 3 | * By John Resig (http://ejohn.org/) 4 | * Modified by Chu Alan "sprite" 5 | * 6 | * Released under the MIT license. 7 | * 8 | * More Info: 9 | * http://ejohn.org/projects/javascript-diff-algorithm/ 10 | * 11 | * Usage: QUnit.diff(expected, actual) 12 | * 13 | * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick brown fox jumped jumps over" 14 | */ 15 | QUnit.diff = (function() { 16 | var hasOwn = Object.prototype.hasOwnProperty; 17 | 18 | /*jshint eqeqeq:false, eqnull:true */ 19 | function diff( o, n ) { 20 | var i, 21 | ns = {}, 22 | os = {}; 23 | 24 | for ( i = 0; i < n.length; i++ ) { 25 | if ( !hasOwn.call( ns, n[ i ] ) ) { 26 | ns[ n[ i ] ] = { 27 | rows: [], 28 | o: null 29 | }; 30 | } 31 | ns[ n[ i ] ].rows.push( i ); 32 | } 33 | 34 | for ( i = 0; i < o.length; i++ ) { 35 | if ( !hasOwn.call( os, o[ i ] ) ) { 36 | os[ o[ i ] ] = { 37 | rows: [], 38 | n: null 39 | }; 40 | } 41 | os[ o[ i ] ].rows.push( i ); 42 | } 43 | 44 | for ( i in ns ) { 45 | if ( hasOwn.call( ns, i ) ) { 46 | if ( ns[ i ].rows.length === 1 && hasOwn.call( os, i ) && os[ i ].rows.length === 1 ) { 47 | n[ ns[ i ].rows[ 0 ] ] = { 48 | text: n[ ns[ i ].rows[ 0 ] ], 49 | row: os[ i ].rows[ 0 ] 50 | }; 51 | o[ os[ i ].rows[ 0 ] ] = { 52 | text: o[ os[ i ].rows[ 0 ] ], 53 | row: ns[ i ].rows[ 0 ] 54 | }; 55 | } 56 | } 57 | } 58 | 59 | for ( i = 0; i < n.length - 1; i++ ) { 60 | if ( n[ i ].text != null && n[ i + 1 ].text == null && n[ i ].row + 1 < o.length && o[ n[ i ].row + 1 ].text == null && 61 | n[ i + 1 ] == o[ n[ i ].row + 1 ] ) { 62 | 63 | n[ i + 1 ] = { 64 | text: n[ i + 1 ], 65 | row: n[ i ].row + 1 66 | }; 67 | o[ n[ i ].row + 1 ] = { 68 | text: o[ n[ i ].row + 1 ], 69 | row: i + 1 70 | }; 71 | } 72 | } 73 | 74 | for ( i = n.length - 1; i > 0; i-- ) { 75 | if ( n[ i ].text != null && n[ i - 1 ].text == null && n[ i ].row > 0 && o[ n[ i ].row - 1 ].text == null && 76 | n[ i - 1 ] == o[ n[ i ].row - 1 ] ) { 77 | 78 | n[ i - 1 ] = { 79 | text: n[ i - 1 ], 80 | row: n[ i ].row - 1 81 | }; 82 | o[ n[ i ].row - 1 ] = { 83 | text: o[ n[ i ].row - 1 ], 84 | row: i - 1 85 | }; 86 | } 87 | } 88 | 89 | return { 90 | o: o, 91 | n: n 92 | }; 93 | } 94 | 95 | return function( o, n ) { 96 | o = o.replace( /\s+$/, "" ); 97 | n = n.replace( /\s+$/, "" ); 98 | 99 | var i, pre, 100 | str = "", 101 | out = diff( o === "" ? [] : o.split( /\s+/ ), n === "" ? [] : n.split( /\s+/ ) ), 102 | oSpace = o.match( /\s+/g ), 103 | nSpace = n.match( /\s+/g ); 104 | 105 | if ( oSpace == null ) { 106 | oSpace = [ " " ]; 107 | } else { 108 | oSpace.push( " " ); 109 | } 110 | 111 | if ( nSpace == null ) { 112 | nSpace = [ " " ]; 113 | } else { 114 | nSpace.push( " " ); 115 | } 116 | 117 | if ( out.n.length === 0 ) { 118 | for ( i = 0; i < out.o.length; i++ ) { 119 | str += "" + out.o[ i ] + oSpace[ i ] + ""; 120 | } 121 | } else { 122 | if ( out.n[ 0 ].text == null ) { 123 | for ( n = 0; n < out.o.length && out.o[ n ].text == null; n++ ) { 124 | str += "" + out.o[ n ] + oSpace[ n ] + ""; 125 | } 126 | } 127 | 128 | for ( i = 0; i < out.n.length; i++ ) { 129 | if ( out.n[ i ].text == null ) { 130 | str += "" + out.n[ i ] + nSpace[ i ] + ""; 131 | } else { 132 | 133 | // `pre` initialized at top of scope 134 | pre = ""; 135 | 136 | for ( n = out.n[ i ].row + 1; n < out.o.length && out.o[ n ].text == null; n++ ) { 137 | pre += "" + out.o[ n ] + oSpace[ n ] + ""; 138 | } 139 | str += " " + out.n[ i ].text + nSpace[ i ] + pre; 140 | } 141 | } 142 | } 143 | 144 | return str; 145 | }; 146 | }()); 147 | -------------------------------------------------------------------------------- /bower_components/qunit/qunit/qunit.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * QUnit 1.15.0 3 | * http://qunitjs.com/ 4 | * 5 | * Copyright 2014 jQuery Foundation and other contributors 6 | * Released under the MIT license 7 | * http://jquery.org/license 8 | * 9 | * Date: 2014-08-08T16:00Z 10 | */ 11 | 12 | /** Font Family and Sizes */ 13 | 14 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { 15 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; 16 | } 17 | 18 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } 19 | #qunit-tests { font-size: smaller; } 20 | 21 | 22 | /** Resets */ 23 | 24 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { 25 | margin: 0; 26 | padding: 0; 27 | } 28 | 29 | 30 | /** Header */ 31 | 32 | #qunit-header { 33 | padding: 0.5em 0 0.5em 1em; 34 | 35 | color: #8699A4; 36 | background-color: #0D3349; 37 | 38 | font-size: 1.5em; 39 | line-height: 1em; 40 | font-weight: 400; 41 | 42 | border-radius: 5px 5px 0 0; 43 | } 44 | 45 | #qunit-header a { 46 | text-decoration: none; 47 | color: #C2CCD1; 48 | } 49 | 50 | #qunit-header a:hover, 51 | #qunit-header a:focus { 52 | color: #FFF; 53 | } 54 | 55 | #qunit-testrunner-toolbar label { 56 | display: inline-block; 57 | padding: 0 0.5em 0 0.1em; 58 | } 59 | 60 | #qunit-banner { 61 | height: 5px; 62 | } 63 | 64 | #qunit-testrunner-toolbar { 65 | padding: 0.5em 1em 0.5em 1em; 66 | color: #5E740B; 67 | background-color: #EEE; 68 | overflow: hidden; 69 | } 70 | 71 | #qunit-userAgent { 72 | padding: 0.5em 1em 0.5em 1em; 73 | background-color: #2B81AF; 74 | color: #FFF; 75 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; 76 | } 77 | 78 | #qunit-modulefilter-container { 79 | float: right; 80 | } 81 | 82 | /** Tests: Pass/Fail */ 83 | 84 | #qunit-tests { 85 | list-style-position: inside; 86 | } 87 | 88 | #qunit-tests li { 89 | padding: 0.4em 1em 0.4em 1em; 90 | border-bottom: 1px solid #FFF; 91 | list-style-position: inside; 92 | } 93 | 94 | #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { 95 | display: none; 96 | } 97 | 98 | #qunit-tests li strong { 99 | cursor: pointer; 100 | } 101 | 102 | #qunit-tests li a { 103 | padding: 0.5em; 104 | color: #C2CCD1; 105 | text-decoration: none; 106 | } 107 | #qunit-tests li a:hover, 108 | #qunit-tests li a:focus { 109 | color: #000; 110 | } 111 | 112 | #qunit-tests li .runtime { 113 | float: right; 114 | font-size: smaller; 115 | } 116 | 117 | .qunit-assert-list { 118 | margin-top: 0.5em; 119 | padding: 0.5em; 120 | 121 | background-color: #FFF; 122 | 123 | border-radius: 5px; 124 | } 125 | 126 | .qunit-collapsed { 127 | display: none; 128 | } 129 | 130 | #qunit-tests table { 131 | border-collapse: collapse; 132 | margin-top: 0.2em; 133 | } 134 | 135 | #qunit-tests th { 136 | text-align: right; 137 | vertical-align: top; 138 | padding: 0 0.5em 0 0; 139 | } 140 | 141 | #qunit-tests td { 142 | vertical-align: top; 143 | } 144 | 145 | #qunit-tests pre { 146 | margin: 0; 147 | white-space: pre-wrap; 148 | word-wrap: break-word; 149 | } 150 | 151 | #qunit-tests del { 152 | background-color: #E0F2BE; 153 | color: #374E0C; 154 | text-decoration: none; 155 | } 156 | 157 | #qunit-tests ins { 158 | background-color: #FFCACA; 159 | color: #500; 160 | text-decoration: none; 161 | } 162 | 163 | /*** Test Counts */ 164 | 165 | #qunit-tests b.counts { color: #000; } 166 | #qunit-tests b.passed { color: #5E740B; } 167 | #qunit-tests b.failed { color: #710909; } 168 | 169 | #qunit-tests li li { 170 | padding: 5px; 171 | background-color: #FFF; 172 | border-bottom: none; 173 | list-style-position: inside; 174 | } 175 | 176 | /*** Passing Styles */ 177 | 178 | #qunit-tests li li.pass { 179 | color: #3C510C; 180 | background-color: #FFF; 181 | border-left: 10px solid #C6E746; 182 | } 183 | 184 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } 185 | #qunit-tests .pass .test-name { color: #366097; } 186 | 187 | #qunit-tests .pass .test-actual, 188 | #qunit-tests .pass .test-expected { color: #999; } 189 | 190 | #qunit-banner.qunit-pass { background-color: #C6E746; } 191 | 192 | /*** Failing Styles */ 193 | 194 | #qunit-tests li li.fail { 195 | color: #710909; 196 | background-color: #FFF; 197 | border-left: 10px solid #EE5757; 198 | white-space: pre; 199 | } 200 | 201 | #qunit-tests > li:last-child { 202 | border-radius: 0 0 5px 5px; 203 | } 204 | 205 | #qunit-tests .fail { color: #000; background-color: #EE5757; } 206 | #qunit-tests .fail .test-name, 207 | #qunit-tests .fail .module-name { color: #000; } 208 | 209 | #qunit-tests .fail .test-actual { color: #EE5757; } 210 | #qunit-tests .fail .test-expected { color: #008000; } 211 | 212 | #qunit-banner.qunit-fail { background-color: #EE5757; } 213 | 214 | 215 | /** Result */ 216 | 217 | #qunit-testresult { 218 | padding: 0.5em 1em 0.5em 1em; 219 | 220 | color: #2B81AF; 221 | background-color: #D2E0E6; 222 | 223 | border-bottom: 1px solid #FFF; 224 | } 225 | #qunit-testresult .module-name { 226 | font-weight: 700; 227 | } 228 | 229 | /** Fixture */ 230 | 231 | #qunit-fixture { 232 | position: absolute; 233 | top: -10000px; 234 | left: -10000px; 235 | width: 1000px; 236 | height: 1000px; 237 | } 238 | -------------------------------------------------------------------------------- /bower_components/qunit/reporter/html.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | // Deprecated QUnit.init - Ref #530 4 | // Re-initialize the configuration options 5 | QUnit.init = function() { 6 | var tests, banner, result, qunit, 7 | config = QUnit.config; 8 | 9 | config.stats = { all: 0, bad: 0 }; 10 | config.moduleStats = { all: 0, bad: 0 }; 11 | config.started = 0; 12 | config.updateRate = 1000; 13 | config.blocking = false; 14 | config.autostart = true; 15 | config.autorun = false; 16 | config.filter = ""; 17 | config.queue = []; 18 | config.semaphore = 1; 19 | 20 | // Return on non-browser environments 21 | // This is necessary to not break on node tests 22 | if ( typeof window === "undefined" ) { 23 | return; 24 | } 25 | 26 | qunit = id( "qunit" ); 27 | if ( qunit ) { 28 | qunit.innerHTML = 29 | "

" + escapeText( document.title ) + "

" + 30 | "

" + 31 | "
" + 32 | "

" + 33 | "
    "; 34 | } 35 | 36 | tests = id( "qunit-tests" ); 37 | banner = id( "qunit-banner" ); 38 | result = id( "qunit-testresult" ); 39 | 40 | if ( tests ) { 41 | tests.innerHTML = ""; 42 | } 43 | 44 | if ( banner ) { 45 | banner.className = ""; 46 | } 47 | 48 | if ( result ) { 49 | result.parentNode.removeChild( result ); 50 | } 51 | 52 | if ( tests ) { 53 | result = document.createElement( "p" ); 54 | result.id = "qunit-testresult"; 55 | result.className = "result"; 56 | tests.parentNode.insertBefore( result, tests ); 57 | result.innerHTML = "Running...
     "; 58 | } 59 | }; 60 | 61 | // Resets the test setup. Useful for tests that modify the DOM. 62 | /* 63 | DEPRECATED: Use multiple tests instead of resetting inside a test. 64 | Use testStart or testDone for custom cleanup. 65 | This method will throw an error in 2.0, and will be removed in 2.1 66 | */ 67 | QUnit.reset = function() { 68 | 69 | // Return on non-browser environments 70 | // This is necessary to not break on node tests 71 | if ( typeof window === "undefined" ) { 72 | return; 73 | } 74 | 75 | var fixture = id( "qunit-fixture" ); 76 | if ( fixture ) { 77 | fixture.innerHTML = config.fixture; 78 | } 79 | }; 80 | 81 | // Don't load the HTML Reporter on non-Browser environments 82 | if ( typeof window === "undefined" ) { 83 | return; 84 | } 85 | 86 | var config = QUnit.config, 87 | hasOwn = Object.prototype.hasOwnProperty, 88 | defined = { 89 | document: typeof window.document !== "undefined", 90 | sessionStorage: (function() { 91 | var x = "qunit-test-string"; 92 | try { 93 | sessionStorage.setItem( x, x ); 94 | sessionStorage.removeItem( x ); 95 | return true; 96 | } catch ( e ) { 97 | return false; 98 | } 99 | }()) 100 | }; 101 | 102 | /** 103 | * Escape text for attribute or text content. 104 | */ 105 | function escapeText( s ) { 106 | if ( !s ) { 107 | return ""; 108 | } 109 | s = s + ""; 110 | 111 | // Both single quotes and double quotes (for attributes) 112 | return s.replace( /['"<>&]/g, function( s ) { 113 | switch ( s ) { 114 | case "'": 115 | return "'"; 116 | case "\"": 117 | return """; 118 | case "<": 119 | return "<"; 120 | case ">": 121 | return ">"; 122 | case "&": 123 | return "&"; 124 | } 125 | }); 126 | } 127 | 128 | /** 129 | * @param {HTMLElement} elem 130 | * @param {string} type 131 | * @param {Function} fn 132 | */ 133 | function addEvent( elem, type, fn ) { 134 | if ( elem.addEventListener ) { 135 | 136 | // Standards-based browsers 137 | elem.addEventListener( type, fn, false ); 138 | } else if ( elem.attachEvent ) { 139 | 140 | // support: IE <9 141 | elem.attachEvent( "on" + type, fn ); 142 | } 143 | } 144 | 145 | /** 146 | * @param {Array|NodeList} elems 147 | * @param {string} type 148 | * @param {Function} fn 149 | */ 150 | function addEvents( elems, type, fn ) { 151 | var i = elems.length; 152 | while ( i-- ) { 153 | addEvent( elems[ i ], type, fn ); 154 | } 155 | } 156 | 157 | function hasClass( elem, name ) { 158 | return ( " " + elem.className + " " ).indexOf( " " + name + " " ) >= 0; 159 | } 160 | 161 | function addClass( elem, name ) { 162 | if ( !hasClass( elem, name ) ) { 163 | elem.className += ( elem.className ? " " : "" ) + name; 164 | } 165 | } 166 | 167 | function toggleClass( elem, name ) { 168 | if ( hasClass( elem, name ) ) { 169 | removeClass( elem, name ); 170 | } else { 171 | addClass( elem, name ); 172 | } 173 | } 174 | 175 | function removeClass( elem, name ) { 176 | var set = " " + elem.className + " "; 177 | 178 | // Class name may appear multiple times 179 | while ( set.indexOf( " " + name + " " ) >= 0 ) { 180 | set = set.replace( " " + name + " ", " " ); 181 | } 182 | 183 | // trim for prettiness 184 | elem.className = typeof set.trim === "function" ? set.trim() : set.replace( /^\s+|\s+$/g, "" ); 185 | } 186 | 187 | function id( name ) { 188 | return defined.document && document.getElementById && document.getElementById( name ); 189 | } 190 | 191 | function getUrlConfigHtml() { 192 | var i, j, val, 193 | escaped, escapedTooltip, 194 | selection = false, 195 | len = config.urlConfig.length, 196 | urlConfigHtml = ""; 197 | 198 | for ( i = 0; i < len; i++ ) { 199 | val = config.urlConfig[ i ]; 200 | if ( typeof val === "string" ) { 201 | val = { 202 | id: val, 203 | label: val 204 | }; 205 | } 206 | 207 | escaped = escapeText( val.id ); 208 | escapedTooltip = escapeText( val.tooltip ); 209 | 210 | config[ val.id ] = QUnit.urlParams[ val.id ]; 211 | if ( !val.value || typeof val.value === "string" ) { 212 | urlConfigHtml += ""; 218 | } else { 219 | urlConfigHtml += ""; 248 | } 249 | } 250 | 251 | return urlConfigHtml; 252 | } 253 | 254 | function toolbarUrlConfigContainer() { 255 | var urlConfigContainer = document.createElement( "span" ); 256 | 257 | urlConfigContainer.innerHTML = getUrlConfigHtml(); 258 | 259 | // For oldIE support: 260 | // * Add handlers to the individual elements instead of the container 261 | // * Use "click" instead of "change" for checkboxes 262 | // * Fallback from event.target to event.srcElement 263 | addEvents( urlConfigContainer.getElementsByTagName( "input" ), "click", function( event ) { 264 | var params = {}, 265 | target = event.target || event.srcElement; 266 | params[ target.name ] = target.checked ? 267 | target.defaultValue || true : 268 | undefined; 269 | window.location = QUnit.url( params ); 270 | }); 271 | addEvents( urlConfigContainer.getElementsByTagName( "select" ), "change", function( event ) { 272 | var params = {}, 273 | target = event.target || event.srcElement; 274 | params[ target.name ] = target.options[ target.selectedIndex ].value || undefined; 275 | window.location = QUnit.url( params ); 276 | }); 277 | 278 | return urlConfigContainer; 279 | } 280 | 281 | function getModuleNames() { 282 | var i, 283 | moduleNames = []; 284 | 285 | for ( i in config.modules ) { 286 | if ( config.modules.hasOwnProperty( i ) ) { 287 | moduleNames.push( i ); 288 | } 289 | } 290 | 291 | moduleNames.sort(function( a, b ) { 292 | return a.localeCompare( b ); 293 | }); 294 | 295 | return moduleNames; 296 | } 297 | 298 | function toolbarModuleFilterHtml() { 299 | var i, 300 | moduleFilterHtml = "", 301 | moduleNames = getModuleNames(); 302 | 303 | if ( moduleNames.length <= 1 ) { 304 | return false; 305 | } 306 | 307 | moduleFilterHtml += "" + 308 | ""; 319 | 320 | return moduleFilterHtml; 321 | } 322 | 323 | function toolbarModuleFilter() { 324 | var moduleFilter = document.createElement( "span" ), 325 | moduleFilterHtml = toolbarModuleFilterHtml(); 326 | 327 | if ( !moduleFilterHtml ) { 328 | return false; 329 | } 330 | 331 | moduleFilter.setAttribute( "id", "qunit-modulefilter-container" ); 332 | moduleFilter.innerHTML = moduleFilterHtml; 333 | 334 | addEvent( moduleFilter.lastChild, "change", function() { 335 | var selectBox = moduleFilter.getElementsByTagName( "select" )[ 0 ], 336 | selectedModule = decodeURIComponent( selectBox.options[ selectBox.selectedIndex ].value ); 337 | 338 | window.location = QUnit.url({ 339 | module: ( selectedModule === "" ) ? undefined : selectedModule, 340 | 341 | // Remove any existing filters 342 | filter: undefined, 343 | testNumber: undefined 344 | }); 345 | }); 346 | 347 | return moduleFilter; 348 | } 349 | 350 | function toolbarFilter() { 351 | var testList = id( "qunit-tests" ), 352 | filter = document.createElement( "input" ); 353 | 354 | filter.type = "checkbox"; 355 | filter.id = "qunit-filter-pass"; 356 | 357 | addEvent( filter, "click", function() { 358 | if ( filter.checked ) { 359 | addClass( testList, "hidepass" ); 360 | if ( defined.sessionStorage ) { 361 | sessionStorage.setItem( "qunit-filter-passed-tests", "true" ); 362 | } 363 | } else { 364 | removeClass( testList, "hidepass" ); 365 | if ( defined.sessionStorage ) { 366 | sessionStorage.removeItem( "qunit-filter-passed-tests" ); 367 | } 368 | } 369 | }); 370 | 371 | if ( config.hidepassed || defined.sessionStorage && 372 | sessionStorage.getItem( "qunit-filter-passed-tests" ) ) { 373 | filter.checked = true; 374 | 375 | addClass( testList, "hidepass" ); 376 | } 377 | 378 | return filter; 379 | } 380 | 381 | function toolbarLabel() { 382 | var label = document.createElement( "label" ); 383 | label.setAttribute( "for", "qunit-filter-pass" ); 384 | label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." ); 385 | label.innerHTML = "Hide passed tests"; 386 | 387 | return label; 388 | } 389 | 390 | function appendToolbar() { 391 | var moduleFilter, 392 | toolbar = id( "qunit-testrunner-toolbar" ); 393 | 394 | if ( toolbar ) { 395 | toolbar.appendChild( toolbarFilter() ); 396 | toolbar.appendChild( toolbarLabel() ); 397 | toolbar.appendChild( toolbarUrlConfigContainer() ); 398 | 399 | moduleFilter = toolbarModuleFilter(); 400 | if ( moduleFilter ) { 401 | toolbar.appendChild( moduleFilter ); 402 | } 403 | } 404 | } 405 | 406 | function appendBanner() { 407 | var banner = id( "qunit-banner" ); 408 | 409 | if ( banner ) { 410 | banner.className = ""; 411 | banner.innerHTML = "" + banner.innerHTML + " "; 414 | } 415 | } 416 | 417 | function appendTestResults() { 418 | var tests = id( "qunit-tests" ), 419 | result = id( "qunit-testresult" ); 420 | 421 | if ( result ) { 422 | result.parentNode.removeChild( result ); 423 | } 424 | 425 | if ( tests ) { 426 | tests.innerHTML = ""; 427 | result = document.createElement( "p" ); 428 | result.id = "qunit-testresult"; 429 | result.className = "result"; 430 | tests.parentNode.insertBefore( result, tests ); 431 | result.innerHTML = "Running...
     "; 432 | } 433 | } 434 | 435 | function storeFixture() { 436 | var fixture = id( "qunit-fixture" ); 437 | if ( fixture ) { 438 | config.fixture = fixture.innerHTML; 439 | } 440 | } 441 | 442 | function appendUserAgent() { 443 | var userAgent = id( "qunit-userAgent" ); 444 | if ( userAgent ) { 445 | userAgent.innerHTML = navigator.userAgent; 446 | } 447 | } 448 | 449 | // HTML Reporter initialization and load 450 | QUnit.begin(function() { 451 | var qunit = id( "qunit" ); 452 | 453 | if ( qunit ) { 454 | qunit.innerHTML = 455 | "

    " + escapeText( document.title ) + "

    " + 456 | "

    " + 457 | "
    " + 458 | "

    " + 459 | "
      "; 460 | } 461 | 462 | appendBanner(); 463 | appendTestResults(); 464 | appendUserAgent(); 465 | appendToolbar(); 466 | storeFixture(); 467 | }); 468 | 469 | QUnit.done(function( details ) { 470 | var i, key, 471 | banner = id( "qunit-banner" ), 472 | tests = id( "qunit-tests" ), 473 | html = [ 474 | "Tests completed in ", 475 | details.runtime, 476 | " milliseconds.
      ", 477 | "", 478 | details.passed, 479 | " assertions of ", 480 | details.total, 481 | " passed, ", 482 | details.failed, 483 | " failed." 484 | ].join( "" ); 485 | 486 | if ( banner ) { 487 | banner.className = details.failed ? "qunit-fail" : "qunit-pass"; 488 | } 489 | 490 | if ( tests ) { 491 | id( "qunit-testresult" ).innerHTML = html; 492 | } 493 | 494 | if ( config.altertitle && defined.document && document.title ) { 495 | 496 | // show ✖ for good, ✔ for bad suite result in title 497 | // use escape sequences in case file gets loaded with non-utf-8-charset 498 | document.title = [ 499 | ( details.failed ? "\u2716" : "\u2714" ), 500 | document.title.replace( /^[\u2714\u2716] /i, "" ) 501 | ].join( " " ); 502 | } 503 | 504 | // clear own sessionStorage items if all tests passed 505 | if ( config.reorder && defined.sessionStorage && details.failed === 0 ) { 506 | for ( i = 0; i < sessionStorage.length; i++ ) { 507 | key = sessionStorage.key( i++ ); 508 | if ( key.indexOf( "qunit-test-" ) === 0 ) { 509 | sessionStorage.removeItem( key ); 510 | } 511 | } 512 | } 513 | 514 | // scroll back to top to show results 515 | if ( config.scrolltop && window.scrollTo ) { 516 | window.scrollTo( 0, 0 ); 517 | } 518 | }); 519 | 520 | function getNameHtml( name, module ) { 521 | var nameHtml = ""; 522 | 523 | if ( module ) { 524 | nameHtml = "" + escapeText( module ) + ": "; 525 | } 526 | 527 | nameHtml += "" + escapeText( name ) + ""; 528 | 529 | return nameHtml; 530 | } 531 | 532 | QUnit.testStart(function( details ) { 533 | var a, b, li, running, assertList, 534 | name = getNameHtml( details.name, details.module ), 535 | tests = id( "qunit-tests" ); 536 | 537 | if ( tests ) { 538 | b = document.createElement( "strong" ); 539 | b.innerHTML = name; 540 | 541 | a = document.createElement( "a" ); 542 | a.innerHTML = "Rerun"; 543 | a.href = QUnit.url({ testNumber: details.testNumber }); 544 | 545 | li = document.createElement( "li" ); 546 | li.appendChild( b ); 547 | li.appendChild( a ); 548 | li.className = "running"; 549 | li.id = "qunit-test-output" + details.testNumber; 550 | 551 | assertList = document.createElement( "ol" ); 552 | assertList.className = "qunit-assert-list"; 553 | 554 | li.appendChild( assertList ); 555 | 556 | tests.appendChild( li ); 557 | } 558 | 559 | running = id( "qunit-testresult" ); 560 | if ( running ) { 561 | running.innerHTML = "Running:
      " + name; 562 | } 563 | 564 | }); 565 | 566 | QUnit.log(function( details ) { 567 | var assertList, assertLi, 568 | message, expected, actual, 569 | testItem = id( "qunit-test-output" + details.testNumber ); 570 | 571 | if ( !testItem ) { 572 | return; 573 | } 574 | 575 | message = escapeText( details.message ) || ( details.result ? "okay" : "failed" ); 576 | message = "" + message + ""; 577 | 578 | // pushFailure doesn't provide details.expected 579 | // when it calls, it's implicit to also not show expected and diff stuff 580 | // Also, we need to check details.expected existence, as it can exist and be undefined 581 | if ( !details.result && hasOwn.call( details, "expected" ) ) { 582 | expected = escapeText( QUnit.dump.parse( details.expected ) ); 583 | actual = escapeText( QUnit.dump.parse( details.actual ) ); 584 | message += ""; 587 | 588 | if ( actual !== expected ) { 589 | message += "" + 591 | ""; 593 | } 594 | 595 | if ( details.source ) { 596 | message += ""; 598 | } 599 | 600 | message += "
      Expected:
      " +
      585 | 			expected +
      586 | 			"
      Result:
      " +
      590 | 				actual + "
      Diff:
      " +
      592 | 				QUnit.diff( expected, actual ) + "
      Source:
      " +
      597 | 				escapeText( details.source ) + "
      "; 601 | 602 | // this occours when pushFailure is set and we have an extracted stack trace 603 | } else if ( !details.result && details.source ) { 604 | message += "" + 605 | "" + 607 | "
      Source:
      " +
      606 | 			escapeText( details.source ) + "
      "; 608 | } 609 | 610 | assertList = testItem.getElementsByTagName( "ol" )[ 0 ]; 611 | 612 | assertLi = document.createElement( "li" ); 613 | assertLi.className = details.result ? "pass" : "fail"; 614 | assertLi.innerHTML = message; 615 | assertList.appendChild( assertLi ); 616 | }); 617 | 618 | QUnit.testDone(function( details ) { 619 | var testTitle, time, testItem, assertList, 620 | good, bad, testCounts, 621 | tests = id( "qunit-tests" ); 622 | 623 | // QUnit.reset() is deprecated and will be replaced for a new 624 | // fixture reset function on QUnit 2.0/2.1. 625 | // It's still called here for backwards compatibility handling 626 | QUnit.reset(); 627 | 628 | if ( !tests ) { 629 | return; 630 | } 631 | 632 | testItem = id( "qunit-test-output" + details.testNumber ); 633 | assertList = testItem.getElementsByTagName( "ol" )[ 0 ]; 634 | 635 | good = details.passed; 636 | bad = details.failed; 637 | 638 | // store result when possible 639 | if ( config.reorder && defined.sessionStorage ) { 640 | if ( bad ) { 641 | sessionStorage.setItem( "qunit-test-" + details.module + "-" + details.name, bad ); 642 | } else { 643 | sessionStorage.removeItem( "qunit-test-" + details.module + "-" + details.name ); 644 | } 645 | } 646 | 647 | if ( bad === 0 ) { 648 | addClass( assertList, "qunit-collapsed" ); 649 | } 650 | 651 | // testItem.firstChild is the test name 652 | testTitle = testItem.firstChild; 653 | 654 | testCounts = bad ? 655 | "" + bad + ", " + "" + good + ", " : 656 | ""; 657 | 658 | testTitle.innerHTML += " (" + testCounts + 659 | details.assertions.length + ")"; 660 | 661 | addEvent( testTitle, "click", function() { 662 | toggleClass( assertList, "qunit-collapsed" ); 663 | }); 664 | 665 | time = document.createElement( "span" ); 666 | time.className = "runtime"; 667 | time.innerHTML = details.runtime + " ms"; 668 | 669 | testItem.className = bad ? "fail" : "pass"; 670 | 671 | testItem.insertBefore( time, assertList ); 672 | }); 673 | 674 | if ( !defined.document || document.readyState === "complete" ) { 675 | config.autorun = true; 676 | } 677 | 678 | if ( defined.document ) { 679 | addEvent( window, "load", QUnit.load ); 680 | } 681 | 682 | })(); 683 | -------------------------------------------------------------------------------- /bower_components/qunit/src/assert.js: -------------------------------------------------------------------------------- 1 | function Assert( testContext ) { 2 | this.test = testContext; 3 | } 4 | 5 | // Assert helpers 6 | QUnit.assert = Assert.prototype = { 7 | 8 | // Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through. 9 | expect: function( asserts ) { 10 | if ( arguments.length === 1 ) { 11 | this.test.expected = asserts; 12 | } else { 13 | return this.test.expected; 14 | } 15 | }, 16 | 17 | // Exports test.push() to the user API 18 | push: function() { 19 | var assert = this; 20 | 21 | // Backwards compatibility fix. 22 | // Allows the direct use of global exported assertions and QUnit.assert.* 23 | // Although, it's use is not recommended as it can leak assertions 24 | // to other tests from async tests, because we only get a reference to the current test, 25 | // not exactly the test where assertion were intended to be called. 26 | if ( !QUnit.config.current ) { 27 | throw new Error( "assertion outside test context, in " + sourceFromStacktrace( 2 ) ); 28 | } 29 | if ( !( assert instanceof Assert ) ) { 30 | assert = QUnit.config.current.assert; 31 | } 32 | return assert.test.push.apply( assert.test, arguments ); 33 | }, 34 | 35 | /** 36 | * Asserts rough true-ish result. 37 | * @name ok 38 | * @function 39 | * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); 40 | */ 41 | ok: function( result, message ) { 42 | message = message || ( result ? "okay" : "failed, expected argument to be truthy, was: " + 43 | QUnit.dump.parse( result ) ); 44 | if ( !!result ) { 45 | this.push( true, result, true, message ); 46 | } else { 47 | this.test.pushFailure( message, null, result ); 48 | } 49 | }, 50 | 51 | /** 52 | * Assert that the first two arguments are equal, with an optional message. 53 | * Prints out both actual and expected values. 54 | * @name equal 55 | * @function 56 | * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); 57 | */ 58 | equal: function( actual, expected, message ) { 59 | /*jshint eqeqeq:false */ 60 | this.push( expected == actual, actual, expected, message ); 61 | }, 62 | 63 | /** 64 | * @name notEqual 65 | * @function 66 | */ 67 | notEqual: function( actual, expected, message ) { 68 | /*jshint eqeqeq:false */ 69 | this.push( expected != actual, actual, expected, message ); 70 | }, 71 | 72 | /** 73 | * @name propEqual 74 | * @function 75 | */ 76 | propEqual: function( actual, expected, message ) { 77 | actual = objectValues( actual ); 78 | expected = objectValues( expected ); 79 | this.push( QUnit.equiv( actual, expected ), actual, expected, message ); 80 | }, 81 | 82 | /** 83 | * @name notPropEqual 84 | * @function 85 | */ 86 | notPropEqual: function( actual, expected, message ) { 87 | actual = objectValues( actual ); 88 | expected = objectValues( expected ); 89 | this.push( !QUnit.equiv( actual, expected ), actual, expected, message ); 90 | }, 91 | 92 | /** 93 | * @name deepEqual 94 | * @function 95 | */ 96 | deepEqual: function( actual, expected, message ) { 97 | this.push( QUnit.equiv( actual, expected ), actual, expected, message ); 98 | }, 99 | 100 | /** 101 | * @name notDeepEqual 102 | * @function 103 | */ 104 | notDeepEqual: function( actual, expected, message ) { 105 | this.push( !QUnit.equiv( actual, expected ), actual, expected, message ); 106 | }, 107 | 108 | /** 109 | * @name strictEqual 110 | * @function 111 | */ 112 | strictEqual: function( actual, expected, message ) { 113 | this.push( expected === actual, actual, expected, message ); 114 | }, 115 | 116 | /** 117 | * @name notStrictEqual 118 | * @function 119 | */ 120 | notStrictEqual: function( actual, expected, message ) { 121 | this.push( expected !== actual, actual, expected, message ); 122 | }, 123 | 124 | "throws": function( block, expected, message ) { 125 | var actual, expectedType, 126 | expectedOutput = expected, 127 | ok = false; 128 | 129 | // 'expected' is optional unless doing string comparison 130 | if ( message == null && typeof expected === "string" ) { 131 | message = expected; 132 | expected = null; 133 | } 134 | 135 | this.test.ignoreGlobalErrors = true; 136 | try { 137 | block.call( this.test.testEnvironment ); 138 | } catch (e) { 139 | actual = e; 140 | } 141 | this.test.ignoreGlobalErrors = false; 142 | 143 | if ( actual ) { 144 | expectedType = QUnit.objectType( expected ); 145 | 146 | // we don't want to validate thrown error 147 | if ( !expected ) { 148 | ok = true; 149 | expectedOutput = null; 150 | 151 | // expected is a regexp 152 | } else if ( expectedType === "regexp" ) { 153 | ok = expected.test( errorString( actual ) ); 154 | 155 | // expected is a string 156 | } else if ( expectedType === "string" ) { 157 | ok = expected === errorString( actual ); 158 | 159 | // expected is a constructor, maybe an Error constructor 160 | } else if ( expectedType === "function" && actual instanceof expected ) { 161 | ok = true; 162 | 163 | // expected is an Error object 164 | } else if ( expectedType === "object" ) { 165 | ok = actual instanceof expected.constructor && 166 | actual.name === expected.name && 167 | actual.message === expected.message; 168 | 169 | // expected is a validation function which returns true if validation passed 170 | } else if ( expectedType === "function" && expected.call( {}, actual ) === true ) { 171 | expectedOutput = null; 172 | ok = true; 173 | } 174 | 175 | this.push( ok, actual, expectedOutput, message ); 176 | } else { 177 | this.test.pushFailure( message, null, "No exception was thrown." ); 178 | } 179 | } 180 | }; 181 | -------------------------------------------------------------------------------- /bower_components/qunit/src/core.js: -------------------------------------------------------------------------------- 1 | var QUnit, 2 | config, 3 | onErrorFnPrev, 4 | fileName = ( sourceFromStacktrace( 0 ) || "" ).replace( /(:\d+)+\)?/, "" ).replace( /.+\//, "" ), 5 | toString = Object.prototype.toString, 6 | hasOwn = Object.prototype.hasOwnProperty, 7 | // Keep a local reference to Date (GH-283) 8 | Date = window.Date, 9 | now = Date.now || function() { 10 | return new Date().getTime(); 11 | }, 12 | setTimeout = window.setTimeout, 13 | clearTimeout = window.clearTimeout, 14 | defined = { 15 | document: typeof window.document !== "undefined", 16 | setTimeout: typeof window.setTimeout !== "undefined", 17 | sessionStorage: (function() { 18 | var x = "qunit-test-string"; 19 | try { 20 | sessionStorage.setItem( x, x ); 21 | sessionStorage.removeItem( x ); 22 | return true; 23 | } catch ( e ) { 24 | return false; 25 | } 26 | }()) 27 | }, 28 | /** 29 | * Provides a normalized error string, correcting an issue 30 | * with IE 7 (and prior) where Error.prototype.toString is 31 | * not properly implemented 32 | * 33 | * Based on http://es5.github.com/#x15.11.4.4 34 | * 35 | * @param {String|Error} error 36 | * @return {String} error message 37 | */ 38 | errorString = function( error ) { 39 | var name, message, 40 | errorString = error.toString(); 41 | if ( errorString.substring( 0, 7 ) === "[object" ) { 42 | name = error.name ? error.name.toString() : "Error"; 43 | message = error.message ? error.message.toString() : ""; 44 | if ( name && message ) { 45 | return name + ": " + message; 46 | } else if ( name ) { 47 | return name; 48 | } else if ( message ) { 49 | return message; 50 | } else { 51 | return "Error"; 52 | } 53 | } else { 54 | return errorString; 55 | } 56 | }, 57 | /** 58 | * Makes a clone of an object using only Array or Object as base, 59 | * and copies over the own enumerable properties. 60 | * 61 | * @param {Object} obj 62 | * @return {Object} New object with only the own properties (recursively). 63 | */ 64 | objectValues = function( obj ) { 65 | var key, val, 66 | vals = QUnit.is( "array", obj ) ? [] : {}; 67 | for ( key in obj ) { 68 | if ( hasOwn.call( obj, key ) ) { 69 | val = obj[ key ]; 70 | vals[ key ] = val === Object( val ) ? objectValues( val ) : val; 71 | } 72 | } 73 | return vals; 74 | }; 75 | 76 | // Root QUnit object. 77 | // `QUnit` initialized at top of scope 78 | QUnit = { 79 | 80 | // call on start of module test to prepend name to all tests 81 | module: function( name, testEnvironment ) { 82 | config.currentModule = name; 83 | config.currentModuleTestEnvironment = testEnvironment; 84 | config.modules[ name ] = true; 85 | }, 86 | 87 | asyncTest: function( testName, expected, callback ) { 88 | if ( arguments.length === 2 ) { 89 | callback = expected; 90 | expected = null; 91 | } 92 | 93 | QUnit.test( testName, expected, callback, true ); 94 | }, 95 | 96 | test: function( testName, expected, callback, async ) { 97 | var test; 98 | 99 | if ( arguments.length === 2 ) { 100 | callback = expected; 101 | expected = null; 102 | } 103 | 104 | test = new Test({ 105 | testName: testName, 106 | expected: expected, 107 | async: async, 108 | callback: callback, 109 | module: config.currentModule, 110 | moduleTestEnvironment: config.currentModuleTestEnvironment, 111 | stack: sourceFromStacktrace( 2 ) 112 | }); 113 | 114 | if ( !validTest( test ) ) { 115 | return; 116 | } 117 | 118 | test.queue(); 119 | }, 120 | 121 | start: function( count ) { 122 | var message; 123 | 124 | // QUnit hasn't been initialized yet. 125 | // Note: RequireJS (et al) may delay onLoad 126 | if ( config.semaphore === undefined ) { 127 | QUnit.begin(function() { 128 | // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first 129 | setTimeout(function() { 130 | QUnit.start( count ); 131 | }); 132 | }); 133 | return; 134 | } 135 | 136 | config.semaphore -= count || 1; 137 | // don't start until equal number of stop-calls 138 | if ( config.semaphore > 0 ) { 139 | return; 140 | } 141 | 142 | // Set the starting time when the first test is run 143 | QUnit.config.started = QUnit.config.started || now(); 144 | // ignore if start is called more often then stop 145 | if ( config.semaphore < 0 ) { 146 | config.semaphore = 0; 147 | 148 | message = "Called start() while already started (QUnit.config.semaphore was 0 already)"; 149 | 150 | if ( config.current ) { 151 | QUnit.pushFailure( message, sourceFromStacktrace( 2 ) ); 152 | } else { 153 | throw new Error( message ); 154 | } 155 | 156 | return; 157 | } 158 | // A slight delay, to avoid any current callbacks 159 | if ( defined.setTimeout ) { 160 | setTimeout(function() { 161 | if ( config.semaphore > 0 ) { 162 | return; 163 | } 164 | if ( config.timeout ) { 165 | clearTimeout( config.timeout ); 166 | } 167 | 168 | config.blocking = false; 169 | process( true ); 170 | }, 13 ); 171 | } else { 172 | config.blocking = false; 173 | process( true ); 174 | } 175 | }, 176 | 177 | stop: function( count ) { 178 | config.semaphore += count || 1; 179 | config.blocking = true; 180 | 181 | if ( config.testTimeout && defined.setTimeout ) { 182 | clearTimeout( config.timeout ); 183 | config.timeout = setTimeout(function() { 184 | QUnit.ok( false, "Test timed out" ); 185 | config.semaphore = 1; 186 | QUnit.start(); 187 | }, config.testTimeout ); 188 | } 189 | } 190 | }; 191 | 192 | // We use the prototype to distinguish between properties that should 193 | // be exposed as globals (and in exports) and those that shouldn't 194 | (function() { 195 | function F() {} 196 | F.prototype = QUnit; 197 | QUnit = new F(); 198 | 199 | // Make F QUnit's constructor so that we can add to the prototype later 200 | QUnit.constructor = F; 201 | }()); 202 | 203 | /** 204 | * Config object: Maintain internal state 205 | * Later exposed as QUnit.config 206 | * `config` initialized at top of scope 207 | */ 208 | config = { 209 | // The queue of tests to run 210 | queue: [], 211 | 212 | // block until document ready 213 | blocking: true, 214 | 215 | // when enabled, show only failing tests 216 | // gets persisted through sessionStorage and can be changed in UI via checkbox 217 | hidepassed: false, 218 | 219 | // by default, run previously failed tests first 220 | // very useful in combination with "Hide passed tests" checked 221 | reorder: true, 222 | 223 | // by default, modify document.title when suite is done 224 | altertitle: true, 225 | 226 | // by default, scroll to top of the page when suite is done 227 | scrolltop: true, 228 | 229 | // when enabled, all tests must call expect() 230 | requireExpects: false, 231 | 232 | // add checkboxes that are persisted in the query-string 233 | // when enabled, the id is set to `true` as a `QUnit.config` property 234 | urlConfig: [ 235 | { 236 | id: "noglobals", 237 | label: "Check for Globals", 238 | tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings." 239 | }, 240 | { 241 | id: "notrycatch", 242 | label: "No try-catch", 243 | tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings." 244 | } 245 | ], 246 | 247 | // Set of all modules. 248 | modules: {}, 249 | 250 | callbacks: {} 251 | }; 252 | 253 | // Initialize more QUnit.config and QUnit.urlParams 254 | (function() { 255 | var i, current, 256 | location = window.location || { search: "", protocol: "file:" }, 257 | params = location.search.slice( 1 ).split( "&" ), 258 | length = params.length, 259 | urlParams = {}; 260 | 261 | if ( params[ 0 ] ) { 262 | for ( i = 0; i < length; i++ ) { 263 | current = params[ i ].split( "=" ); 264 | current[ 0 ] = decodeURIComponent( current[ 0 ] ); 265 | 266 | // allow just a key to turn on a flag, e.g., test.html?noglobals 267 | current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; 268 | if ( urlParams[ current[ 0 ] ] ) { 269 | urlParams[ current[ 0 ] ] = [].concat( urlParams[ current[ 0 ] ], current[ 1 ] ); 270 | } else { 271 | urlParams[ current[ 0 ] ] = current[ 1 ]; 272 | } 273 | } 274 | } 275 | 276 | QUnit.urlParams = urlParams; 277 | 278 | // String search anywhere in moduleName+testName 279 | config.filter = urlParams.filter; 280 | 281 | // Exact match of the module name 282 | config.module = urlParams.module; 283 | 284 | config.testNumber = []; 285 | if ( urlParams.testNumber ) { 286 | 287 | // Ensure that urlParams.testNumber is an array 288 | urlParams.testNumber = [].concat( urlParams.testNumber ); 289 | for ( i = 0; i < urlParams.testNumber.length; i++ ) { 290 | current = urlParams.testNumber[ i ]; 291 | config.testNumber.push( parseInt( current, 10 ) ); 292 | } 293 | } 294 | 295 | // Figure out if we're running the tests from a server or not 296 | QUnit.isLocal = location.protocol === "file:"; 297 | }()); 298 | 299 | extend( QUnit, { 300 | 301 | config: config, 302 | 303 | // Safe object type checking 304 | is: function( type, obj ) { 305 | return QUnit.objectType( obj ) === type; 306 | }, 307 | 308 | objectType: function( obj ) { 309 | if ( typeof obj === "undefined" ) { 310 | return "undefined"; 311 | } 312 | 313 | // Consider: typeof null === object 314 | if ( obj === null ) { 315 | return "null"; 316 | } 317 | 318 | var match = toString.call( obj ).match( /^\[object\s(.*)\]$/ ), 319 | type = match && match[ 1 ] || ""; 320 | 321 | switch ( type ) { 322 | case "Number": 323 | if ( isNaN( obj ) ) { 324 | return "nan"; 325 | } 326 | return "number"; 327 | case "String": 328 | case "Boolean": 329 | case "Array": 330 | case "Date": 331 | case "RegExp": 332 | case "Function": 333 | return type.toLowerCase(); 334 | } 335 | if ( typeof obj === "object" ) { 336 | return "object"; 337 | } 338 | return undefined; 339 | }, 340 | 341 | url: function( params ) { 342 | params = extend( extend( {}, QUnit.urlParams ), params ); 343 | var key, 344 | querystring = "?"; 345 | 346 | for ( key in params ) { 347 | if ( hasOwn.call( params, key ) ) { 348 | querystring += encodeURIComponent( key ) + "=" + 349 | encodeURIComponent( params[ key ] ) + "&"; 350 | } 351 | } 352 | return window.location.protocol + "//" + window.location.host + 353 | window.location.pathname + querystring.slice( 0, -1 ); 354 | }, 355 | 356 | extend: extend 357 | }); 358 | 359 | /** 360 | * @deprecated: Created for backwards compatibility with test runner that set the hook function 361 | * into QUnit.{hook}, instead of invoking it and passing the hook function. 362 | * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here. 363 | * Doing this allows us to tell if the following methods have been overwritten on the actual 364 | * QUnit object. 365 | */ 366 | extend( QUnit.constructor.prototype, { 367 | 368 | // Logging callbacks; all receive a single argument with the listed properties 369 | // run test/logs.html for any related changes 370 | begin: registerLoggingCallback( "begin" ), 371 | 372 | // done: { failed, passed, total, runtime } 373 | done: registerLoggingCallback( "done" ), 374 | 375 | // log: { result, actual, expected, message } 376 | log: registerLoggingCallback( "log" ), 377 | 378 | // testStart: { name } 379 | testStart: registerLoggingCallback( "testStart" ), 380 | 381 | // testDone: { name, failed, passed, total, runtime } 382 | testDone: registerLoggingCallback( "testDone" ), 383 | 384 | // moduleStart: { name } 385 | moduleStart: registerLoggingCallback( "moduleStart" ), 386 | 387 | // moduleDone: { name, failed, passed, total } 388 | moduleDone: registerLoggingCallback( "moduleDone" ) 389 | }); 390 | 391 | QUnit.load = function() { 392 | runLoggingCallbacks( "begin", { 393 | totalTests: Test.count 394 | }); 395 | 396 | // Initialize the configuration options 397 | extend( config, { 398 | stats: { all: 0, bad: 0 }, 399 | moduleStats: { all: 0, bad: 0 }, 400 | started: 0, 401 | updateRate: 1000, 402 | autostart: true, 403 | filter: "", 404 | semaphore: 1 405 | }, true ); 406 | 407 | config.blocking = false; 408 | 409 | if ( config.autostart ) { 410 | QUnit.start(); 411 | } 412 | }; 413 | 414 | // `onErrorFnPrev` initialized at top of scope 415 | // Preserve other handlers 416 | onErrorFnPrev = window.onerror; 417 | 418 | // Cover uncaught exceptions 419 | // Returning true will suppress the default browser handler, 420 | // returning false will let it run. 421 | window.onerror = function( error, filePath, linerNr ) { 422 | var ret = false; 423 | if ( onErrorFnPrev ) { 424 | ret = onErrorFnPrev( error, filePath, linerNr ); 425 | } 426 | 427 | // Treat return value as window.onerror itself does, 428 | // Only do our handling if not suppressed. 429 | if ( ret !== true ) { 430 | if ( QUnit.config.current ) { 431 | if ( QUnit.config.current.ignoreGlobalErrors ) { 432 | return true; 433 | } 434 | QUnit.pushFailure( error, filePath + ":" + linerNr ); 435 | } else { 436 | QUnit.test( "global failure", extend(function() { 437 | QUnit.pushFailure( error, filePath + ":" + linerNr ); 438 | }, { validTest: validTest } ) ); 439 | } 440 | return false; 441 | } 442 | 443 | return ret; 444 | }; 445 | 446 | function done() { 447 | config.autorun = true; 448 | 449 | // Log the last module results 450 | if ( config.previousModule ) { 451 | runLoggingCallbacks( "moduleDone", { 452 | name: config.previousModule, 453 | failed: config.moduleStats.bad, 454 | passed: config.moduleStats.all - config.moduleStats.bad, 455 | total: config.moduleStats.all 456 | }); 457 | } 458 | delete config.previousModule; 459 | 460 | var runtime = now() - config.started, 461 | passed = config.stats.all - config.stats.bad; 462 | 463 | runLoggingCallbacks( "done", { 464 | failed: config.stats.bad, 465 | passed: passed, 466 | total: config.stats.all, 467 | runtime: runtime 468 | }); 469 | } 470 | 471 | /** @return Boolean: true if this test should be ran */ 472 | function validTest( test ) { 473 | var include, 474 | filter = config.filter && config.filter.toLowerCase(), 475 | module = config.module && config.module.toLowerCase(), 476 | fullName = ( test.module + ": " + test.testName ).toLowerCase(); 477 | 478 | // Internally-generated tests are always valid 479 | if ( test.callback && test.callback.validTest === validTest ) { 480 | delete test.callback.validTest; 481 | return true; 482 | } 483 | 484 | if ( config.testNumber.length > 0 ) { 485 | if ( inArray( test.testNumber, config.testNumber ) < 0 ) { 486 | return false; 487 | } 488 | } 489 | 490 | if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) { 491 | return false; 492 | } 493 | 494 | if ( !filter ) { 495 | return true; 496 | } 497 | 498 | include = filter.charAt( 0 ) !== "!"; 499 | if ( !include ) { 500 | filter = filter.slice( 1 ); 501 | } 502 | 503 | // If the filter matches, we need to honour include 504 | if ( fullName.indexOf( filter ) !== -1 ) { 505 | return include; 506 | } 507 | 508 | // Otherwise, do the opposite 509 | return !include; 510 | } 511 | 512 | // Doesn't support IE6 to IE9 513 | // See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack 514 | function extractStacktrace( e, offset ) { 515 | offset = offset === undefined ? 4 : offset; 516 | 517 | var stack, include, i; 518 | 519 | if ( e.stacktrace ) { 520 | 521 | // Opera 12.x 522 | return e.stacktrace.split( "\n" )[ offset + 3 ]; 523 | } else if ( e.stack ) { 524 | 525 | // Firefox, Chrome, Safari 6+, IE10+, PhantomJS and Node 526 | stack = e.stack.split( "\n" ); 527 | if ( /^error$/i.test( stack[ 0 ] ) ) { 528 | stack.shift(); 529 | } 530 | if ( fileName ) { 531 | include = []; 532 | for ( i = offset; i < stack.length; i++ ) { 533 | if ( stack[ i ].indexOf( fileName ) !== -1 ) { 534 | break; 535 | } 536 | include.push( stack[ i ] ); 537 | } 538 | if ( include.length ) { 539 | return include.join( "\n" ); 540 | } 541 | } 542 | return stack[ offset ]; 543 | } else if ( e.sourceURL ) { 544 | 545 | // Safari < 6 546 | // exclude useless self-reference for generated Error objects 547 | if ( /qunit.js$/.test( e.sourceURL ) ) { 548 | return; 549 | } 550 | 551 | // for actual exceptions, this is useful 552 | return e.sourceURL + ":" + e.line; 553 | } 554 | } 555 | function sourceFromStacktrace( offset ) { 556 | try { 557 | throw new Error(); 558 | } catch ( e ) { 559 | return extractStacktrace( e, offset ); 560 | } 561 | } 562 | 563 | function synchronize( callback, last ) { 564 | config.queue.push( callback ); 565 | 566 | if ( config.autorun && !config.blocking ) { 567 | process( last ); 568 | } 569 | } 570 | 571 | function process( last ) { 572 | function next() { 573 | process( last ); 574 | } 575 | var start = now(); 576 | config.depth = config.depth ? config.depth + 1 : 1; 577 | 578 | while ( config.queue.length && !config.blocking ) { 579 | if ( !defined.setTimeout || config.updateRate <= 0 || ( ( now() - start ) < config.updateRate ) ) { 580 | config.queue.shift()(); 581 | } else { 582 | setTimeout( next, 13 ); 583 | break; 584 | } 585 | } 586 | config.depth--; 587 | if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { 588 | done(); 589 | } 590 | } 591 | 592 | function saveGlobal() { 593 | config.pollution = []; 594 | 595 | if ( config.noglobals ) { 596 | for ( var key in window ) { 597 | if ( hasOwn.call( window, key ) ) { 598 | // in Opera sometimes DOM element ids show up here, ignore them 599 | if ( /^qunit-test-output/.test( key ) ) { 600 | continue; 601 | } 602 | config.pollution.push( key ); 603 | } 604 | } 605 | } 606 | } 607 | 608 | function checkPollution() { 609 | var newGlobals, 610 | deletedGlobals, 611 | old = config.pollution; 612 | 613 | saveGlobal(); 614 | 615 | newGlobals = diff( config.pollution, old ); 616 | if ( newGlobals.length > 0 ) { 617 | QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join( ", " ) ); 618 | } 619 | 620 | deletedGlobals = diff( old, config.pollution ); 621 | if ( deletedGlobals.length > 0 ) { 622 | QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join( ", " ) ); 623 | } 624 | } 625 | 626 | // returns a new Array with the elements that are in a but not in b 627 | function diff( a, b ) { 628 | var i, j, 629 | result = a.slice(); 630 | 631 | for ( i = 0; i < result.length; i++ ) { 632 | for ( j = 0; j < b.length; j++ ) { 633 | if ( result[ i ] === b[ j ] ) { 634 | result.splice( i, 1 ); 635 | i--; 636 | break; 637 | } 638 | } 639 | } 640 | return result; 641 | } 642 | 643 | function extend( a, b, undefOnly ) { 644 | for ( var prop in b ) { 645 | if ( hasOwn.call( b, prop ) ) { 646 | 647 | // Avoid "Member not found" error in IE8 caused by messing with window.constructor 648 | if ( !( prop === "constructor" && a === window ) ) { 649 | if ( b[ prop ] === undefined ) { 650 | delete a[ prop ]; 651 | } else if ( !( undefOnly && typeof a[ prop ] !== "undefined" ) ) { 652 | a[ prop ] = b[ prop ]; 653 | } 654 | } 655 | } 656 | } 657 | 658 | return a; 659 | } 660 | 661 | function registerLoggingCallback( key ) { 662 | 663 | // Initialize key collection of logging callback 664 | if ( QUnit.objectType( config.callbacks[ key ] ) === "undefined" ) { 665 | config.callbacks[ key ] = []; 666 | } 667 | 668 | return function( callback ) { 669 | config.callbacks[ key ].push( callback ); 670 | }; 671 | } 672 | 673 | function runLoggingCallbacks( key, args ) { 674 | var i, l, callbacks; 675 | 676 | callbacks = config.callbacks[ key ]; 677 | for ( i = 0, l = callbacks.length; i < l; i++ ) { 678 | callbacks[ i ]( args ); 679 | } 680 | } 681 | 682 | // from jquery.js 683 | function inArray( elem, array ) { 684 | if ( array.indexOf ) { 685 | return array.indexOf( elem ); 686 | } 687 | 688 | for ( var i = 0, length = array.length; i < length; i++ ) { 689 | if ( array[ i ] === elem ) { 690 | return i; 691 | } 692 | } 693 | 694 | return -1; 695 | } 696 | -------------------------------------------------------------------------------- /bower_components/qunit/src/dump.js: -------------------------------------------------------------------------------- 1 | // Based on jsDump by Ariel Flesler 2 | // http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html 3 | QUnit.dump = (function() { 4 | function quote( str ) { 5 | return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\""; 6 | } 7 | function literal( o ) { 8 | return o + ""; 9 | } 10 | function join( pre, arr, post ) { 11 | var s = dump.separator(), 12 | base = dump.indent(), 13 | inner = dump.indent( 1 ); 14 | if ( arr.join ) { 15 | arr = arr.join( "," + s + inner ); 16 | } 17 | if ( !arr ) { 18 | return pre + post; 19 | } 20 | return [ pre, inner + arr, base + post ].join( s ); 21 | } 22 | function array( arr, stack ) { 23 | var i = arr.length, 24 | ret = new Array( i ); 25 | this.up(); 26 | while ( i-- ) { 27 | ret[ i ] = this.parse( arr[ i ], undefined, stack ); 28 | } 29 | this.down(); 30 | return join( "[", ret, "]" ); 31 | } 32 | 33 | var reName = /^function (\w+)/, 34 | dump = { 35 | // type is used mostly internally, you can fix a (custom)type in advance 36 | parse: function( obj, type, stack ) { 37 | stack = stack || []; 38 | var inStack, res, 39 | parser = this.parsers[ type || this.typeOf( obj ) ]; 40 | 41 | type = typeof parser; 42 | inStack = inArray( obj, stack ); 43 | 44 | if ( inStack !== -1 ) { 45 | return "recursion(" + ( inStack - stack.length ) + ")"; 46 | } 47 | if ( type === "function" ) { 48 | stack.push( obj ); 49 | res = parser.call( this, obj, stack ); 50 | stack.pop(); 51 | return res; 52 | } 53 | return ( type === "string" ) ? parser : this.parsers.error; 54 | }, 55 | typeOf: function( obj ) { 56 | var type; 57 | if ( obj === null ) { 58 | type = "null"; 59 | } else if ( typeof obj === "undefined" ) { 60 | type = "undefined"; 61 | } else if ( QUnit.is( "regexp", obj ) ) { 62 | type = "regexp"; 63 | } else if ( QUnit.is( "date", obj ) ) { 64 | type = "date"; 65 | } else if ( QUnit.is( "function", obj ) ) { 66 | type = "function"; 67 | } else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) { 68 | type = "window"; 69 | } else if ( obj.nodeType === 9 ) { 70 | type = "document"; 71 | } else if ( obj.nodeType ) { 72 | type = "node"; 73 | } else if ( 74 | 75 | // native arrays 76 | toString.call( obj ) === "[object Array]" || 77 | 78 | // NodeList objects 79 | ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item( 0 ) === obj[ 0 ] : ( obj.item( 0 ) === null && typeof obj[ 0 ] === "undefined" ) ) ) 80 | ) { 81 | type = "array"; 82 | } else if ( obj.constructor === Error.prototype.constructor ) { 83 | type = "error"; 84 | } else { 85 | type = typeof obj; 86 | } 87 | return type; 88 | }, 89 | separator: function() { 90 | return this.multiline ? this.HTML ? "
      " : "\n" : this.HTML ? " " : " "; 91 | }, 92 | // extra can be a number, shortcut for increasing-calling-decreasing 93 | indent: function( extra ) { 94 | if ( !this.multiline ) { 95 | return ""; 96 | } 97 | var chr = this.indentChar; 98 | if ( this.HTML ) { 99 | chr = chr.replace( /\t/g, " " ).replace( / /g, " " ); 100 | } 101 | return new Array( this.depth + ( extra || 0 ) ).join( chr ); 102 | }, 103 | up: function( a ) { 104 | this.depth += a || 1; 105 | }, 106 | down: function( a ) { 107 | this.depth -= a || 1; 108 | }, 109 | setParser: function( name, parser ) { 110 | this.parsers[ name ] = parser; 111 | }, 112 | // The next 3 are exposed so you can use them 113 | quote: quote, 114 | literal: literal, 115 | join: join, 116 | // 117 | depth: 1, 118 | // This is the list of parsers, to modify them, use dump.setParser 119 | parsers: { 120 | window: "[Window]", 121 | document: "[Document]", 122 | error: function( error ) { 123 | return "Error(\"" + error.message + "\")"; 124 | }, 125 | unknown: "[Unknown]", 126 | "null": "null", 127 | "undefined": "undefined", 128 | "function": function( fn ) { 129 | var ret = "function", 130 | // functions never have name in IE 131 | name = "name" in fn ? fn.name : ( reName.exec( fn ) || [] )[ 1 ]; 132 | 133 | if ( name ) { 134 | ret += " " + name; 135 | } 136 | ret += "( "; 137 | 138 | ret = [ ret, dump.parse( fn, "functionArgs" ), "){" ].join( "" ); 139 | return join( ret, dump.parse( fn, "functionCode" ), "}" ); 140 | }, 141 | array: array, 142 | nodelist: array, 143 | "arguments": array, 144 | object: function( map, stack ) { 145 | /*jshint forin:false */ 146 | var ret = [], keys, key, val, i, nonEnumerableProperties; 147 | dump.up(); 148 | keys = []; 149 | for ( key in map ) { 150 | keys.push( key ); 151 | } 152 | 153 | // Some properties are not always enumerable on Error objects. 154 | nonEnumerableProperties = [ "message", "name" ]; 155 | for ( i in nonEnumerableProperties ) { 156 | key = nonEnumerableProperties[ i ]; 157 | if ( key in map && !( key in keys ) ) { 158 | keys.push( key ); 159 | } 160 | } 161 | keys.sort(); 162 | for ( i = 0; i < keys.length; i++ ) { 163 | key = keys[ i ]; 164 | val = map[ key ]; 165 | ret.push( dump.parse( key, "key" ) + ": " + dump.parse( val, undefined, stack ) ); 166 | } 167 | dump.down(); 168 | return join( "{", ret, "}" ); 169 | }, 170 | node: function( node ) { 171 | var len, i, val, 172 | open = dump.HTML ? "<" : "<", 173 | close = dump.HTML ? ">" : ">", 174 | tag = node.nodeName.toLowerCase(), 175 | ret = open + tag, 176 | attrs = node.attributes; 177 | 178 | if ( attrs ) { 179 | for ( i = 0, len = attrs.length; i < len; i++ ) { 180 | val = attrs[ i ].nodeValue; 181 | 182 | // IE6 includes all attributes in .attributes, even ones not explicitly set. 183 | // Those have values like undefined, null, 0, false, "" or "inherit". 184 | if ( val && val !== "inherit" ) { 185 | ret += " " + attrs[ i ].nodeName + "=" + dump.parse( val, "attribute" ); 186 | } 187 | } 188 | } 189 | ret += close; 190 | 191 | // Show content of TextNode or CDATASection 192 | if ( node.nodeType === 3 || node.nodeType === 4 ) { 193 | ret += node.nodeValue; 194 | } 195 | 196 | return ret + open + "/" + tag + close; 197 | }, 198 | 199 | // function calls it internally, it's the arguments part of the function 200 | functionArgs: function( fn ) { 201 | var args, 202 | l = fn.length; 203 | 204 | if ( !l ) { 205 | return ""; 206 | } 207 | 208 | args = new Array( l ); 209 | while ( l-- ) { 210 | 211 | // 97 is 'a' 212 | args[ l ] = String.fromCharCode( 97 + l ); 213 | } 214 | return " " + args.join( ", " ) + " "; 215 | }, 216 | // object calls it internally, the key part of an item in a map 217 | key: quote, 218 | // function calls it internally, it's the content of the function 219 | functionCode: "[code]", 220 | // node calls it internally, it's an html attribute value 221 | attribute: quote, 222 | string: quote, 223 | date: quote, 224 | regexp: literal, 225 | number: literal, 226 | "boolean": literal 227 | }, 228 | // if true, entities are escaped ( <, >, \t, space and \n ) 229 | HTML: false, 230 | // indentation unit 231 | indentChar: " ", 232 | // if true, items in a collection, are separated by a \n, else just a space. 233 | multiline: true 234 | }; 235 | 236 | return dump; 237 | }()); 238 | 239 | // back compat 240 | QUnit.jsDump = QUnit.dump; 241 | -------------------------------------------------------------------------------- /bower_components/qunit/src/equiv.js: -------------------------------------------------------------------------------- 1 | // Test for equality any JavaScript type. 2 | // Author: Philippe Rathé 3 | QUnit.equiv = (function() { 4 | 5 | // Call the o related callback with the given arguments. 6 | function bindCallbacks( o, callbacks, args ) { 7 | var prop = QUnit.objectType( o ); 8 | if ( prop ) { 9 | if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) { 10 | return callbacks[ prop ].apply( callbacks, args ); 11 | } else { 12 | return callbacks[ prop ]; // or undefined 13 | } 14 | } 15 | } 16 | 17 | // the real equiv function 18 | var innerEquiv, 19 | 20 | // stack to decide between skip/abort functions 21 | callers = [], 22 | 23 | // stack to avoiding loops from circular referencing 24 | parents = [], 25 | parentsB = [], 26 | 27 | getProto = Object.getPrototypeOf || function( obj ) { 28 | /* jshint camelcase: false, proto: true */ 29 | return obj.__proto__; 30 | }, 31 | callbacks = (function() { 32 | 33 | // for string, boolean, number and null 34 | function useStrictEquality( b, a ) { 35 | 36 | /*jshint eqeqeq:false */ 37 | if ( b instanceof a.constructor || a instanceof b.constructor ) { 38 | 39 | // to catch short annotation VS 'new' annotation of a 40 | // declaration 41 | // e.g. var i = 1; 42 | // var j = new Number(1); 43 | return a == b; 44 | } else { 45 | return a === b; 46 | } 47 | } 48 | 49 | return { 50 | "string": useStrictEquality, 51 | "boolean": useStrictEquality, 52 | "number": useStrictEquality, 53 | "null": useStrictEquality, 54 | "undefined": useStrictEquality, 55 | 56 | "nan": function( b ) { 57 | return isNaN( b ); 58 | }, 59 | 60 | "date": function( b, a ) { 61 | return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf(); 62 | }, 63 | 64 | "regexp": function( b, a ) { 65 | return QUnit.objectType( b ) === "regexp" && 66 | 67 | // the regex itself 68 | a.source === b.source && 69 | 70 | // and its modifiers 71 | a.global === b.global && 72 | 73 | // (gmi) ... 74 | a.ignoreCase === b.ignoreCase && 75 | a.multiline === b.multiline && 76 | a.sticky === b.sticky; 77 | }, 78 | 79 | // - skip when the property is a method of an instance (OOP) 80 | // - abort otherwise, 81 | // initial === would have catch identical references anyway 82 | "function": function() { 83 | var caller = callers[ callers.length - 1 ]; 84 | return caller !== Object && typeof caller !== "undefined"; 85 | }, 86 | 87 | "array": function( b, a ) { 88 | var i, j, len, loop, aCircular, bCircular; 89 | 90 | // b could be an object literal here 91 | if ( QUnit.objectType( b ) !== "array" ) { 92 | return false; 93 | } 94 | 95 | len = a.length; 96 | if ( len !== b.length ) { 97 | // safe and faster 98 | return false; 99 | } 100 | 101 | // track reference to avoid circular references 102 | parents.push( a ); 103 | parentsB.push( b ); 104 | for ( i = 0; i < len; i++ ) { 105 | loop = false; 106 | for ( j = 0; j < parents.length; j++ ) { 107 | aCircular = parents[ j ] === a[ i ]; 108 | bCircular = parentsB[ j ] === b[ i ]; 109 | if ( aCircular || bCircular ) { 110 | if ( a[ i ] === b[ i ] || aCircular && bCircular ) { 111 | loop = true; 112 | } else { 113 | parents.pop(); 114 | parentsB.pop(); 115 | return false; 116 | } 117 | } 118 | } 119 | if ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) { 120 | parents.pop(); 121 | parentsB.pop(); 122 | return false; 123 | } 124 | } 125 | parents.pop(); 126 | parentsB.pop(); 127 | return true; 128 | }, 129 | 130 | "object": function( b, a ) { 131 | 132 | /*jshint forin:false */ 133 | var i, j, loop, aCircular, bCircular, 134 | // Default to true 135 | eq = true, 136 | aProperties = [], 137 | bProperties = []; 138 | 139 | // comparing constructors is more strict than using 140 | // instanceof 141 | if ( a.constructor !== b.constructor ) { 142 | 143 | // Allow objects with no prototype to be equivalent to 144 | // objects with Object as their constructor. 145 | if ( !( ( getProto( a ) === null && getProto( b ) === Object.prototype ) || 146 | ( getProto( b ) === null && getProto( a ) === Object.prototype ) ) ) { 147 | return false; 148 | } 149 | } 150 | 151 | // stack constructor before traversing properties 152 | callers.push( a.constructor ); 153 | 154 | // track reference to avoid circular references 155 | parents.push( a ); 156 | parentsB.push( b ); 157 | 158 | // be strict: don't ensure hasOwnProperty and go deep 159 | for ( i in a ) { 160 | loop = false; 161 | for ( j = 0; j < parents.length; j++ ) { 162 | aCircular = parents[ j ] === a[ i ]; 163 | bCircular = parentsB[ j ] === b[ i ]; 164 | if ( aCircular || bCircular ) { 165 | if ( a[ i ] === b[ i ] || aCircular && bCircular ) { 166 | loop = true; 167 | } else { 168 | eq = false; 169 | break; 170 | } 171 | } 172 | } 173 | aProperties.push( i ); 174 | if ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) { 175 | eq = false; 176 | break; 177 | } 178 | } 179 | 180 | parents.pop(); 181 | parentsB.pop(); 182 | callers.pop(); // unstack, we are done 183 | 184 | for ( i in b ) { 185 | bProperties.push( i ); // collect b's properties 186 | } 187 | 188 | // Ensures identical properties name 189 | return eq && innerEquiv( aProperties.sort(), bProperties.sort() ); 190 | } 191 | }; 192 | }()); 193 | 194 | innerEquiv = function() { // can take multiple arguments 195 | var args = [].slice.apply( arguments ); 196 | if ( args.length < 2 ) { 197 | return true; // end transition 198 | } 199 | 200 | return ( (function( a, b ) { 201 | if ( a === b ) { 202 | return true; // catch the most you can 203 | } else if ( a === null || b === null || typeof a === "undefined" || 204 | typeof b === "undefined" || 205 | QUnit.objectType( a ) !== QUnit.objectType( b ) ) { 206 | 207 | // don't lose time with error prone cases 208 | return false; 209 | } else { 210 | return bindCallbacks( a, callbacks, [ b, a ] ); 211 | } 212 | 213 | // apply transition with (1..n) arguments 214 | }( args[ 0 ], args[ 1 ] ) ) && innerEquiv.apply( this, args.splice( 1, args.length - 1 ) ) ); 215 | }; 216 | 217 | return innerEquiv; 218 | }()); 219 | -------------------------------------------------------------------------------- /bower_components/qunit/src/export.js: -------------------------------------------------------------------------------- 1 | // For browser, export only select globals 2 | if ( typeof window !== "undefined" ) { 3 | 4 | // Deprecated 5 | // Extend assert methods to QUnit and Global scope through Backwards compatibility 6 | (function() { 7 | var i, 8 | assertions = Assert.prototype; 9 | 10 | function applyCurrent( current ) { 11 | return function() { 12 | var assert = new Assert( QUnit.config.current ); 13 | current.apply( assert, arguments ); 14 | }; 15 | } 16 | 17 | for ( i in assertions ) { 18 | QUnit[ i ] = applyCurrent( assertions[ i ] ); 19 | } 20 | })(); 21 | 22 | (function() { 23 | var i, l, 24 | keys = [ 25 | "test", 26 | "module", 27 | "expect", 28 | "asyncTest", 29 | "start", 30 | "stop", 31 | "ok", 32 | "equal", 33 | "notEqual", 34 | "propEqual", 35 | "notPropEqual", 36 | "deepEqual", 37 | "notDeepEqual", 38 | "strictEqual", 39 | "notStrictEqual", 40 | "throws" 41 | ]; 42 | 43 | for ( i = 0, l = keys.length; i < l; i++ ) { 44 | window[ keys[ i ] ] = QUnit[ keys[ i ] ]; 45 | } 46 | })(); 47 | 48 | window.QUnit = QUnit; 49 | } 50 | 51 | // For CommonJS environments, export everything 52 | if ( typeof module !== "undefined" && module.exports ) { 53 | module.exports = QUnit; 54 | } 55 | -------------------------------------------------------------------------------- /bower_components/qunit/src/intro.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * QUnit @VERSION 3 | * http://qunitjs.com/ 4 | * 5 | * Copyright 2014 jQuery Foundation and other contributors 6 | * Released under the MIT license 7 | * http://jquery.org/license 8 | * 9 | * Date: @DATE 10 | */ 11 | 12 | (function( window ) { 13 | -------------------------------------------------------------------------------- /bower_components/qunit/src/outro.js: -------------------------------------------------------------------------------- 1 | // Get a reference to the global object, like window in browsers 2 | }( (function() { 3 | return this; 4 | })() )); 5 | -------------------------------------------------------------------------------- /bower_components/qunit/src/qunit.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * QUnit @VERSION 3 | * http://qunitjs.com/ 4 | * 5 | * Copyright 2014 jQuery Foundation and other contributors 6 | * Released under the MIT license 7 | * http://jquery.org/license 8 | * 9 | * Date: @DATE 10 | */ 11 | 12 | /** Font Family and Sizes */ 13 | 14 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { 15 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; 16 | } 17 | 18 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } 19 | #qunit-tests { font-size: smaller; } 20 | 21 | 22 | /** Resets */ 23 | 24 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { 25 | margin: 0; 26 | padding: 0; 27 | } 28 | 29 | 30 | /** Header */ 31 | 32 | #qunit-header { 33 | padding: 0.5em 0 0.5em 1em; 34 | 35 | color: #8699A4; 36 | background-color: #0D3349; 37 | 38 | font-size: 1.5em; 39 | line-height: 1em; 40 | font-weight: 400; 41 | 42 | border-radius: 5px 5px 0 0; 43 | } 44 | 45 | #qunit-header a { 46 | text-decoration: none; 47 | color: #C2CCD1; 48 | } 49 | 50 | #qunit-header a:hover, 51 | #qunit-header a:focus { 52 | color: #FFF; 53 | } 54 | 55 | #qunit-testrunner-toolbar label { 56 | display: inline-block; 57 | padding: 0 0.5em 0 0.1em; 58 | } 59 | 60 | #qunit-banner { 61 | height: 5px; 62 | } 63 | 64 | #qunit-testrunner-toolbar { 65 | padding: 0.5em 1em 0.5em 1em; 66 | color: #5E740B; 67 | background-color: #EEE; 68 | overflow: hidden; 69 | } 70 | 71 | #qunit-userAgent { 72 | padding: 0.5em 1em 0.5em 1em; 73 | background-color: #2B81AF; 74 | color: #FFF; 75 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; 76 | } 77 | 78 | #qunit-modulefilter-container { 79 | float: right; 80 | } 81 | 82 | /** Tests: Pass/Fail */ 83 | 84 | #qunit-tests { 85 | list-style-position: inside; 86 | } 87 | 88 | #qunit-tests li { 89 | padding: 0.4em 1em 0.4em 1em; 90 | border-bottom: 1px solid #FFF; 91 | list-style-position: inside; 92 | } 93 | 94 | #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { 95 | display: none; 96 | } 97 | 98 | #qunit-tests li strong { 99 | cursor: pointer; 100 | } 101 | 102 | #qunit-tests li a { 103 | padding: 0.5em; 104 | color: #C2CCD1; 105 | text-decoration: none; 106 | } 107 | #qunit-tests li a:hover, 108 | #qunit-tests li a:focus { 109 | color: #000; 110 | } 111 | 112 | #qunit-tests li .runtime { 113 | float: right; 114 | font-size: smaller; 115 | } 116 | 117 | .qunit-assert-list { 118 | margin-top: 0.5em; 119 | padding: 0.5em; 120 | 121 | background-color: #FFF; 122 | 123 | border-radius: 5px; 124 | } 125 | 126 | .qunit-collapsed { 127 | display: none; 128 | } 129 | 130 | #qunit-tests table { 131 | border-collapse: collapse; 132 | margin-top: 0.2em; 133 | } 134 | 135 | #qunit-tests th { 136 | text-align: right; 137 | vertical-align: top; 138 | padding: 0 0.5em 0 0; 139 | } 140 | 141 | #qunit-tests td { 142 | vertical-align: top; 143 | } 144 | 145 | #qunit-tests pre { 146 | margin: 0; 147 | white-space: pre-wrap; 148 | word-wrap: break-word; 149 | } 150 | 151 | #qunit-tests del { 152 | background-color: #E0F2BE; 153 | color: #374E0C; 154 | text-decoration: none; 155 | } 156 | 157 | #qunit-tests ins { 158 | background-color: #FFCACA; 159 | color: #500; 160 | text-decoration: none; 161 | } 162 | 163 | /*** Test Counts */ 164 | 165 | #qunit-tests b.counts { color: #000; } 166 | #qunit-tests b.passed { color: #5E740B; } 167 | #qunit-tests b.failed { color: #710909; } 168 | 169 | #qunit-tests li li { 170 | padding: 5px; 171 | background-color: #FFF; 172 | border-bottom: none; 173 | list-style-position: inside; 174 | } 175 | 176 | /*** Passing Styles */ 177 | 178 | #qunit-tests li li.pass { 179 | color: #3C510C; 180 | background-color: #FFF; 181 | border-left: 10px solid #C6E746; 182 | } 183 | 184 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } 185 | #qunit-tests .pass .test-name { color: #366097; } 186 | 187 | #qunit-tests .pass .test-actual, 188 | #qunit-tests .pass .test-expected { color: #999; } 189 | 190 | #qunit-banner.qunit-pass { background-color: #C6E746; } 191 | 192 | /*** Failing Styles */ 193 | 194 | #qunit-tests li li.fail { 195 | color: #710909; 196 | background-color: #FFF; 197 | border-left: 10px solid #EE5757; 198 | white-space: pre; 199 | } 200 | 201 | #qunit-tests > li:last-child { 202 | border-radius: 0 0 5px 5px; 203 | } 204 | 205 | #qunit-tests .fail { color: #000; background-color: #EE5757; } 206 | #qunit-tests .fail .test-name, 207 | #qunit-tests .fail .module-name { color: #000; } 208 | 209 | #qunit-tests .fail .test-actual { color: #EE5757; } 210 | #qunit-tests .fail .test-expected { color: #008000; } 211 | 212 | #qunit-banner.qunit-fail { background-color: #EE5757; } 213 | 214 | 215 | /** Result */ 216 | 217 | #qunit-testresult { 218 | padding: 0.5em 1em 0.5em 1em; 219 | 220 | color: #2B81AF; 221 | background-color: #D2E0E6; 222 | 223 | border-bottom: 1px solid #FFF; 224 | } 225 | #qunit-testresult .module-name { 226 | font-weight: 700; 227 | } 228 | 229 | /** Fixture */ 230 | 231 | #qunit-fixture { 232 | position: absolute; 233 | top: -10000px; 234 | left: -10000px; 235 | width: 1000px; 236 | height: 1000px; 237 | } 238 | -------------------------------------------------------------------------------- /bower_components/qunit/src/test.js: -------------------------------------------------------------------------------- 1 | function Test( settings ) { 2 | extend( this, settings ); 3 | this.assert = new Assert( this ); 4 | this.assertions = []; 5 | this.testNumber = ++Test.count; 6 | } 7 | 8 | Test.count = 0; 9 | 10 | Test.prototype = { 11 | setup: function() { 12 | if ( 13 | 14 | // Emit moduleStart when we're switching from one module to another 15 | this.module !== config.previousModule || 16 | 17 | // They could be equal (both undefined) but if the previousModule property doesn't 18 | // yet exist it means this is the first test in a suite that isn't wrapped in a 19 | // module, in which case we'll just emit a moduleStart event for 'undefined'. 20 | // Without this, reporters can get testStart before moduleStart which is a problem. 21 | !hasOwn.call( config, "previousModule" ) 22 | ) { 23 | if ( hasOwn.call( config, "previousModule" ) ) { 24 | runLoggingCallbacks( "moduleDone", { 25 | name: config.previousModule, 26 | failed: config.moduleStats.bad, 27 | passed: config.moduleStats.all - config.moduleStats.bad, 28 | total: config.moduleStats.all 29 | }); 30 | } 31 | config.previousModule = this.module; 32 | config.moduleStats = { all: 0, bad: 0 }; 33 | runLoggingCallbacks( "moduleStart", { 34 | name: this.module 35 | }); 36 | } 37 | 38 | config.current = this; 39 | 40 | this.testEnvironment = extend({ 41 | setup: function() {}, 42 | teardown: function() {} 43 | }, this.moduleTestEnvironment ); 44 | 45 | this.started = now(); 46 | runLoggingCallbacks( "testStart", { 47 | name: this.testName, 48 | module: this.module, 49 | testNumber: this.testNumber 50 | }); 51 | 52 | if ( !config.pollution ) { 53 | saveGlobal(); 54 | } 55 | if ( config.notrycatch ) { 56 | this.testEnvironment.setup.call( this.testEnvironment, this.assert ); 57 | return; 58 | } 59 | try { 60 | this.testEnvironment.setup.call( this.testEnvironment, this.assert ); 61 | } catch ( e ) { 62 | this.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); 63 | } 64 | }, 65 | run: function() { 66 | config.current = this; 67 | 68 | if ( this.async ) { 69 | QUnit.stop(); 70 | } 71 | 72 | this.callbackStarted = now(); 73 | 74 | if ( config.notrycatch ) { 75 | this.callback.call( this.testEnvironment, this.assert ); 76 | this.callbackRuntime = now() - this.callbackStarted; 77 | return; 78 | } 79 | 80 | try { 81 | this.callback.call( this.testEnvironment, this.assert ); 82 | this.callbackRuntime = now() - this.callbackStarted; 83 | } catch ( e ) { 84 | this.callbackRuntime = now() - this.callbackStarted; 85 | 86 | this.pushFailure( "Died on test #" + ( this.assertions.length + 1 ) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); 87 | 88 | // else next test will carry the responsibility 89 | saveGlobal(); 90 | 91 | // Restart the tests if they're blocking 92 | if ( config.blocking ) { 93 | QUnit.start(); 94 | } 95 | } 96 | }, 97 | teardown: function() { 98 | config.current = this; 99 | if ( config.notrycatch ) { 100 | if ( typeof this.callbackRuntime === "undefined" ) { 101 | this.callbackRuntime = now() - this.callbackStarted; 102 | } 103 | this.testEnvironment.teardown.call( this.testEnvironment, this.assert ); 104 | return; 105 | } else { 106 | try { 107 | this.testEnvironment.teardown.call( this.testEnvironment, this.assert ); 108 | } catch ( e ) { 109 | this.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); 110 | } 111 | } 112 | checkPollution(); 113 | }, 114 | finish: function() { 115 | config.current = this; 116 | if ( config.requireExpects && this.expected === null ) { 117 | this.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack ); 118 | } else if ( this.expected !== null && this.expected !== this.assertions.length ) { 119 | this.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack ); 120 | } else if ( this.expected === null && !this.assertions.length ) { 121 | this.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack ); 122 | } 123 | 124 | var i, 125 | bad = 0; 126 | 127 | this.runtime = now() - this.started; 128 | config.stats.all += this.assertions.length; 129 | config.moduleStats.all += this.assertions.length; 130 | 131 | for ( i = 0; i < this.assertions.length; i++ ) { 132 | if ( !this.assertions[ i ].result ) { 133 | bad++; 134 | config.stats.bad++; 135 | config.moduleStats.bad++; 136 | } 137 | } 138 | 139 | runLoggingCallbacks( "testDone", { 140 | name: this.testName, 141 | module: this.module, 142 | failed: bad, 143 | passed: this.assertions.length - bad, 144 | total: this.assertions.length, 145 | runtime: this.runtime, 146 | 147 | // HTML Reporter use 148 | assertions: this.assertions, 149 | testNumber: this.testNumber, 150 | 151 | // DEPRECATED: this property will be removed in 2.0.0, use runtime instead 152 | duration: this.runtime 153 | }); 154 | 155 | config.current = undefined; 156 | }, 157 | 158 | queue: function() { 159 | var bad, 160 | test = this; 161 | 162 | function run() { 163 | // each of these can by async 164 | synchronize(function() { 165 | test.setup(); 166 | }); 167 | synchronize(function() { 168 | test.run(); 169 | }); 170 | synchronize(function() { 171 | test.teardown(); 172 | }); 173 | synchronize(function() { 174 | test.finish(); 175 | }); 176 | } 177 | 178 | // `bad` initialized at top of scope 179 | // defer when previous test run passed, if storage is available 180 | bad = QUnit.config.reorder && defined.sessionStorage && 181 | +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName ); 182 | 183 | if ( bad ) { 184 | run(); 185 | } else { 186 | synchronize( run, true ); 187 | } 188 | }, 189 | 190 | push: function( result, actual, expected, message ) { 191 | var source, 192 | details = { 193 | module: this.module, 194 | name: this.testName, 195 | result: result, 196 | message: message, 197 | actual: actual, 198 | expected: expected, 199 | testNumber: this.testNumber 200 | }; 201 | 202 | if ( !result ) { 203 | source = sourceFromStacktrace(); 204 | 205 | if ( source ) { 206 | details.source = source; 207 | } 208 | } 209 | 210 | runLoggingCallbacks( "log", details ); 211 | 212 | this.assertions.push({ 213 | result: !!result, 214 | message: message 215 | }); 216 | }, 217 | 218 | pushFailure: function( message, source, actual ) { 219 | if ( !this instanceof Test ) { 220 | throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace( 2 ) ); 221 | } 222 | 223 | var details = { 224 | module: this.module, 225 | name: this.testName, 226 | result: false, 227 | message: message || "error", 228 | actual: actual || null, 229 | testNumber: this.testNumber 230 | }; 231 | 232 | if ( source ) { 233 | details.source = source; 234 | } 235 | 236 | runLoggingCallbacks( "log", details ); 237 | 238 | this.assertions.push({ 239 | result: false, 240 | message: message 241 | }); 242 | } 243 | }; 244 | 245 | QUnit.pushFailure = function() { 246 | if ( !QUnit.config.current ) { 247 | throw new Error( "pushFailure() assertion outside test context, in " + sourceFromStacktrace( 2 ) ); 248 | } 249 | 250 | // Gets current test obj 251 | var currentTest = QUnit.config.current.assert.test; 252 | 253 | return currentTest.pushFailure.apply( currentTest, arguments ); 254 | }; 255 | -------------------------------------------------------------------------------- /idb-iegap.min.js: -------------------------------------------------------------------------------- 1 | navigator.userAgent.indexOf("Trident/")!==-1&&function(n,t){function a(n,t){return typeof t!="object"&&(t=t()),Object.keys(t).forEach(function(i){n[i]=t[i]}),n}function b(n){return{from:function(t){return n.prototype=Object.create(t.prototype),n.prototype.constructor=n,{extend:function(i){a(n.prototype,typeof i!="object"?i(t.prototype):i)}}}}}function r(n,t){if(typeof n=="object")Object.keys(t).forEach(function(i){var u=Object.getOwnPropertyDescriptor(n,i),r=t[i](u);r.hasOwnProperty("value")&&r.writable!==!1&&(r.writable=!0);Object.defineProperty(n,i,a({configurable:!0,enumerable:!0},r))});else return t(n)}function s(n,i){var f,r,o,h,u,e;if(n.hasOwnProperty(i))return n[i];if(!i)return n;if(typeof i!="string"){for(f=[],r=0,o=i.length;r=-4;--n)v[n]=Math.pow(32768,n)}function rt(n,t,i){for(var r=t-1,o=n<0?32767:0,s=n<0?-n:n,u="",f,e;r>=-i;)f=s/v[r]&32767^o,e=f<<1|1,u+=String.fromCharCode(e),--r;return u}function d(n,i,r,u){var e=0,o=i-1,h=n.length,f,s;if(i+r!=h)return t;for(f=0;f>1,u?e-=v[o]*(s^32767):e+=v[o]*s,--o;return e}function f(n){for(var t,r=n.length,u=new Array(r),i=0;i=6&&(this.value=f)}function ut(){this._el={}}function e(n,t,i){this._el={};this.source=n;this.transaction=t;this.readyState="pending";var r=this,u={get:function(){return r}};i(function(n,t){r.result=t;Object.defineProperty(n,"target",u);r.readyState="done";r.dispatchEvent(n)},function(n,t){r.error=t||n.target.error;Object.defineProperty(n,"target",u);r.readyState="done";n.type!="error"&&Object.defineProperty(n,"type",{get:function(){return"error"}});r.dispatchEvent(n)},this)}function ft(){e.apply(this,arguments)}function o(n,t,i,r){this.lower=n;this.upper=t;this.lowerOpen=i;this.upperOpen=r}function et(n){return Object.defineProperties(n,{contains:{configurable:!0,writable:!0,value:function(t){return n.indexOf(t)!==-1}},item:{configurable:!0,writable:!0,value:function(t){return n[t]}}}),n}function ht(){var a=Object.getOwnPropertyDescriptor(y.prototype,"objectStoreNames").get,v=y.prototype.deleteObjectStore,t=y.prototype.createObjectStore;st();n.open=r(n.open,function(n){return function(){var i=n.apply(this,arguments);return new ft(this,null,function(n,r,u){i.onerror=r;i.onblocked=function(n){u.dispatchEvent(n)};i.onupgradeneeded=function(n){var r,f;u.transaction=i.transaction;r=u.result=i.result;r._upgradeTransaction=i.transaction;r._iegapmeta={stores:{}};a.apply(r).contains("$iegapmeta")||(f=t.call(r,"$iegapmeta"),f.add(r._iegapmeta,1));n.target=n.currentTarget=u;u.dispatchEvent(n)};i.onsuccess=function(t){var u=i.result,e,f;delete u._upgradeTransaction;u._iegapmeta={stores:{}};try{e=u.transaction(["$iegapmeta"],"readonly");f=e.objectStore("$iegapmeta").get(1);f.onerror=r;f.onsuccess=function(){u._iegapmeta=f.result;n(t,u)}}catch(o){r(t,o)}}})}});u.bound=r(u.bound,function(n){return function(t,i,r,u){return Array.isArray(t)?new o(t,i,r,u):n.apply(this,arguments)}});u.lowerBound=r(u.lowerBound,function(n){return function(t,i){return Array.isArray(t)?new o(t,null,i,null):n.apply(this,arguments)}});u.upperBound=r(u.upperBound,function(n){return function(t,i){return Array.isArray(t)?new o(null,t,null,i):n.apply(this,arguments)}});u.only=r(u.only,function(n){return function(t){return Array.isArray(t)?new o(t,t):n.apply(this,arguments)}});i.prototype.count=r(i.prototype.count,function(n){return function(t){return arguments.length>0&&(arguments[0]=l(t)),n.apply(this,arguments)}});i.prototype.get=r(i.prototype.get,function(n){return function(t){return arguments.length>0&&(arguments[0]=l(t)),n.apply(this,arguments)}});i.prototype.openCursor=r(i.prototype.openCursor,function(n){return function(t){var h=this.transaction.db._iegapmeta.stores[this.name],i,l,r,s;if(!h)return n.apply(this,arguments);if(Array.isArray(t)&&(t=new o(t,t)),i=h.compound,i&&t&&!(t instanceof o))throw new RangeError("Primary key is compound but given range is not.");return l=i&&t?u.bound(f(t.lower),f(t.upper),t.lowerOpen,t.upperOpen):t,arguments[0]=l,r=n.apply(this,arguments),s=this,new e(this,this.transaction,function(n,t){r.onerror=t;r.onsuccess=function(t){var r=t.target.result,u,f;r?(u=i?c(r.key):r.key,f=new w(r,s,s,u,u,r.value),n(t,f)):n(t,null)}})}});i.prototype.createIndex=r(i.prototype.createIndex,function(n){function i(n,i,r,u){var f=n.transaction.db,e="$iegap-"+n.name+"-"+i,o=f._iegapmeta,c;if(u.multiEntry&&Array.isArray(r)){t.call(f,"dummy",{keyPath:"",autoIncrement:!0});throw"invalid access";}var s=t.call(f,e,{autoIncrement:!0}),h=o.stores[n.name]||(o.stores[n.name]={indexes:{},metaStores:[]}),l={name:i,keyPath:r,multiEntry:u.multiEntry||!1,unique:u.unique||!1,compound:Array.isArray(r),storeName:n.name,idxStoreName:e};return h.indexes[i]=l,h.metaStores.push(e),s.createIndex("fk","fk",{unique:!1}),c=s.createIndex("k","k",{unique:u.unique||!1}),p(f,n.transaction,o),n._reindexing||(n._reindexing=!0,n.openCursor().onsuccess=function(t){delete n._reindexing;var i=t.target.result;i&&(i.update(i.value),i.continue())}),new g(c,n,i,r,u.multiEntry)}return function(t,r,u){return Array.isArray(r)||u&&u.multiEntry?i(this,t,r,u||{}):n.apply(this,arguments)}});i.prototype.deleteIndex=r(i.prototype.deleteIndex,function(n){return function(t){var i=this.transaction.db,f=i._iegapmeta,r=f.stores[this.name],u;if(!r||(u=r.indexes[t],!u))return n.apply(this,arguments);v.call(i,u.idxStoreName);delete r.indexes[t];p(i,this.transaction,f)}});i.prototype.index=r(i.prototype.index,function(n){return function(t){var r=this.transaction.db._iegapmeta.stores[this.name],i;return r?(i=r.indexes[t],i?new g(this.transaction.objectStore(i.idxStoreName).index("k"),this,i.name,i.keyPath,i.multiEntry):n.apply(this,arguments)):n.apply(this,arguments)}});i.prototype.add=r(i.prototype.add,function(n){return function(t,i){var u=this.transaction.db._iegapmeta.stores[this.name],r,h,o;if(!u)return n.apply(this,arguments);if(u.compound){if(i)return this.add(null);i=f(s(t,u.keyPath));r=n.call(this,t,i)}else r=n.apply(this,arguments);return(h=Object.keys(u.indexes),!u.compound&&h.length===0)?r:(o=this,new e(this,this.transaction,function(n,f){function v(){if(y&&(l||e))if(e){var t=!1;e.preventDefault=function(){t=!0};f(e);t||o.transaction.abort()}else n(l,u.compound?c(r.result):r.result)}function w(){function n(){--i==0&&(e?ot(p,function(){y=!0;v()},"rolling back index additions"):(y=!0,v()))}var i=h.length;h.forEach(function(i){var r=u.indexes[i],f=o.transaction.objectStore(r.idxStoreName);if(r.multiEntry)tt(f,r,t,a,p,n);else if(r.compound)nt(f,r,t,a,p,n);else throw"IEGap assert error";})}var l=null,e=null,y=!1,p=[],a=i||o.keyPath&&s(t,o.keyPath);a?(w(),r.onerror=function(n){e=n;n.preventDefault();v()},r.onsuccess=function(n){l=n;v()}):(r.onerror=f,r.onsuccess=function(n){l=n;a=r.result;w()})}))}});i.prototype.put=r(i.prototype.put,function(n){return function(t,i){var r=this.transaction.db._iegapmeta.stores[this.name],u,o,h;if(!r)return n.apply(this,arguments);if(r.compound){if(i)return this.add(null);i=f(s(t,r.keyPath));u=n.call(this,t,i)}else u=n.apply(this,arguments);return(o=Object.keys(r.indexes),!r.compound&&o.length===0)?u:(h=this,new e(this,this.transaction,function(n,i){function s(){function i(){--u==0&&n(e,r.compound?c(f):f)}var u=o.length;o.forEach(function(n){var u=r.indexes[n],e=h.transaction.objectStore(u.idxStoreName);it(e.index("fk"),f,function(){if(u.multiEntry)tt(e,u,t,f,null,i);else if(u.compound)nt(e,u,t,f,null,i);else{i();throw"IEGap assert error";}})})}var e=null,f;u.onerror=i;u.onsuccess=function(n){e=n;f=u.result;s()}}))}});i.prototype.delete=r(i.prototype.delete,function(n){return function(t){var i=this.transaction.db._iegapmeta.stores[this.name],r,u,o;return i?(i.compound&&(t=f(t)),r=n.call(this,t),u=Object.keys(i.indexes),u.length==0)?r:(o=this,new e(this,this.transaction,function(n,f){function s(){function f(){--r==0&&n(e)}var r=u.length;u.forEach(function(n){var r=i.indexes[n],u=o.transaction.objectStore(r.idxStoreName);it(u.index("fk"),t,f)})}var e=null;r.onerror=f;r.onsuccess=function(n){e=n;s()}})):n.apply(this,arguments)}});i.prototype.clear=r(i.prototype.clear,function(n){return function(){var t=n.apply(this,arguments),i=this.transaction.db._iegapmeta.stores[this.name],r;return i?(r=this,new e(this,this.transaction,function(n,u){function o(){function u(){--t==0&&n(f)}var t=e.length;if(t===0)return n(f);e.forEach(function(n){var f=i.indexes[n],e=r.transaction.objectStore(f.idxStoreName),t=e.clear();t.onerror=h("clearing meta store",u);t.onsuccess=u})}var e=Object.keys(i.indexes),f=null;t.onerror=u;t.onsuccess=function(n){f=n;o()}})):t}});r(i.prototype,{indexNames:function(n){return{get:function(){var t=[].slice.call(n.get.apply(this)),i=this.transaction.db._iegapmeta.stores[this.name];return i&&(t=t.concat(Object.keys(i.indexes))),new et(t)}}},autoIncrement:function(n){return{get:function(){var t=this.transaction.db._iegapmeta.stores[this.name];return t&&"autoIncrement"in t?t.autoIncrement:n.get.call(this)}}},keyPath:function(n){return{get:function(){var t=this.transaction.db._iegapmeta.stores[this.name];return t&&"keyPath"in t?t.keyPath:n.get.call(this)}}}});r(y.prototype,{transaction:function(n){return{value:function(t,i){t=typeof t=="string"?[t]:[].slice.call(t);var r=this._iegapmeta.stores;return t.forEach(function(n){var i=r[n];i&&(t=t.concat(i.metaStores))}),n.value.call(this,t,i||"readonly")}}},objectStoreNames:function(n){return{get:function(){return new et([].slice.call(n.get.apply(this)).filter(function(n){return n.indexOf("$iegap")!==0}))}}},createObjectStore:function(n){return{value:function(t,i){var r,e=!1,u,f;if(i&&Array.isArray(i.keyPath)){if(e=!0,i.autoIncrement)throw new RangeError("Cannot autoincrement compound key");r=n.value.call(this,t)}else r=n.value.apply(this,arguments);return u=this._iegapmeta,f=u.stores[t]||(u.stores[t]={indexes:{},metaStores:[]}),f.keyPath=i&&i.keyPath||null,f.compound=e,f.autoIncrement=i&&i.autoIncrement||!1,p(this,r.transaction,u),r}}},deleteObjectStore:function(n){return{value:function(t){n.value.call(this,t);var i=this._iegapmeta,r=i.stores[t];if(r){if(r.metaStores.forEach(function(t){n.value.call(this,t)}),delete i.stores[t],!this._upgradeTransaction)throw"assert error";p(this,this._upgradeTransaction,i)}}}}})}var v={},u=window.IDBKeyRange,i=window.IDBObjectStore,y=window.IDBDatabase;b(g).from(Object).extend(function(){function n(n,t,i,r){return new e(n,n.objectStore.transaction,function(e,s){var h=n._compound,v=Array.isArray(n.objectStore.keyPath),l,a;h&&Array.isArray(t)&&(t=new o(t,t));l=h&&t?u.bound(f(t.lower),f(t.upper),t.lowerOpen,t.upperOpen):t;typeof l=="undefined"&&(l=null);a=n._idx.openCursor(l,i);a.onerror=s;a.onsuccess=r?function(t){var i=t.target.result,r;i?(r=n._store.get(i.value.fk),r.onerror=s,r.onsuccess=function(){if(!r.result)return i.continue();var u=h?c(i.key):i.key,f=v?c(i.value.fk):i.value.fk;e(t,new w(i,n,n.objectStore,f,u,r.result))}):e(t,null)}:function(t){var i=t.target.result,r=h?c(i.key):i.key,u=v?c(i.value.fk):i.value.fk;e(t,i&&new w(i,n,n.objectStore,u,r))}})}return{count:function(n){return arguments.length>0&&(arguments[0]=l(n)),this._idx.count.apply(this._idx,arguments)},get:function(n){var i=this,t=this._idx.get(l(n));return new e(this,this.objectStore.transaction,function(n,r){t.onsuccess=function(u){var f=t.result&&t.result.fk;f?(t=i.objectStore.get(f),t.onsuccess=function(){n(u,t.result)},t.onerror=r):n(u)};t.onerror=r})},getKey:function(n){var i=this,t=this._idx.get(l(n));return new e(this,this.objectStore.transaction,function(n,i){t.onsuccess=function(t){var i=t.target.result;n(t,i&&i.fk)};t.onerror=i})},openKeyCursor:function(t,i){return n(this,t,i)},openCursor:function(t,i){return n(this,t,i,!0)}}});a(w.prototype,function(){return{advance:function(n){this._cursor.advance(n)},"continue":function(n){return n?Array.isArray(n)?this._cursor.continue(f(n)):this._cursor.continue(n):this._cursor.continue()},"delete":function(){return this._store.delete(this.primaryKey)},update:function(n){return this._store.keyPath?this._store.put(n):this._store.put(n,this.primaryKey)}}});a(ut.prototype,function(){return{addEventListener:function(n,t){this._el[n]?this._el[n].push(t):this._el[n]=[t]},removeEventListener:function(n,t){var i=this._el[n],r;i&&(r=i.indexOf(t),r!==-1&&i.splice(r,1))},dispatchEvent:function(n){var t=this["on"+n.type],i,r,u;if(t&&t(n)===!1)return!1;if(i=this._el[n.type],i){for(r=0,u=i.length;r 2 | 3 | 4 | IDB-IEGAP Tests 5 | 6 | 7 |

      IDB-IEGAP Tests

      8 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/migration-phase-1.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | IDB-IEGAP Migration Phase 1 5 | 6 | 7 | 8 |

      IDB-IEGAP Migration Phase 1

      9 |

      10 | In this step, the polyfill is NOT loaded and we create 11 | a database in plain IE indexedDB scenario. 12 | The purpose is to verify that we at the next page is able 13 | to add the polyfill and still be able to use the existing database as 14 | well as upgrading it to start utilizing compound and multiValue indexes. 15 |

      16 |

      17 | In phase 2, we will include the polyfill and migrate the existing database. 18 |

      19 |

      20 | 21 |

      22 |

      23 | Continue to phase 2 --> 24 |

      25 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /test/migration-phase-2.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | IDB-IEGAP Migration Phase 2 5 | 6 | 7 | 8 | 9 |

      IDB-IEGAP Migration Phase 2

      10 |

      11 | In phase 2, we will include the polyfill and migrate the existing database. 12 | 13 | The purpose is to verify that we at the page is able 14 | to add the polyfill and still be able to use the existing database as 15 | well as upgrading it to start utilizing compound and multiValue indexes. 16 |

      17 |

      18 | 19 |

      20 |

      21 | <-- Back to phase 1 22 |

      23 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /test/tests-common.js: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | (function () { 5 | 6 | var db = new Dexie("iegap-unit-test-database"); 7 | db.version(1).stores({ 8 | users: '[customer+userid],userid,[customer+displayName],*&email' 9 | }); 10 | db.on('populate', function () { 11 | db.users.add({ 12 | customer: "awarica", 13 | userid: "dfahlander", 14 | email: ["david@awarica.com","david.fahlander@gmail.com"], 15 | displayName: "David" 16 | }); 17 | }); 18 | 19 | db.open(); 20 | 21 | asyncTest("compound-primary-key", function () { 22 | db.users.get(["awarica", "dfahlander"], function (user) { 23 | ok(!!user, "User found"); 24 | equal(user.userid, "dfahlander", "User correct"); 25 | }).catch(function (err) { 26 | ok(false, err); 27 | }).finally(start); 28 | }); 29 | 30 | asyncTest("compound-key", function () { 31 | db.users.where("[customer+displayName]").equals(["awarica","David"]).first(function (user) { 32 | ok(!!user, "User found"); 33 | equal(user.userid, "dfahlander", "User correct"); 34 | }).catch(function (err) { 35 | ok(false, err); 36 | }).finally(start); 37 | }); 38 | 39 | asyncTest("multiEntry-key", function () { 40 | db.users.get(["awarica", "dfahlander"], function (user) { 41 | ok(!!user, "User found"); 42 | equal(user.userid, "dfahlander", "User correct"); 43 | user.email.push("dfahlander@hotmail.com"); 44 | return db.users.put(user); 45 | }).then(function () { 46 | return db.users.where("email").equals("dfahlander@hotmail.com").first(); 47 | }).then(function (user) { 48 | ok(!!user, "User found by new multiENtry key"); 49 | equal(user.userid, "dfahlander", "User correct"); 50 | user.email.pop(); 51 | return db.users.put(user); 52 | }).then(function () { 53 | return db.users.where("email").equals("dfahlander@hotmail.com").count(); 54 | }).then(function (count) { 55 | equal(count, 0, "Should not find any user on that deleted email anymore"); 56 | }).catch(function (err) { 57 | ok(false, err); 58 | }).finally(start); 59 | }); 60 | 61 | })(); 62 | -------------------------------------------------------------------------------- /test/unit-tests.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | idb-iegap unit tests 6 | 7 | 8 | 9 |
      10 |
      11 | 12 | 13 | 14 | 15 | 16 | 17 | --------------------------------------------------------------------------------